Merged with gcc-4_4-branch@151281.
[official-gcc.git] / gcc / config / alpha / alpha.c
blob5ca9a1b6d83d9f01ff3709d3f3d088f8ffb2af7f
1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
12 any later version.
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "regs.h"
31 #include "hard-reg-set.h"
32 #include "real.h"
33 #include "insn-config.h"
34 #include "conditions.h"
35 #include "output.h"
36 #include "insn-attr.h"
37 #include "flags.h"
38 #include "recog.h"
39 #include "expr.h"
40 #include "optabs.h"
41 #include "reload.h"
42 #include "obstack.h"
43 #include "except.h"
44 #include "function.h"
45 #include "toplev.h"
46 #include "ggc.h"
47 #include "integrate.h"
48 #include "tm_p.h"
49 #include "target.h"
50 #include "target-def.h"
51 #include "debug.h"
52 #include "langhooks.h"
53 #include <splay-tree.h>
54 #include "cfglayout.h"
55 #include "gimple.h"
56 #include "tree-flow.h"
57 #include "tree-stdarg.h"
58 #include "tm-constrs.h"
59 #include "df.h"
61 /* Specify which cpu to schedule for. */
62 enum processor_type alpha_tune;
64 /* Which cpu we're generating code for. */
65 enum processor_type alpha_cpu;
67 static const char * const alpha_cpu_name[] =
69 "ev4", "ev5", "ev6"
72 /* Specify how accurate floating-point traps need to be. */
74 enum alpha_trap_precision alpha_tp;
76 /* Specify the floating-point rounding mode. */
78 enum alpha_fp_rounding_mode alpha_fprm;
80 /* Specify which things cause traps. */
82 enum alpha_fp_trap_mode alpha_fptm;
84 /* Save information from a "cmpxx" operation until the branch or scc is
85 emitted. */
87 struct alpha_compare alpha_compare;
89 /* Nonzero if inside of a function, because the Alpha asm can't
90 handle .files inside of functions. */
92 static int inside_function = FALSE;
94 /* The number of cycles of latency we should assume on memory reads. */
96 int alpha_memory_latency = 3;
98 /* Whether the function needs the GP. */
100 static int alpha_function_needs_gp;
102 /* The alias set for prologue/epilogue register save/restore. */
104 static GTY(()) alias_set_type alpha_sr_alias_set;
106 /* The assembler name of the current function. */
108 static const char *alpha_fnname;
110 /* The next explicit relocation sequence number. */
111 extern GTY(()) int alpha_next_sequence_number;
112 int alpha_next_sequence_number = 1;
114 /* The literal and gpdisp sequence numbers for this insn, as printed
115 by %# and %* respectively. */
116 extern GTY(()) int alpha_this_literal_sequence_number;
117 extern GTY(()) int alpha_this_gpdisp_sequence_number;
118 int alpha_this_literal_sequence_number;
119 int alpha_this_gpdisp_sequence_number;
121 /* Costs of various operations on the different architectures. */
123 struct alpha_rtx_cost_data
125 unsigned char fp_add;
126 unsigned char fp_mult;
127 unsigned char fp_div_sf;
128 unsigned char fp_div_df;
129 unsigned char int_mult_si;
130 unsigned char int_mult_di;
131 unsigned char int_shift;
132 unsigned char int_cmov;
133 unsigned short int_div;
136 static struct alpha_rtx_cost_data const alpha_rtx_cost_data[PROCESSOR_MAX] =
138 { /* EV4 */
139 COSTS_N_INSNS (6), /* fp_add */
140 COSTS_N_INSNS (6), /* fp_mult */
141 COSTS_N_INSNS (34), /* fp_div_sf */
142 COSTS_N_INSNS (63), /* fp_div_df */
143 COSTS_N_INSNS (23), /* int_mult_si */
144 COSTS_N_INSNS (23), /* int_mult_di */
145 COSTS_N_INSNS (2), /* int_shift */
146 COSTS_N_INSNS (2), /* int_cmov */
147 COSTS_N_INSNS (97), /* int_div */
149 { /* EV5 */
150 COSTS_N_INSNS (4), /* fp_add */
151 COSTS_N_INSNS (4), /* fp_mult */
152 COSTS_N_INSNS (15), /* fp_div_sf */
153 COSTS_N_INSNS (22), /* fp_div_df */
154 COSTS_N_INSNS (8), /* int_mult_si */
155 COSTS_N_INSNS (12), /* int_mult_di */
156 COSTS_N_INSNS (1) + 1, /* int_shift */
157 COSTS_N_INSNS (1), /* int_cmov */
158 COSTS_N_INSNS (83), /* int_div */
160 { /* EV6 */
161 COSTS_N_INSNS (4), /* fp_add */
162 COSTS_N_INSNS (4), /* fp_mult */
163 COSTS_N_INSNS (12), /* fp_div_sf */
164 COSTS_N_INSNS (15), /* fp_div_df */
165 COSTS_N_INSNS (7), /* int_mult_si */
166 COSTS_N_INSNS (7), /* int_mult_di */
167 COSTS_N_INSNS (1), /* int_shift */
168 COSTS_N_INSNS (2), /* int_cmov */
169 COSTS_N_INSNS (86), /* int_div */
173 /* Similar but tuned for code size instead of execution latency. The
174 extra +N is fractional cost tuning based on latency. It's used to
175 encourage use of cheaper insns like shift, but only if there's just
176 one of them. */
178 static struct alpha_rtx_cost_data const alpha_rtx_cost_size =
180 COSTS_N_INSNS (1), /* fp_add */
181 COSTS_N_INSNS (1), /* fp_mult */
182 COSTS_N_INSNS (1), /* fp_div_sf */
183 COSTS_N_INSNS (1) + 1, /* fp_div_df */
184 COSTS_N_INSNS (1) + 1, /* int_mult_si */
185 COSTS_N_INSNS (1) + 2, /* int_mult_di */
186 COSTS_N_INSNS (1), /* int_shift */
187 COSTS_N_INSNS (1), /* int_cmov */
188 COSTS_N_INSNS (6), /* int_div */
191 /* Get the number of args of a function in one of two ways. */
192 #if TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK
193 #define NUM_ARGS crtl->args.info.num_args
194 #else
195 #define NUM_ARGS crtl->args.info
196 #endif
198 #define REG_PV 27
199 #define REG_RA 26
201 /* Declarations of static functions. */
202 static struct machine_function *alpha_init_machine_status (void);
203 static rtx alpha_emit_xfloating_compare (enum rtx_code *, rtx, rtx);
205 #if TARGET_ABI_OPEN_VMS
206 static void alpha_write_linkage (FILE *, const char *, tree);
207 #endif
209 static void unicosmk_output_deferred_case_vectors (FILE *);
210 static void unicosmk_gen_dsib (unsigned long *);
211 static void unicosmk_output_ssib (FILE *, const char *);
212 static int unicosmk_need_dex (rtx);
214 /* Implement TARGET_HANDLE_OPTION. */
216 static bool
217 alpha_handle_option (size_t code, const char *arg, int value)
219 switch (code)
221 case OPT_mfp_regs:
222 if (value == 0)
223 target_flags |= MASK_SOFT_FP;
224 break;
226 case OPT_mieee:
227 case OPT_mieee_with_inexact:
228 target_flags |= MASK_IEEE_CONFORMANT;
229 break;
231 case OPT_mtls_size_:
232 if (value != 16 && value != 32 && value != 64)
233 error ("bad value %qs for -mtls-size switch", arg);
234 break;
237 return true;
240 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
241 /* Implement TARGET_MANGLE_TYPE. */
243 static const char *
244 alpha_mangle_type (const_tree type)
246 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
247 && TARGET_LONG_DOUBLE_128)
248 return "g";
250 /* For all other types, use normal C++ mangling. */
251 return NULL;
253 #endif
255 /* Parse target option strings. */
257 void
258 override_options (void)
260 static const struct cpu_table {
261 const char *const name;
262 const enum processor_type processor;
263 const int flags;
264 } cpu_table[] = {
265 { "ev4", PROCESSOR_EV4, 0 },
266 { "ev45", PROCESSOR_EV4, 0 },
267 { "21064", PROCESSOR_EV4, 0 },
268 { "ev5", PROCESSOR_EV5, 0 },
269 { "21164", PROCESSOR_EV5, 0 },
270 { "ev56", PROCESSOR_EV5, MASK_BWX },
271 { "21164a", PROCESSOR_EV5, MASK_BWX },
272 { "pca56", PROCESSOR_EV5, MASK_BWX|MASK_MAX },
273 { "21164PC",PROCESSOR_EV5, MASK_BWX|MASK_MAX },
274 { "21164pc",PROCESSOR_EV5, MASK_BWX|MASK_MAX },
275 { "ev6", PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX },
276 { "21264", PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX },
277 { "ev67", PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX|MASK_CIX },
278 { "21264a", PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX|MASK_CIX },
279 { 0, 0, 0 }
282 int i;
284 /* Unicos/Mk doesn't have shared libraries. */
285 if (TARGET_ABI_UNICOSMK && flag_pic)
287 warning (0, "-f%s ignored for Unicos/Mk (not supported)",
288 (flag_pic > 1) ? "PIC" : "pic");
289 flag_pic = 0;
292 /* On Unicos/Mk, the native compiler consistently generates /d suffices for
293 floating-point instructions. Make that the default for this target. */
294 if (TARGET_ABI_UNICOSMK)
295 alpha_fprm = ALPHA_FPRM_DYN;
296 else
297 alpha_fprm = ALPHA_FPRM_NORM;
299 alpha_tp = ALPHA_TP_PROG;
300 alpha_fptm = ALPHA_FPTM_N;
302 /* We cannot use su and sui qualifiers for conversion instructions on
303 Unicos/Mk. I'm not sure if this is due to assembler or hardware
304 limitations. Right now, we issue a warning if -mieee is specified
305 and then ignore it; eventually, we should either get it right or
306 disable the option altogether. */
308 if (TARGET_IEEE)
310 if (TARGET_ABI_UNICOSMK)
311 warning (0, "-mieee not supported on Unicos/Mk");
312 else
314 alpha_tp = ALPHA_TP_INSN;
315 alpha_fptm = ALPHA_FPTM_SU;
319 if (TARGET_IEEE_WITH_INEXACT)
321 if (TARGET_ABI_UNICOSMK)
322 warning (0, "-mieee-with-inexact not supported on Unicos/Mk");
323 else
325 alpha_tp = ALPHA_TP_INSN;
326 alpha_fptm = ALPHA_FPTM_SUI;
330 if (alpha_tp_string)
332 if (! strcmp (alpha_tp_string, "p"))
333 alpha_tp = ALPHA_TP_PROG;
334 else if (! strcmp (alpha_tp_string, "f"))
335 alpha_tp = ALPHA_TP_FUNC;
336 else if (! strcmp (alpha_tp_string, "i"))
337 alpha_tp = ALPHA_TP_INSN;
338 else
339 error ("bad value %qs for -mtrap-precision switch", alpha_tp_string);
342 if (alpha_fprm_string)
344 if (! strcmp (alpha_fprm_string, "n"))
345 alpha_fprm = ALPHA_FPRM_NORM;
346 else if (! strcmp (alpha_fprm_string, "m"))
347 alpha_fprm = ALPHA_FPRM_MINF;
348 else if (! strcmp (alpha_fprm_string, "c"))
349 alpha_fprm = ALPHA_FPRM_CHOP;
350 else if (! strcmp (alpha_fprm_string,"d"))
351 alpha_fprm = ALPHA_FPRM_DYN;
352 else
353 error ("bad value %qs for -mfp-rounding-mode switch",
354 alpha_fprm_string);
357 if (alpha_fptm_string)
359 if (strcmp (alpha_fptm_string, "n") == 0)
360 alpha_fptm = ALPHA_FPTM_N;
361 else if (strcmp (alpha_fptm_string, "u") == 0)
362 alpha_fptm = ALPHA_FPTM_U;
363 else if (strcmp (alpha_fptm_string, "su") == 0)
364 alpha_fptm = ALPHA_FPTM_SU;
365 else if (strcmp (alpha_fptm_string, "sui") == 0)
366 alpha_fptm = ALPHA_FPTM_SUI;
367 else
368 error ("bad value %qs for -mfp-trap-mode switch", alpha_fptm_string);
371 if (alpha_cpu_string)
373 for (i = 0; cpu_table [i].name; i++)
374 if (! strcmp (alpha_cpu_string, cpu_table [i].name))
376 alpha_tune = alpha_cpu = cpu_table [i].processor;
377 target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX);
378 target_flags |= cpu_table [i].flags;
379 break;
381 if (! cpu_table [i].name)
382 error ("bad value %qs for -mcpu switch", alpha_cpu_string);
385 if (alpha_tune_string)
387 for (i = 0; cpu_table [i].name; i++)
388 if (! strcmp (alpha_tune_string, cpu_table [i].name))
390 alpha_tune = cpu_table [i].processor;
391 break;
393 if (! cpu_table [i].name)
394 error ("bad value %qs for -mcpu switch", alpha_tune_string);
397 /* Do some sanity checks on the above options. */
399 if (TARGET_ABI_UNICOSMK && alpha_fptm != ALPHA_FPTM_N)
401 warning (0, "trap mode not supported on Unicos/Mk");
402 alpha_fptm = ALPHA_FPTM_N;
405 if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
406 && alpha_tp != ALPHA_TP_INSN && alpha_cpu != PROCESSOR_EV6)
408 warning (0, "fp software completion requires -mtrap-precision=i");
409 alpha_tp = ALPHA_TP_INSN;
412 if (alpha_cpu == PROCESSOR_EV6)
414 /* Except for EV6 pass 1 (not released), we always have precise
415 arithmetic traps. Which means we can do software completion
416 without minding trap shadows. */
417 alpha_tp = ALPHA_TP_PROG;
420 if (TARGET_FLOAT_VAX)
422 if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
424 warning (0, "rounding mode not supported for VAX floats");
425 alpha_fprm = ALPHA_FPRM_NORM;
427 if (alpha_fptm == ALPHA_FPTM_SUI)
429 warning (0, "trap mode not supported for VAX floats");
430 alpha_fptm = ALPHA_FPTM_SU;
432 if (target_flags_explicit & MASK_LONG_DOUBLE_128)
433 warning (0, "128-bit long double not supported for VAX floats");
434 target_flags &= ~MASK_LONG_DOUBLE_128;
438 char *end;
439 int lat;
441 if (!alpha_mlat_string)
442 alpha_mlat_string = "L1";
444 if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
445 && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
447 else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
448 && ISDIGIT ((unsigned char)alpha_mlat_string[1])
449 && alpha_mlat_string[2] == '\0')
451 static int const cache_latency[][4] =
453 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
454 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
455 { 3, 12, 30 }, /* ev6 -- Bcache from DS20 LMbench. */
458 lat = alpha_mlat_string[1] - '0';
459 if (lat <= 0 || lat > 3 || cache_latency[alpha_tune][lat-1] == -1)
461 warning (0, "L%d cache latency unknown for %s",
462 lat, alpha_cpu_name[alpha_tune]);
463 lat = 3;
465 else
466 lat = cache_latency[alpha_tune][lat-1];
468 else if (! strcmp (alpha_mlat_string, "main"))
470 /* Most current memories have about 370ns latency. This is
471 a reasonable guess for a fast cpu. */
472 lat = 150;
474 else
476 warning (0, "bad value %qs for -mmemory-latency", alpha_mlat_string);
477 lat = 3;
480 alpha_memory_latency = lat;
483 /* Default the definition of "small data" to 8 bytes. */
484 if (!g_switch_set)
485 g_switch_value = 8;
487 /* Infer TARGET_SMALL_DATA from -fpic/-fPIC. */
488 if (flag_pic == 1)
489 target_flags |= MASK_SMALL_DATA;
490 else if (flag_pic == 2)
491 target_flags &= ~MASK_SMALL_DATA;
493 /* Align labels and loops for optimal branching. */
494 /* ??? Kludge these by not doing anything if we don't optimize and also if
495 we are writing ECOFF symbols to work around a bug in DEC's assembler. */
496 if (optimize > 0 && write_symbols != SDB_DEBUG)
498 if (align_loops <= 0)
499 align_loops = 16;
500 if (align_jumps <= 0)
501 align_jumps = 16;
503 if (align_functions <= 0)
504 align_functions = 16;
506 /* Acquire a unique set number for our register saves and restores. */
507 alpha_sr_alias_set = new_alias_set ();
509 /* Register variables and functions with the garbage collector. */
511 /* Set up function hooks. */
512 init_machine_status = alpha_init_machine_status;
514 /* Tell the compiler when we're using VAX floating point. */
515 if (TARGET_FLOAT_VAX)
517 REAL_MODE_FORMAT (SFmode) = &vax_f_format;
518 REAL_MODE_FORMAT (DFmode) = &vax_g_format;
519 REAL_MODE_FORMAT (TFmode) = NULL;
522 #ifdef TARGET_DEFAULT_LONG_DOUBLE_128
523 if (!(target_flags_explicit & MASK_LONG_DOUBLE_128))
524 target_flags |= MASK_LONG_DOUBLE_128;
525 #endif
527 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
528 can be optimized to ap = __builtin_next_arg (0). */
529 if (TARGET_ABI_UNICOSMK)
530 targetm.expand_builtin_va_start = NULL;
533 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
536 zap_mask (HOST_WIDE_INT value)
538 int i;
540 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
541 i++, value >>= 8)
542 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
543 return 0;
545 return 1;
548 /* Return true if OP is valid for a particular TLS relocation.
549 We are already guaranteed that OP is a CONST. */
552 tls_symbolic_operand_1 (rtx op, int size, int unspec)
554 op = XEXP (op, 0);
556 if (GET_CODE (op) != UNSPEC || XINT (op, 1) != unspec)
557 return 0;
558 op = XVECEXP (op, 0, 0);
560 if (GET_CODE (op) != SYMBOL_REF)
561 return 0;
563 switch (SYMBOL_REF_TLS_MODEL (op))
565 case TLS_MODEL_LOCAL_DYNAMIC:
566 return unspec == UNSPEC_DTPREL && size == alpha_tls_size;
567 case TLS_MODEL_INITIAL_EXEC:
568 return unspec == UNSPEC_TPREL && size == 64;
569 case TLS_MODEL_LOCAL_EXEC:
570 return unspec == UNSPEC_TPREL && size == alpha_tls_size;
571 default:
572 gcc_unreachable ();
576 /* Used by aligned_memory_operand and unaligned_memory_operand to
577 resolve what reload is going to do with OP if it's a register. */
580 resolve_reload_operand (rtx op)
582 if (reload_in_progress)
584 rtx tmp = op;
585 if (GET_CODE (tmp) == SUBREG)
586 tmp = SUBREG_REG (tmp);
587 if (GET_CODE (tmp) == REG
588 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
590 op = reg_equiv_memory_loc[REGNO (tmp)];
591 if (op == 0)
592 return 0;
595 return op;
598 /* The scalar modes supported differs from the default check-what-c-supports
599 version in that sometimes TFmode is available even when long double
600 indicates only DFmode. On unicosmk, we have the situation that HImode
601 doesn't map to any C type, but of course we still support that. */
603 static bool
604 alpha_scalar_mode_supported_p (enum machine_mode mode)
606 switch (mode)
608 case QImode:
609 case HImode:
610 case SImode:
611 case DImode:
612 case TImode: /* via optabs.c */
613 return true;
615 case SFmode:
616 case DFmode:
617 return true;
619 case TFmode:
620 return TARGET_HAS_XFLOATING_LIBS;
622 default:
623 return false;
627 /* Alpha implements a couple of integer vector mode operations when
628 TARGET_MAX is enabled. We do not check TARGET_MAX here, however,
629 which allows the vectorizer to operate on e.g. move instructions,
630 or when expand_vector_operations can do something useful. */
632 static bool
633 alpha_vector_mode_supported_p (enum machine_mode mode)
635 return mode == V8QImode || mode == V4HImode || mode == V2SImode;
638 /* Return 1 if this function can directly return via $26. */
641 direct_return (void)
643 return (! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK
644 && reload_completed
645 && alpha_sa_size () == 0
646 && get_frame_size () == 0
647 && crtl->outgoing_args_size == 0
648 && crtl->args.pretend_args_size == 0);
651 /* Return the ADDR_VEC associated with a tablejump insn. */
654 alpha_tablejump_addr_vec (rtx insn)
656 rtx tmp;
658 tmp = JUMP_LABEL (insn);
659 if (!tmp)
660 return NULL_RTX;
661 tmp = NEXT_INSN (tmp);
662 if (!tmp)
663 return NULL_RTX;
664 if (GET_CODE (tmp) == JUMP_INSN
665 && GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC)
666 return PATTERN (tmp);
667 return NULL_RTX;
670 /* Return the label of the predicted edge, or CONST0_RTX if we don't know. */
673 alpha_tablejump_best_label (rtx insn)
675 rtx jump_table = alpha_tablejump_addr_vec (insn);
676 rtx best_label = NULL_RTX;
678 /* ??? Once the CFG doesn't keep getting completely rebuilt, look
679 there for edge frequency counts from profile data. */
681 if (jump_table)
683 int n_labels = XVECLEN (jump_table, 1);
684 int best_count = -1;
685 int i, j;
687 for (i = 0; i < n_labels; i++)
689 int count = 1;
691 for (j = i + 1; j < n_labels; j++)
692 if (XEXP (XVECEXP (jump_table, 1, i), 0)
693 == XEXP (XVECEXP (jump_table, 1, j), 0))
694 count++;
696 if (count > best_count)
697 best_count = count, best_label = XVECEXP (jump_table, 1, i);
701 return best_label ? best_label : const0_rtx;
704 /* Return the TLS model to use for SYMBOL. */
706 static enum tls_model
707 tls_symbolic_operand_type (rtx symbol)
709 enum tls_model model;
711 if (GET_CODE (symbol) != SYMBOL_REF)
712 return 0;
713 model = SYMBOL_REF_TLS_MODEL (symbol);
715 /* Local-exec with a 64-bit size is the same code as initial-exec. */
716 if (model == TLS_MODEL_LOCAL_EXEC && alpha_tls_size == 64)
717 model = TLS_MODEL_INITIAL_EXEC;
719 return model;
722 /* Return true if the function DECL will share the same GP as any
723 function in the current unit of translation. */
725 static bool
726 decl_has_samegp (const_tree decl)
728 /* Functions that are not local can be overridden, and thus may
729 not share the same gp. */
730 if (!(*targetm.binds_local_p) (decl))
731 return false;
733 /* If -msmall-data is in effect, assume that there is only one GP
734 for the module, and so any local symbol has this property. We
735 need explicit relocations to be able to enforce this for symbols
736 not defined in this unit of translation, however. */
737 if (TARGET_EXPLICIT_RELOCS && TARGET_SMALL_DATA)
738 return true;
740 /* Functions that are not external are defined in this UoT. */
741 /* ??? Irritatingly, static functions not yet emitted are still
742 marked "external". Apply this to non-static functions only. */
743 return !TREE_PUBLIC (decl) || !DECL_EXTERNAL (decl);
746 /* Return true if EXP should be placed in the small data section. */
748 static bool
749 alpha_in_small_data_p (const_tree exp)
751 /* We want to merge strings, so we never consider them small data. */
752 if (TREE_CODE (exp) == STRING_CST)
753 return false;
755 /* Functions are never in the small data area. Duh. */
756 if (TREE_CODE (exp) == FUNCTION_DECL)
757 return false;
759 if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
761 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
762 if (strcmp (section, ".sdata") == 0
763 || strcmp (section, ".sbss") == 0)
764 return true;
766 else
768 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
770 /* If this is an incomplete type with size 0, then we can't put it
771 in sdata because it might be too big when completed. */
772 if (size > 0 && (unsigned HOST_WIDE_INT) size <= g_switch_value)
773 return true;
776 return false;
779 #if TARGET_ABI_OPEN_VMS
780 static bool
781 alpha_linkage_symbol_p (const char *symname)
783 int symlen = strlen (symname);
785 if (symlen > 4)
786 return strcmp (&symname [symlen - 4], "..lk") == 0;
788 return false;
791 #define LINKAGE_SYMBOL_REF_P(X) \
792 ((GET_CODE (X) == SYMBOL_REF \
793 && alpha_linkage_symbol_p (XSTR (X, 0))) \
794 || (GET_CODE (X) == CONST \
795 && GET_CODE (XEXP (X, 0)) == PLUS \
796 && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \
797 && alpha_linkage_symbol_p (XSTR (XEXP (XEXP (X, 0), 0), 0))))
798 #endif
800 /* legitimate_address_p recognizes an RTL expression that is a valid
801 memory address for an instruction. The MODE argument is the
802 machine mode for the MEM expression that wants to use this address.
804 For Alpha, we have either a constant address or the sum of a
805 register and a constant address, or just a register. For DImode,
806 any of those forms can be surrounded with an AND that clear the
807 low-order three bits; this is an "unaligned" access. */
809 bool
810 alpha_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
812 /* If this is an ldq_u type address, discard the outer AND. */
813 if (mode == DImode
814 && GET_CODE (x) == AND
815 && GET_CODE (XEXP (x, 1)) == CONST_INT
816 && INTVAL (XEXP (x, 1)) == -8)
817 x = XEXP (x, 0);
819 /* Discard non-paradoxical subregs. */
820 if (GET_CODE (x) == SUBREG
821 && (GET_MODE_SIZE (GET_MODE (x))
822 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
823 x = SUBREG_REG (x);
825 /* Unadorned general registers are valid. */
826 if (REG_P (x)
827 && (strict
828 ? STRICT_REG_OK_FOR_BASE_P (x)
829 : NONSTRICT_REG_OK_FOR_BASE_P (x)))
830 return true;
832 /* Constant addresses (i.e. +/- 32k) are valid. */
833 if (CONSTANT_ADDRESS_P (x))
834 return true;
836 #if TARGET_ABI_OPEN_VMS
837 if (LINKAGE_SYMBOL_REF_P (x))
838 return true;
839 #endif
841 /* Register plus a small constant offset is valid. */
842 if (GET_CODE (x) == PLUS)
844 rtx ofs = XEXP (x, 1);
845 x = XEXP (x, 0);
847 /* Discard non-paradoxical subregs. */
848 if (GET_CODE (x) == SUBREG
849 && (GET_MODE_SIZE (GET_MODE (x))
850 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
851 x = SUBREG_REG (x);
853 if (REG_P (x))
855 if (! strict
856 && NONSTRICT_REG_OK_FP_BASE_P (x)
857 && GET_CODE (ofs) == CONST_INT)
858 return true;
859 if ((strict
860 ? STRICT_REG_OK_FOR_BASE_P (x)
861 : NONSTRICT_REG_OK_FOR_BASE_P (x))
862 && CONSTANT_ADDRESS_P (ofs))
863 return true;
867 /* If we're managing explicit relocations, LO_SUM is valid, as are small
868 data symbols. Avoid explicit relocations of modes larger than word
869 mode since i.e. $LC0+8($1) can fold around +/- 32k offset. */
870 else if (TARGET_EXPLICIT_RELOCS
871 && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
873 if (small_symbolic_operand (x, Pmode))
874 return true;
876 if (GET_CODE (x) == LO_SUM)
878 rtx ofs = XEXP (x, 1);
879 x = XEXP (x, 0);
881 /* Discard non-paradoxical subregs. */
882 if (GET_CODE (x) == SUBREG
883 && (GET_MODE_SIZE (GET_MODE (x))
884 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
885 x = SUBREG_REG (x);
887 /* Must have a valid base register. */
888 if (! (REG_P (x)
889 && (strict
890 ? STRICT_REG_OK_FOR_BASE_P (x)
891 : NONSTRICT_REG_OK_FOR_BASE_P (x))))
892 return false;
894 /* The symbol must be local. */
895 if (local_symbolic_operand (ofs, Pmode)
896 || dtp32_symbolic_operand (ofs, Pmode)
897 || tp32_symbolic_operand (ofs, Pmode))
898 return true;
902 return false;
905 /* Build the SYMBOL_REF for __tls_get_addr. */
907 static GTY(()) rtx tls_get_addr_libfunc;
909 static rtx
910 get_tls_get_addr (void)
912 if (!tls_get_addr_libfunc)
913 tls_get_addr_libfunc = init_one_libfunc ("__tls_get_addr");
914 return tls_get_addr_libfunc;
917 /* Try machine-dependent ways of modifying an illegitimate address
918 to be legitimate. If we find one, return the new, valid address. */
921 alpha_legitimize_address (rtx x, rtx scratch, enum machine_mode mode)
923 HOST_WIDE_INT addend;
925 /* If the address is (plus reg const_int) and the CONST_INT is not a
926 valid offset, compute the high part of the constant and add it to
927 the register. Then our address is (plus temp low-part-const). */
928 if (GET_CODE (x) == PLUS
929 && GET_CODE (XEXP (x, 0)) == REG
930 && GET_CODE (XEXP (x, 1)) == CONST_INT
931 && ! CONSTANT_ADDRESS_P (XEXP (x, 1)))
933 addend = INTVAL (XEXP (x, 1));
934 x = XEXP (x, 0);
935 goto split_addend;
938 /* If the address is (const (plus FOO const_int)), find the low-order
939 part of the CONST_INT. Then load FOO plus any high-order part of the
940 CONST_INT into a register. Our address is (plus reg low-part-const).
941 This is done to reduce the number of GOT entries. */
942 if (can_create_pseudo_p ()
943 && GET_CODE (x) == CONST
944 && GET_CODE (XEXP (x, 0)) == PLUS
945 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
947 addend = INTVAL (XEXP (XEXP (x, 0), 1));
948 x = force_reg (Pmode, XEXP (XEXP (x, 0), 0));
949 goto split_addend;
952 /* If we have a (plus reg const), emit the load as in (2), then add
953 the two registers, and finally generate (plus reg low-part-const) as
954 our address. */
955 if (can_create_pseudo_p ()
956 && GET_CODE (x) == PLUS
957 && GET_CODE (XEXP (x, 0)) == REG
958 && GET_CODE (XEXP (x, 1)) == CONST
959 && GET_CODE (XEXP (XEXP (x, 1), 0)) == PLUS
960 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == CONST_INT)
962 addend = INTVAL (XEXP (XEXP (XEXP (x, 1), 0), 1));
963 x = expand_simple_binop (Pmode, PLUS, XEXP (x, 0),
964 XEXP (XEXP (XEXP (x, 1), 0), 0),
965 NULL_RTX, 1, OPTAB_LIB_WIDEN);
966 goto split_addend;
969 /* If this is a local symbol, split the address into HIGH/LO_SUM parts.
970 Avoid modes larger than word mode since i.e. $LC0+8($1) can fold
971 around +/- 32k offset. */
972 if (TARGET_EXPLICIT_RELOCS
973 && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
974 && symbolic_operand (x, Pmode))
976 rtx r0, r16, eqv, tga, tp, insn, dest, seq;
978 switch (tls_symbolic_operand_type (x))
980 case TLS_MODEL_NONE:
981 break;
983 case TLS_MODEL_GLOBAL_DYNAMIC:
984 start_sequence ();
986 r0 = gen_rtx_REG (Pmode, 0);
987 r16 = gen_rtx_REG (Pmode, 16);
988 tga = get_tls_get_addr ();
989 dest = gen_reg_rtx (Pmode);
990 seq = GEN_INT (alpha_next_sequence_number++);
992 emit_insn (gen_movdi_er_tlsgd (r16, pic_offset_table_rtx, x, seq));
993 insn = gen_call_value_osf_tlsgd (r0, tga, seq);
994 insn = emit_call_insn (insn);
995 RTL_CONST_CALL_P (insn) = 1;
996 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
998 insn = get_insns ();
999 end_sequence ();
1001 emit_libcall_block (insn, dest, r0, x);
1002 return dest;
1004 case TLS_MODEL_LOCAL_DYNAMIC:
1005 start_sequence ();
1007 r0 = gen_rtx_REG (Pmode, 0);
1008 r16 = gen_rtx_REG (Pmode, 16);
1009 tga = get_tls_get_addr ();
1010 scratch = gen_reg_rtx (Pmode);
1011 seq = GEN_INT (alpha_next_sequence_number++);
1013 emit_insn (gen_movdi_er_tlsldm (r16, pic_offset_table_rtx, seq));
1014 insn = gen_call_value_osf_tlsldm (r0, tga, seq);
1015 insn = emit_call_insn (insn);
1016 RTL_CONST_CALL_P (insn) = 1;
1017 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
1019 insn = get_insns ();
1020 end_sequence ();
1022 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
1023 UNSPEC_TLSLDM_CALL);
1024 emit_libcall_block (insn, scratch, r0, eqv);
1026 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPREL);
1027 eqv = gen_rtx_CONST (Pmode, eqv);
1029 if (alpha_tls_size == 64)
1031 dest = gen_reg_rtx (Pmode);
1032 emit_insn (gen_rtx_SET (VOIDmode, dest, eqv));
1033 emit_insn (gen_adddi3 (dest, dest, scratch));
1034 return dest;
1036 if (alpha_tls_size == 32)
1038 insn = gen_rtx_HIGH (Pmode, eqv);
1039 insn = gen_rtx_PLUS (Pmode, scratch, insn);
1040 scratch = gen_reg_rtx (Pmode);
1041 emit_insn (gen_rtx_SET (VOIDmode, scratch, insn));
1043 return gen_rtx_LO_SUM (Pmode, scratch, eqv);
1045 case TLS_MODEL_INITIAL_EXEC:
1046 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
1047 eqv = gen_rtx_CONST (Pmode, eqv);
1048 tp = gen_reg_rtx (Pmode);
1049 scratch = gen_reg_rtx (Pmode);
1050 dest = gen_reg_rtx (Pmode);
1052 emit_insn (gen_load_tp (tp));
1053 emit_insn (gen_rtx_SET (VOIDmode, scratch, eqv));
1054 emit_insn (gen_adddi3 (dest, tp, scratch));
1055 return dest;
1057 case TLS_MODEL_LOCAL_EXEC:
1058 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
1059 eqv = gen_rtx_CONST (Pmode, eqv);
1060 tp = gen_reg_rtx (Pmode);
1062 emit_insn (gen_load_tp (tp));
1063 if (alpha_tls_size == 32)
1065 insn = gen_rtx_HIGH (Pmode, eqv);
1066 insn = gen_rtx_PLUS (Pmode, tp, insn);
1067 tp = gen_reg_rtx (Pmode);
1068 emit_insn (gen_rtx_SET (VOIDmode, tp, insn));
1070 return gen_rtx_LO_SUM (Pmode, tp, eqv);
1072 default:
1073 gcc_unreachable ();
1076 if (local_symbolic_operand (x, Pmode))
1078 if (small_symbolic_operand (x, Pmode))
1079 return x;
1080 else
1082 if (can_create_pseudo_p ())
1083 scratch = gen_reg_rtx (Pmode);
1084 emit_insn (gen_rtx_SET (VOIDmode, scratch,
1085 gen_rtx_HIGH (Pmode, x)));
1086 return gen_rtx_LO_SUM (Pmode, scratch, x);
1091 return NULL;
1093 split_addend:
1095 HOST_WIDE_INT low, high;
1097 low = ((addend & 0xffff) ^ 0x8000) - 0x8000;
1098 addend -= low;
1099 high = ((addend & 0xffffffff) ^ 0x80000000) - 0x80000000;
1100 addend -= high;
1102 if (addend)
1103 x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (addend),
1104 (!can_create_pseudo_p () ? scratch : NULL_RTX),
1105 1, OPTAB_LIB_WIDEN);
1106 if (high)
1107 x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (high),
1108 (!can_create_pseudo_p () ? scratch : NULL_RTX),
1109 1, OPTAB_LIB_WIDEN);
1111 return plus_constant (x, low);
1115 /* Primarily this is required for TLS symbols, but given that our move
1116 patterns *ought* to be able to handle any symbol at any time, we
1117 should never be spilling symbolic operands to the constant pool, ever. */
1119 static bool
1120 alpha_cannot_force_const_mem (rtx x)
1122 enum rtx_code code = GET_CODE (x);
1123 return code == SYMBOL_REF || code == LABEL_REF || code == CONST;
1126 /* We do not allow indirect calls to be optimized into sibling calls, nor
1127 can we allow a call to a function with a different GP to be optimized
1128 into a sibcall. */
1130 static bool
1131 alpha_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
1133 /* Can't do indirect tail calls, since we don't know if the target
1134 uses the same GP. */
1135 if (!decl)
1136 return false;
1138 /* Otherwise, we can make a tail call if the target function shares
1139 the same GP. */
1140 return decl_has_samegp (decl);
1144 some_small_symbolic_operand_int (rtx *px, void *data ATTRIBUTE_UNUSED)
1146 rtx x = *px;
1148 /* Don't re-split. */
1149 if (GET_CODE (x) == LO_SUM)
1150 return -1;
1152 return small_symbolic_operand (x, Pmode) != 0;
1155 static int
1156 split_small_symbolic_operand_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
1158 rtx x = *px;
1160 /* Don't re-split. */
1161 if (GET_CODE (x) == LO_SUM)
1162 return -1;
1164 if (small_symbolic_operand (x, Pmode))
1166 x = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, x);
1167 *px = x;
1168 return -1;
1171 return 0;
1175 split_small_symbolic_operand (rtx x)
1177 x = copy_insn (x);
1178 for_each_rtx (&x, split_small_symbolic_operand_1, NULL);
1179 return x;
1182 /* Indicate that INSN cannot be duplicated. This is true for any insn
1183 that we've marked with gpdisp relocs, since those have to stay in
1184 1-1 correspondence with one another.
1186 Technically we could copy them if we could set up a mapping from one
1187 sequence number to another, across the set of insns to be duplicated.
1188 This seems overly complicated and error-prone since interblock motion
1189 from sched-ebb could move one of the pair of insns to a different block.
1191 Also cannot allow jsr insns to be duplicated. If they throw exceptions,
1192 then they'll be in a different block from their ldgp. Which could lead
1193 the bb reorder code to think that it would be ok to copy just the block
1194 containing the call and branch to the block containing the ldgp. */
1196 static bool
1197 alpha_cannot_copy_insn_p (rtx insn)
1199 if (!reload_completed || !TARGET_EXPLICIT_RELOCS)
1200 return false;
1201 if (recog_memoized (insn) >= 0)
1202 return get_attr_cannot_copy (insn);
1203 else
1204 return false;
1208 /* Try a machine-dependent way of reloading an illegitimate address
1209 operand. If we find one, push the reload and return the new rtx. */
1212 alpha_legitimize_reload_address (rtx x,
1213 enum machine_mode mode ATTRIBUTE_UNUSED,
1214 int opnum, int type,
1215 int ind_levels ATTRIBUTE_UNUSED)
1217 /* We must recognize output that we have already generated ourselves. */
1218 if (GET_CODE (x) == PLUS
1219 && GET_CODE (XEXP (x, 0)) == PLUS
1220 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
1221 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1222 && GET_CODE (XEXP (x, 1)) == CONST_INT)
1224 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
1225 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
1226 opnum, type);
1227 return x;
1230 /* We wish to handle large displacements off a base register by
1231 splitting the addend across an ldah and the mem insn. This
1232 cuts number of extra insns needed from 3 to 1. */
1233 if (GET_CODE (x) == PLUS
1234 && GET_CODE (XEXP (x, 0)) == REG
1235 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
1236 && REGNO_OK_FOR_BASE_P (REGNO (XEXP (x, 0)))
1237 && GET_CODE (XEXP (x, 1)) == CONST_INT)
1239 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
1240 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1241 HOST_WIDE_INT high
1242 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
1244 /* Check for 32-bit overflow. */
1245 if (high + low != val)
1246 return NULL_RTX;
1248 /* Reload the high part into a base reg; leave the low part
1249 in the mem directly. */
1250 x = gen_rtx_PLUS (GET_MODE (x),
1251 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
1252 GEN_INT (high)),
1253 GEN_INT (low));
1255 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
1256 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
1257 opnum, type);
1258 return x;
1261 return NULL_RTX;
1264 /* Compute a (partial) cost for rtx X. Return true if the complete
1265 cost has been computed, and false if subexpressions should be
1266 scanned. In either case, *TOTAL contains the cost result. */
1268 static bool
1269 alpha_rtx_costs (rtx x, int code, int outer_code, int *total,
1270 bool speed)
1272 enum machine_mode mode = GET_MODE (x);
1273 bool float_mode_p = FLOAT_MODE_P (mode);
1274 const struct alpha_rtx_cost_data *cost_data;
1276 if (!speed)
1277 cost_data = &alpha_rtx_cost_size;
1278 else
1279 cost_data = &alpha_rtx_cost_data[alpha_tune];
1281 switch (code)
1283 case CONST_INT:
1284 /* If this is an 8-bit constant, return zero since it can be used
1285 nearly anywhere with no cost. If it is a valid operand for an
1286 ADD or AND, likewise return 0 if we know it will be used in that
1287 context. Otherwise, return 2 since it might be used there later.
1288 All other constants take at least two insns. */
1289 if (INTVAL (x) >= 0 && INTVAL (x) < 256)
1291 *total = 0;
1292 return true;
1294 /* FALLTHRU */
1296 case CONST_DOUBLE:
1297 if (x == CONST0_RTX (mode))
1298 *total = 0;
1299 else if ((outer_code == PLUS && add_operand (x, VOIDmode))
1300 || (outer_code == AND && and_operand (x, VOIDmode)))
1301 *total = 0;
1302 else if (add_operand (x, VOIDmode) || and_operand (x, VOIDmode))
1303 *total = 2;
1304 else
1305 *total = COSTS_N_INSNS (2);
1306 return true;
1308 case CONST:
1309 case SYMBOL_REF:
1310 case LABEL_REF:
1311 if (TARGET_EXPLICIT_RELOCS && small_symbolic_operand (x, VOIDmode))
1312 *total = COSTS_N_INSNS (outer_code != MEM);
1313 else if (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (x, VOIDmode))
1314 *total = COSTS_N_INSNS (1 + (outer_code != MEM));
1315 else if (tls_symbolic_operand_type (x))
1316 /* Estimate of cost for call_pal rduniq. */
1317 /* ??? How many insns do we emit here? More than one... */
1318 *total = COSTS_N_INSNS (15);
1319 else
1320 /* Otherwise we do a load from the GOT. */
1321 *total = COSTS_N_INSNS (!speed ? 1 : alpha_memory_latency);
1322 return true;
1324 case HIGH:
1325 /* This is effectively an add_operand. */
1326 *total = 2;
1327 return true;
1329 case PLUS:
1330 case MINUS:
1331 if (float_mode_p)
1332 *total = cost_data->fp_add;
1333 else if (GET_CODE (XEXP (x, 0)) == MULT
1334 && const48_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
1336 *total = (rtx_cost (XEXP (XEXP (x, 0), 0), outer_code, speed)
1337 + rtx_cost (XEXP (x, 1), outer_code, speed) + COSTS_N_INSNS (1));
1338 return true;
1340 return false;
1342 case MULT:
1343 if (float_mode_p)
1344 *total = cost_data->fp_mult;
1345 else if (mode == DImode)
1346 *total = cost_data->int_mult_di;
1347 else
1348 *total = cost_data->int_mult_si;
1349 return false;
1351 case ASHIFT:
1352 if (GET_CODE (XEXP (x, 1)) == CONST_INT
1353 && INTVAL (XEXP (x, 1)) <= 3)
1355 *total = COSTS_N_INSNS (1);
1356 return false;
1358 /* FALLTHRU */
1360 case ASHIFTRT:
1361 case LSHIFTRT:
1362 *total = cost_data->int_shift;
1363 return false;
1365 case IF_THEN_ELSE:
1366 if (float_mode_p)
1367 *total = cost_data->fp_add;
1368 else
1369 *total = cost_data->int_cmov;
1370 return false;
1372 case DIV:
1373 case UDIV:
1374 case MOD:
1375 case UMOD:
1376 if (!float_mode_p)
1377 *total = cost_data->int_div;
1378 else if (mode == SFmode)
1379 *total = cost_data->fp_div_sf;
1380 else
1381 *total = cost_data->fp_div_df;
1382 return false;
1384 case MEM:
1385 *total = COSTS_N_INSNS (!speed ? 1 : alpha_memory_latency);
1386 return true;
1388 case NEG:
1389 if (! float_mode_p)
1391 *total = COSTS_N_INSNS (1);
1392 return false;
1394 /* FALLTHRU */
1396 case ABS:
1397 if (! float_mode_p)
1399 *total = COSTS_N_INSNS (1) + cost_data->int_cmov;
1400 return false;
1402 /* FALLTHRU */
1404 case FLOAT:
1405 case UNSIGNED_FLOAT:
1406 case FIX:
1407 case UNSIGNED_FIX:
1408 case FLOAT_TRUNCATE:
1409 *total = cost_data->fp_add;
1410 return false;
1412 case FLOAT_EXTEND:
1413 if (GET_CODE (XEXP (x, 0)) == MEM)
1414 *total = 0;
1415 else
1416 *total = cost_data->fp_add;
1417 return false;
1419 default:
1420 return false;
1424 /* REF is an alignable memory location. Place an aligned SImode
1425 reference into *PALIGNED_MEM and the number of bits to shift into
1426 *PBITNUM. SCRATCH is a free register for use in reloading out
1427 of range stack slots. */
1429 void
1430 get_aligned_mem (rtx ref, rtx *paligned_mem, rtx *pbitnum)
1432 rtx base;
1433 HOST_WIDE_INT disp, offset;
1435 gcc_assert (GET_CODE (ref) == MEM);
1437 if (reload_in_progress
1438 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1440 base = find_replacement (&XEXP (ref, 0));
1441 gcc_assert (memory_address_p (GET_MODE (ref), base));
1443 else
1444 base = XEXP (ref, 0);
1446 if (GET_CODE (base) == PLUS)
1447 disp = INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1448 else
1449 disp = 0;
1451 /* Find the byte offset within an aligned word. If the memory itself is
1452 claimed to be aligned, believe it. Otherwise, aligned_memory_operand
1453 will have examined the base register and determined it is aligned, and
1454 thus displacements from it are naturally alignable. */
1455 if (MEM_ALIGN (ref) >= 32)
1456 offset = 0;
1457 else
1458 offset = disp & 3;
1460 /* Access the entire aligned word. */
1461 *paligned_mem = widen_memory_access (ref, SImode, -offset);
1463 /* Convert the byte offset within the word to a bit offset. */
1464 if (WORDS_BIG_ENDIAN)
1465 offset = 32 - (GET_MODE_BITSIZE (GET_MODE (ref)) + offset * 8);
1466 else
1467 offset *= 8;
1468 *pbitnum = GEN_INT (offset);
1471 /* Similar, but just get the address. Handle the two reload cases.
1472 Add EXTRA_OFFSET to the address we return. */
1475 get_unaligned_address (rtx ref)
1477 rtx base;
1478 HOST_WIDE_INT offset = 0;
1480 gcc_assert (GET_CODE (ref) == MEM);
1482 if (reload_in_progress
1483 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1485 base = find_replacement (&XEXP (ref, 0));
1487 gcc_assert (memory_address_p (GET_MODE (ref), base));
1489 else
1490 base = XEXP (ref, 0);
1492 if (GET_CODE (base) == PLUS)
1493 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1495 return plus_constant (base, offset);
1498 /* Compute a value X, such that X & 7 == (ADDR + OFS) & 7.
1499 X is always returned in a register. */
1502 get_unaligned_offset (rtx addr, HOST_WIDE_INT ofs)
1504 if (GET_CODE (addr) == PLUS)
1506 ofs += INTVAL (XEXP (addr, 1));
1507 addr = XEXP (addr, 0);
1510 return expand_simple_binop (Pmode, PLUS, addr, GEN_INT (ofs & 7),
1511 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1514 /* On the Alpha, all (non-symbolic) constants except zero go into
1515 a floating-point register via memory. Note that we cannot
1516 return anything that is not a subset of RCLASS, and that some
1517 symbolic constants cannot be dropped to memory. */
1519 enum reg_class
1520 alpha_preferred_reload_class(rtx x, enum reg_class rclass)
1522 /* Zero is present in any register class. */
1523 if (x == CONST0_RTX (GET_MODE (x)))
1524 return rclass;
1526 /* These sorts of constants we can easily drop to memory. */
1527 if (GET_CODE (x) == CONST_INT
1528 || GET_CODE (x) == CONST_DOUBLE
1529 || GET_CODE (x) == CONST_VECTOR)
1531 if (rclass == FLOAT_REGS)
1532 return NO_REGS;
1533 if (rclass == ALL_REGS)
1534 return GENERAL_REGS;
1535 return rclass;
1538 /* All other kinds of constants should not (and in the case of HIGH
1539 cannot) be dropped to memory -- instead we use a GENERAL_REGS
1540 secondary reload. */
1541 if (CONSTANT_P (x))
1542 return (rclass == ALL_REGS ? GENERAL_REGS : rclass);
1544 return rclass;
1547 /* Inform reload about cases where moving X with a mode MODE to a register in
1548 RCLASS requires an extra scratch or immediate register. Return the class
1549 needed for the immediate register. */
1551 static enum reg_class
1552 alpha_secondary_reload (bool in_p, rtx x, enum reg_class rclass,
1553 enum machine_mode mode, secondary_reload_info *sri)
1555 /* Loading and storing HImode or QImode values to and from memory
1556 usually requires a scratch register. */
1557 if (!TARGET_BWX && (mode == QImode || mode == HImode || mode == CQImode))
1559 if (any_memory_operand (x, mode))
1561 if (in_p)
1563 if (!aligned_memory_operand (x, mode))
1564 sri->icode = reload_in_optab[mode];
1566 else
1567 sri->icode = reload_out_optab[mode];
1568 return NO_REGS;
1572 /* We also cannot do integral arithmetic into FP regs, as might result
1573 from register elimination into a DImode fp register. */
1574 if (rclass == FLOAT_REGS)
1576 if (MEM_P (x) && GET_CODE (XEXP (x, 0)) == AND)
1577 return GENERAL_REGS;
1578 if (in_p && INTEGRAL_MODE_P (mode)
1579 && !MEM_P (x) && !REG_P (x) && !CONST_INT_P (x))
1580 return GENERAL_REGS;
1583 return NO_REGS;
1586 /* Subfunction of the following function. Update the flags of any MEM
1587 found in part of X. */
1589 static int
1590 alpha_set_memflags_1 (rtx *xp, void *data)
1592 rtx x = *xp, orig = (rtx) data;
1594 if (GET_CODE (x) != MEM)
1595 return 0;
1597 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (orig);
1598 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (orig);
1599 MEM_SCALAR_P (x) = MEM_SCALAR_P (orig);
1600 MEM_NOTRAP_P (x) = MEM_NOTRAP_P (orig);
1601 MEM_READONLY_P (x) = MEM_READONLY_P (orig);
1603 /* Sadly, we cannot use alias sets because the extra aliasing
1604 produced by the AND interferes. Given that two-byte quantities
1605 are the only thing we would be able to differentiate anyway,
1606 there does not seem to be any point in convoluting the early
1607 out of the alias check. */
1609 return -1;
1612 /* Given SEQ, which is an INSN list, look for any MEMs in either
1613 a SET_DEST or a SET_SRC and copy the in-struct, unchanging, and
1614 volatile flags from REF into each of the MEMs found. If REF is not
1615 a MEM, don't do anything. */
1617 void
1618 alpha_set_memflags (rtx seq, rtx ref)
1620 rtx insn;
1622 if (!MEM_P (ref))
1623 return;
1625 /* This is only called from alpha.md, after having had something
1626 generated from one of the insn patterns. So if everything is
1627 zero, the pattern is already up-to-date. */
1628 if (!MEM_VOLATILE_P (ref)
1629 && !MEM_IN_STRUCT_P (ref)
1630 && !MEM_SCALAR_P (ref)
1631 && !MEM_NOTRAP_P (ref)
1632 && !MEM_READONLY_P (ref))
1633 return;
1635 for (insn = seq; insn; insn = NEXT_INSN (insn))
1636 if (INSN_P (insn))
1637 for_each_rtx (&PATTERN (insn), alpha_set_memflags_1, (void *) ref);
1638 else
1639 gcc_unreachable ();
1642 static rtx alpha_emit_set_const (rtx, enum machine_mode, HOST_WIDE_INT,
1643 int, bool);
1645 /* Internal routine for alpha_emit_set_const to check for N or below insns.
1646 If NO_OUTPUT is true, then we only check to see if N insns are possible,
1647 and return pc_rtx if successful. */
1649 static rtx
1650 alpha_emit_set_const_1 (rtx target, enum machine_mode mode,
1651 HOST_WIDE_INT c, int n, bool no_output)
1653 HOST_WIDE_INT new_const;
1654 int i, bits;
1655 /* Use a pseudo if highly optimizing and still generating RTL. */
1656 rtx subtarget
1657 = (flag_expensive_optimizations && can_create_pseudo_p () ? 0 : target);
1658 rtx temp, insn;
1660 /* If this is a sign-extended 32-bit constant, we can do this in at most
1661 three insns, so do it if we have enough insns left. We always have
1662 a sign-extended 32-bit constant when compiling on a narrow machine. */
1664 if (HOST_BITS_PER_WIDE_INT != 64
1665 || c >> 31 == -1 || c >> 31 == 0)
1667 HOST_WIDE_INT low = ((c & 0xffff) ^ 0x8000) - 0x8000;
1668 HOST_WIDE_INT tmp1 = c - low;
1669 HOST_WIDE_INT high = (((tmp1 >> 16) & 0xffff) ^ 0x8000) - 0x8000;
1670 HOST_WIDE_INT extra = 0;
1672 /* If HIGH will be interpreted as negative but the constant is
1673 positive, we must adjust it to do two ldha insns. */
1675 if ((high & 0x8000) != 0 && c >= 0)
1677 extra = 0x4000;
1678 tmp1 -= 0x40000000;
1679 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1682 if (c == low || (low == 0 && extra == 0))
1684 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1685 but that meant that we can't handle INT_MIN on 32-bit machines
1686 (like NT/Alpha), because we recurse indefinitely through
1687 emit_move_insn to gen_movdi. So instead, since we know exactly
1688 what we want, create it explicitly. */
1690 if (no_output)
1691 return pc_rtx;
1692 if (target == NULL)
1693 target = gen_reg_rtx (mode);
1694 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1695 return target;
1697 else if (n >= 2 + (extra != 0))
1699 if (no_output)
1700 return pc_rtx;
1701 if (!can_create_pseudo_p ())
1703 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (high << 16)));
1704 temp = target;
1706 else
1707 temp = copy_to_suggested_reg (GEN_INT (high << 16),
1708 subtarget, mode);
1710 /* As of 2002-02-23, addsi3 is only available when not optimizing.
1711 This means that if we go through expand_binop, we'll try to
1712 generate extensions, etc, which will require new pseudos, which
1713 will fail during some split phases. The SImode add patterns
1714 still exist, but are not named. So build the insns by hand. */
1716 if (extra != 0)
1718 if (! subtarget)
1719 subtarget = gen_reg_rtx (mode);
1720 insn = gen_rtx_PLUS (mode, temp, GEN_INT (extra << 16));
1721 insn = gen_rtx_SET (VOIDmode, subtarget, insn);
1722 emit_insn (insn);
1723 temp = subtarget;
1726 if (target == NULL)
1727 target = gen_reg_rtx (mode);
1728 insn = gen_rtx_PLUS (mode, temp, GEN_INT (low));
1729 insn = gen_rtx_SET (VOIDmode, target, insn);
1730 emit_insn (insn);
1731 return target;
1735 /* If we couldn't do it that way, try some other methods. But if we have
1736 no instructions left, don't bother. Likewise, if this is SImode and
1737 we can't make pseudos, we can't do anything since the expand_binop
1738 and expand_unop calls will widen and try to make pseudos. */
1740 if (n == 1 || (mode == SImode && !can_create_pseudo_p ()))
1741 return 0;
1743 /* Next, see if we can load a related constant and then shift and possibly
1744 negate it to get the constant we want. Try this once each increasing
1745 numbers of insns. */
1747 for (i = 1; i < n; i++)
1749 /* First, see if minus some low bits, we've an easy load of
1750 high bits. */
1752 new_const = ((c & 0xffff) ^ 0x8000) - 0x8000;
1753 if (new_const != 0)
1755 temp = alpha_emit_set_const (subtarget, mode, c - new_const, i, no_output);
1756 if (temp)
1758 if (no_output)
1759 return temp;
1760 return expand_binop (mode, add_optab, temp, GEN_INT (new_const),
1761 target, 0, OPTAB_WIDEN);
1765 /* Next try complementing. */
1766 temp = alpha_emit_set_const (subtarget, mode, ~c, i, no_output);
1767 if (temp)
1769 if (no_output)
1770 return temp;
1771 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1774 /* Next try to form a constant and do a left shift. We can do this
1775 if some low-order bits are zero; the exact_log2 call below tells
1776 us that information. The bits we are shifting out could be any
1777 value, but here we'll just try the 0- and sign-extended forms of
1778 the constant. To try to increase the chance of having the same
1779 constant in more than one insn, start at the highest number of
1780 bits to shift, but try all possibilities in case a ZAPNOT will
1781 be useful. */
1783 bits = exact_log2 (c & -c);
1784 if (bits > 0)
1785 for (; bits > 0; bits--)
1787 new_const = c >> bits;
1788 temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output);
1789 if (!temp && c < 0)
1791 new_const = (unsigned HOST_WIDE_INT)c >> bits;
1792 temp = alpha_emit_set_const (subtarget, mode, new_const,
1793 i, no_output);
1795 if (temp)
1797 if (no_output)
1798 return temp;
1799 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1800 target, 0, OPTAB_WIDEN);
1804 /* Now try high-order zero bits. Here we try the shifted-in bits as
1805 all zero and all ones. Be careful to avoid shifting outside the
1806 mode and to avoid shifting outside the host wide int size. */
1807 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1808 confuse the recursive call and set all of the high 32 bits. */
1810 bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1811 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64));
1812 if (bits > 0)
1813 for (; bits > 0; bits--)
1815 new_const = c << bits;
1816 temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output);
1817 if (!temp)
1819 new_const = (c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1);
1820 temp = alpha_emit_set_const (subtarget, mode, new_const,
1821 i, no_output);
1823 if (temp)
1825 if (no_output)
1826 return temp;
1827 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1828 target, 1, OPTAB_WIDEN);
1832 /* Now try high-order 1 bits. We get that with a sign-extension.
1833 But one bit isn't enough here. Be careful to avoid shifting outside
1834 the mode and to avoid shifting outside the host wide int size. */
1836 bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1837 - floor_log2 (~ c) - 2);
1838 if (bits > 0)
1839 for (; bits > 0; bits--)
1841 new_const = c << bits;
1842 temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output);
1843 if (!temp)
1845 new_const = (c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1);
1846 temp = alpha_emit_set_const (subtarget, mode, new_const,
1847 i, no_output);
1849 if (temp)
1851 if (no_output)
1852 return temp;
1853 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1854 target, 0, OPTAB_WIDEN);
1859 #if HOST_BITS_PER_WIDE_INT == 64
1860 /* Finally, see if can load a value into the target that is the same as the
1861 constant except that all bytes that are 0 are changed to be 0xff. If we
1862 can, then we can do a ZAPNOT to obtain the desired constant. */
1864 new_const = c;
1865 for (i = 0; i < 64; i += 8)
1866 if ((new_const & ((HOST_WIDE_INT) 0xff << i)) == 0)
1867 new_const |= (HOST_WIDE_INT) 0xff << i;
1869 /* We are only called for SImode and DImode. If this is SImode, ensure that
1870 we are sign extended to a full word. */
1872 if (mode == SImode)
1873 new_const = ((new_const & 0xffffffff) ^ 0x80000000) - 0x80000000;
1875 if (new_const != c)
1877 temp = alpha_emit_set_const (subtarget, mode, new_const, n - 1, no_output);
1878 if (temp)
1880 if (no_output)
1881 return temp;
1882 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new_const),
1883 target, 0, OPTAB_WIDEN);
1886 #endif
1888 return 0;
1891 /* Try to output insns to set TARGET equal to the constant C if it can be
1892 done in less than N insns. Do all computations in MODE. Returns the place
1893 where the output has been placed if it can be done and the insns have been
1894 emitted. If it would take more than N insns, zero is returned and no
1895 insns and emitted. */
1897 static rtx
1898 alpha_emit_set_const (rtx target, enum machine_mode mode,
1899 HOST_WIDE_INT c, int n, bool no_output)
1901 enum machine_mode orig_mode = mode;
1902 rtx orig_target = target;
1903 rtx result = 0;
1904 int i;
1906 /* If we can't make any pseudos, TARGET is an SImode hard register, we
1907 can't load this constant in one insn, do this in DImode. */
1908 if (!can_create_pseudo_p () && mode == SImode
1909 && GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER)
1911 result = alpha_emit_set_const_1 (target, mode, c, 1, no_output);
1912 if (result)
1913 return result;
1915 target = no_output ? NULL : gen_lowpart (DImode, target);
1916 mode = DImode;
1918 else if (mode == V8QImode || mode == V4HImode || mode == V2SImode)
1920 target = no_output ? NULL : gen_lowpart (DImode, target);
1921 mode = DImode;
1924 /* Try 1 insn, then 2, then up to N. */
1925 for (i = 1; i <= n; i++)
1927 result = alpha_emit_set_const_1 (target, mode, c, i, no_output);
1928 if (result)
1930 rtx insn, set;
1932 if (no_output)
1933 return result;
1935 insn = get_last_insn ();
1936 set = single_set (insn);
1937 if (! CONSTANT_P (SET_SRC (set)))
1938 set_unique_reg_note (get_last_insn (), REG_EQUAL, GEN_INT (c));
1939 break;
1943 /* Allow for the case where we changed the mode of TARGET. */
1944 if (result)
1946 if (result == target)
1947 result = orig_target;
1948 else if (mode != orig_mode)
1949 result = gen_lowpart (orig_mode, result);
1952 return result;
1955 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1956 fall back to a straight forward decomposition. We do this to avoid
1957 exponential run times encountered when looking for longer sequences
1958 with alpha_emit_set_const. */
1960 static rtx
1961 alpha_emit_set_long_const (rtx target, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
1963 HOST_WIDE_INT d1, d2, d3, d4;
1965 /* Decompose the entire word */
1966 #if HOST_BITS_PER_WIDE_INT >= 64
1967 gcc_assert (c2 == -(c1 < 0));
1968 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1969 c1 -= d1;
1970 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1971 c1 = (c1 - d2) >> 32;
1972 d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1973 c1 -= d3;
1974 d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1975 gcc_assert (c1 == d4);
1976 #else
1977 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1978 c1 -= d1;
1979 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1980 gcc_assert (c1 == d2);
1981 c2 += (d2 < 0);
1982 d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
1983 c2 -= d3;
1984 d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1985 gcc_assert (c2 == d4);
1986 #endif
1988 /* Construct the high word */
1989 if (d4)
1991 emit_move_insn (target, GEN_INT (d4));
1992 if (d3)
1993 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
1995 else
1996 emit_move_insn (target, GEN_INT (d3));
1998 /* Shift it into place */
1999 emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
2001 /* Add in the low bits. */
2002 if (d2)
2003 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
2004 if (d1)
2005 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
2007 return target;
2010 /* Given an integral CONST_INT, CONST_DOUBLE, or CONST_VECTOR, return
2011 the low 64 bits. */
2013 static void
2014 alpha_extract_integer (rtx x, HOST_WIDE_INT *p0, HOST_WIDE_INT *p1)
2016 HOST_WIDE_INT i0, i1;
2018 if (GET_CODE (x) == CONST_VECTOR)
2019 x = simplify_subreg (DImode, x, GET_MODE (x), 0);
2022 if (GET_CODE (x) == CONST_INT)
2024 i0 = INTVAL (x);
2025 i1 = -(i0 < 0);
2027 else if (HOST_BITS_PER_WIDE_INT >= 64)
2029 i0 = CONST_DOUBLE_LOW (x);
2030 i1 = -(i0 < 0);
2032 else
2034 i0 = CONST_DOUBLE_LOW (x);
2035 i1 = CONST_DOUBLE_HIGH (x);
2038 *p0 = i0;
2039 *p1 = i1;
2042 /* Implement LEGITIMATE_CONSTANT_P. This is all constants for which we
2043 are willing to load the value into a register via a move pattern.
2044 Normally this is all symbolic constants, integral constants that
2045 take three or fewer instructions, and floating-point zero. */
2047 bool
2048 alpha_legitimate_constant_p (rtx x)
2050 enum machine_mode mode = GET_MODE (x);
2051 HOST_WIDE_INT i0, i1;
2053 switch (GET_CODE (x))
2055 case LABEL_REF:
2056 case HIGH:
2057 return true;
2059 case CONST:
2060 if (GET_CODE (XEXP (x, 0)) == PLUS
2061 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
2062 x = XEXP (XEXP (x, 0), 0);
2063 else
2064 return true;
2066 if (GET_CODE (x) != SYMBOL_REF)
2067 return true;
2069 /* FALLTHRU */
2071 case SYMBOL_REF:
2072 /* TLS symbols are never valid. */
2073 return SYMBOL_REF_TLS_MODEL (x) == 0;
2075 case CONST_DOUBLE:
2076 if (x == CONST0_RTX (mode))
2077 return true;
2078 if (FLOAT_MODE_P (mode))
2079 return false;
2080 goto do_integer;
2082 case CONST_VECTOR:
2083 if (x == CONST0_RTX (mode))
2084 return true;
2085 if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
2086 return false;
2087 if (GET_MODE_SIZE (mode) != 8)
2088 return false;
2089 goto do_integer;
2091 case CONST_INT:
2092 do_integer:
2093 if (TARGET_BUILD_CONSTANTS)
2094 return true;
2095 alpha_extract_integer (x, &i0, &i1);
2096 if (HOST_BITS_PER_WIDE_INT >= 64 || i1 == (-i0 < 0))
2097 return alpha_emit_set_const_1 (x, mode, i0, 3, true) != NULL;
2098 return false;
2100 default:
2101 return false;
2105 /* Operand 1 is known to be a constant, and should require more than one
2106 instruction to load. Emit that multi-part load. */
2108 bool
2109 alpha_split_const_mov (enum machine_mode mode, rtx *operands)
2111 HOST_WIDE_INT i0, i1;
2112 rtx temp = NULL_RTX;
2114 alpha_extract_integer (operands[1], &i0, &i1);
2116 if (HOST_BITS_PER_WIDE_INT >= 64 || i1 == -(i0 < 0))
2117 temp = alpha_emit_set_const (operands[0], mode, i0, 3, false);
2119 if (!temp && TARGET_BUILD_CONSTANTS)
2120 temp = alpha_emit_set_long_const (operands[0], i0, i1);
2122 if (temp)
2124 if (!rtx_equal_p (operands[0], temp))
2125 emit_move_insn (operands[0], temp);
2126 return true;
2129 return false;
2132 /* Expand a move instruction; return true if all work is done.
2133 We don't handle non-bwx subword loads here. */
2135 bool
2136 alpha_expand_mov (enum machine_mode mode, rtx *operands)
2138 rtx tmp;
2140 /* If the output is not a register, the input must be. */
2141 if (GET_CODE (operands[0]) == MEM
2142 && ! reg_or_0_operand (operands[1], mode))
2143 operands[1] = force_reg (mode, operands[1]);
2145 /* Allow legitimize_address to perform some simplifications. */
2146 if (mode == Pmode && symbolic_operand (operands[1], mode))
2148 tmp = alpha_legitimize_address (operands[1], operands[0], mode);
2149 if (tmp)
2151 if (tmp == operands[0])
2152 return true;
2153 operands[1] = tmp;
2154 return false;
2158 /* Early out for non-constants and valid constants. */
2159 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], mode))
2160 return false;
2162 /* Split large integers. */
2163 if (GET_CODE (operands[1]) == CONST_INT
2164 || GET_CODE (operands[1]) == CONST_DOUBLE
2165 || GET_CODE (operands[1]) == CONST_VECTOR)
2167 if (alpha_split_const_mov (mode, operands))
2168 return true;
2171 /* Otherwise we've nothing left but to drop the thing to memory. */
2172 tmp = force_const_mem (mode, operands[1]);
2174 if (tmp == NULL_RTX)
2175 return false;
2177 if (reload_in_progress)
2179 emit_move_insn (operands[0], XEXP (tmp, 0));
2180 operands[1] = replace_equiv_address (tmp, operands[0]);
2182 else
2183 operands[1] = validize_mem (tmp);
2184 return false;
2187 /* Expand a non-bwx QImode or HImode move instruction;
2188 return true if all work is done. */
2190 bool
2191 alpha_expand_mov_nobwx (enum machine_mode mode, rtx *operands)
2193 rtx seq;
2195 /* If the output is not a register, the input must be. */
2196 if (MEM_P (operands[0]))
2197 operands[1] = force_reg (mode, operands[1]);
2199 /* Handle four memory cases, unaligned and aligned for either the input
2200 or the output. The only case where we can be called during reload is
2201 for aligned loads; all other cases require temporaries. */
2203 if (any_memory_operand (operands[1], mode))
2205 if (aligned_memory_operand (operands[1], mode))
2207 if (reload_in_progress)
2209 if (mode == QImode)
2210 seq = gen_reload_inqi_aligned (operands[0], operands[1]);
2211 else
2212 seq = gen_reload_inhi_aligned (operands[0], operands[1]);
2213 emit_insn (seq);
2215 else
2217 rtx aligned_mem, bitnum;
2218 rtx scratch = gen_reg_rtx (SImode);
2219 rtx subtarget;
2220 bool copyout;
2222 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
2224 subtarget = operands[0];
2225 if (GET_CODE (subtarget) == REG)
2226 subtarget = gen_lowpart (DImode, subtarget), copyout = false;
2227 else
2228 subtarget = gen_reg_rtx (DImode), copyout = true;
2230 if (mode == QImode)
2231 seq = gen_aligned_loadqi (subtarget, aligned_mem,
2232 bitnum, scratch);
2233 else
2234 seq = gen_aligned_loadhi (subtarget, aligned_mem,
2235 bitnum, scratch);
2236 emit_insn (seq);
2238 if (copyout)
2239 emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
2242 else
2244 /* Don't pass these as parameters since that makes the generated
2245 code depend on parameter evaluation order which will cause
2246 bootstrap failures. */
2248 rtx temp1, temp2, subtarget, ua;
2249 bool copyout;
2251 temp1 = gen_reg_rtx (DImode);
2252 temp2 = gen_reg_rtx (DImode);
2254 subtarget = operands[0];
2255 if (GET_CODE (subtarget) == REG)
2256 subtarget = gen_lowpart (DImode, subtarget), copyout = false;
2257 else
2258 subtarget = gen_reg_rtx (DImode), copyout = true;
2260 ua = get_unaligned_address (operands[1]);
2261 if (mode == QImode)
2262 seq = gen_unaligned_loadqi (subtarget, ua, temp1, temp2);
2263 else
2264 seq = gen_unaligned_loadhi (subtarget, ua, temp1, temp2);
2266 alpha_set_memflags (seq, operands[1]);
2267 emit_insn (seq);
2269 if (copyout)
2270 emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
2272 return true;
2275 if (any_memory_operand (operands[0], mode))
2277 if (aligned_memory_operand (operands[0], mode))
2279 rtx aligned_mem, bitnum;
2280 rtx temp1 = gen_reg_rtx (SImode);
2281 rtx temp2 = gen_reg_rtx (SImode);
2283 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
2285 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
2286 temp1, temp2));
2288 else
2290 rtx temp1 = gen_reg_rtx (DImode);
2291 rtx temp2 = gen_reg_rtx (DImode);
2292 rtx temp3 = gen_reg_rtx (DImode);
2293 rtx ua = get_unaligned_address (operands[0]);
2295 if (mode == QImode)
2296 seq = gen_unaligned_storeqi (ua, operands[1], temp1, temp2, temp3);
2297 else
2298 seq = gen_unaligned_storehi (ua, operands[1], temp1, temp2, temp3);
2300 alpha_set_memflags (seq, operands[0]);
2301 emit_insn (seq);
2303 return true;
2306 return false;
2309 /* Implement the movmisalign patterns. One of the operands is a memory
2310 that is not naturally aligned. Emit instructions to load it. */
2312 void
2313 alpha_expand_movmisalign (enum machine_mode mode, rtx *operands)
2315 /* Honor misaligned loads, for those we promised to do so. */
2316 if (MEM_P (operands[1]))
2318 rtx tmp;
2320 if (register_operand (operands[0], mode))
2321 tmp = operands[0];
2322 else
2323 tmp = gen_reg_rtx (mode);
2325 alpha_expand_unaligned_load (tmp, operands[1], 8, 0, 0);
2326 if (tmp != operands[0])
2327 emit_move_insn (operands[0], tmp);
2329 else if (MEM_P (operands[0]))
2331 if (!reg_or_0_operand (operands[1], mode))
2332 operands[1] = force_reg (mode, operands[1]);
2333 alpha_expand_unaligned_store (operands[0], operands[1], 8, 0);
2335 else
2336 gcc_unreachable ();
2339 /* Generate an unsigned DImode to FP conversion. This is the same code
2340 optabs would emit if we didn't have TFmode patterns.
2342 For SFmode, this is the only construction I've found that can pass
2343 gcc.c-torture/execute/ieee/rbug.c. No scenario that uses DFmode
2344 intermediates will work, because you'll get intermediate rounding
2345 that ruins the end result. Some of this could be fixed by turning
2346 on round-to-positive-infinity, but that requires diddling the fpsr,
2347 which kills performance. I tried turning this around and converting
2348 to a negative number, so that I could turn on /m, but either I did
2349 it wrong or there's something else cause I wound up with the exact
2350 same single-bit error. There is a branch-less form of this same code:
2352 srl $16,1,$1
2353 and $16,1,$2
2354 cmplt $16,0,$3
2355 or $1,$2,$2
2356 cmovge $16,$16,$2
2357 itoft $3,$f10
2358 itoft $2,$f11
2359 cvtqs $f11,$f11
2360 adds $f11,$f11,$f0
2361 fcmoveq $f10,$f11,$f0
2363 I'm not using it because it's the same number of instructions as
2364 this branch-full form, and it has more serialized long latency
2365 instructions on the critical path.
2367 For DFmode, we can avoid rounding errors by breaking up the word
2368 into two pieces, converting them separately, and adding them back:
2370 LC0: .long 0,0x5f800000
2372 itoft $16,$f11
2373 lda $2,LC0
2374 cmplt $16,0,$1
2375 cpyse $f11,$f31,$f10
2376 cpyse $f31,$f11,$f11
2377 s4addq $1,$2,$1
2378 lds $f12,0($1)
2379 cvtqt $f10,$f10
2380 cvtqt $f11,$f11
2381 addt $f12,$f10,$f0
2382 addt $f0,$f11,$f0
2384 This doesn't seem to be a clear-cut win over the optabs form.
2385 It probably all depends on the distribution of numbers being
2386 converted -- in the optabs form, all but high-bit-set has a
2387 much lower minimum execution time. */
2389 void
2390 alpha_emit_floatuns (rtx operands[2])
2392 rtx neglab, donelab, i0, i1, f0, in, out;
2393 enum machine_mode mode;
2395 out = operands[0];
2396 in = force_reg (DImode, operands[1]);
2397 mode = GET_MODE (out);
2398 neglab = gen_label_rtx ();
2399 donelab = gen_label_rtx ();
2400 i0 = gen_reg_rtx (DImode);
2401 i1 = gen_reg_rtx (DImode);
2402 f0 = gen_reg_rtx (mode);
2404 emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0, neglab);
2406 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_FLOAT (mode, in)));
2407 emit_jump_insn (gen_jump (donelab));
2408 emit_barrier ();
2410 emit_label (neglab);
2412 emit_insn (gen_lshrdi3 (i0, in, const1_rtx));
2413 emit_insn (gen_anddi3 (i1, in, const1_rtx));
2414 emit_insn (gen_iordi3 (i0, i0, i1));
2415 emit_insn (gen_rtx_SET (VOIDmode, f0, gen_rtx_FLOAT (mode, i0)));
2416 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0)));
2418 emit_label (donelab);
2421 /* Generate the comparison for a conditional branch. */
2424 alpha_emit_conditional_branch (enum rtx_code code)
2426 enum rtx_code cmp_code, branch_code;
2427 enum machine_mode cmp_mode, branch_mode = VOIDmode;
2428 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
2429 rtx tem;
2431 if (alpha_compare.fp_p && GET_MODE (op0) == TFmode)
2433 op0 = alpha_emit_xfloating_compare (&code, op0, op1);
2434 op1 = const0_rtx;
2435 alpha_compare.fp_p = 0;
2438 /* The general case: fold the comparison code to the types of compares
2439 that we have, choosing the branch as necessary. */
2440 switch (code)
2442 case EQ: case LE: case LT: case LEU: case LTU:
2443 case UNORDERED:
2444 /* We have these compares: */
2445 cmp_code = code, branch_code = NE;
2446 break;
2448 case NE:
2449 case ORDERED:
2450 /* These must be reversed. */
2451 cmp_code = reverse_condition (code), branch_code = EQ;
2452 break;
2454 case GE: case GT: case GEU: case GTU:
2455 /* For FP, we swap them, for INT, we reverse them. */
2456 if (alpha_compare.fp_p)
2458 cmp_code = swap_condition (code);
2459 branch_code = NE;
2460 tem = op0, op0 = op1, op1 = tem;
2462 else
2464 cmp_code = reverse_condition (code);
2465 branch_code = EQ;
2467 break;
2469 default:
2470 gcc_unreachable ();
2473 if (alpha_compare.fp_p)
2475 cmp_mode = DFmode;
2476 if (flag_unsafe_math_optimizations && cmp_code != UNORDERED)
2478 /* When we are not as concerned about non-finite values, and we
2479 are comparing against zero, we can branch directly. */
2480 if (op1 == CONST0_RTX (DFmode))
2481 cmp_code = UNKNOWN, branch_code = code;
2482 else if (op0 == CONST0_RTX (DFmode))
2484 /* Undo the swap we probably did just above. */
2485 tem = op0, op0 = op1, op1 = tem;
2486 branch_code = swap_condition (cmp_code);
2487 cmp_code = UNKNOWN;
2490 else
2492 /* ??? We mark the branch mode to be CCmode to prevent the
2493 compare and branch from being combined, since the compare
2494 insn follows IEEE rules that the branch does not. */
2495 branch_mode = CCmode;
2498 else
2500 cmp_mode = DImode;
2502 /* The following optimizations are only for signed compares. */
2503 if (code != LEU && code != LTU && code != GEU && code != GTU)
2505 /* Whee. Compare and branch against 0 directly. */
2506 if (op1 == const0_rtx)
2507 cmp_code = UNKNOWN, branch_code = code;
2509 /* If the constants doesn't fit into an immediate, but can
2510 be generated by lda/ldah, we adjust the argument and
2511 compare against zero, so we can use beq/bne directly. */
2512 /* ??? Don't do this when comparing against symbols, otherwise
2513 we'll reduce (&x == 0x1234) to (&x-0x1234 == 0), which will
2514 be declared false out of hand (at least for non-weak). */
2515 else if (GET_CODE (op1) == CONST_INT
2516 && (code == EQ || code == NE)
2517 && !(symbolic_operand (op0, VOIDmode)
2518 || (GET_CODE (op0) == REG && REG_POINTER (op0))))
2520 rtx n_op1 = GEN_INT (-INTVAL (op1));
2522 if (! satisfies_constraint_I (op1)
2523 && (satisfies_constraint_K (n_op1)
2524 || satisfies_constraint_L (n_op1)))
2525 cmp_code = PLUS, branch_code = code, op1 = n_op1;
2529 if (!reg_or_0_operand (op0, DImode))
2530 op0 = force_reg (DImode, op0);
2531 if (cmp_code != PLUS && !reg_or_8bit_operand (op1, DImode))
2532 op1 = force_reg (DImode, op1);
2535 /* Emit an initial compare instruction, if necessary. */
2536 tem = op0;
2537 if (cmp_code != UNKNOWN)
2539 tem = gen_reg_rtx (cmp_mode);
2540 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
2543 /* Zero the operands. */
2544 memset (&alpha_compare, 0, sizeof (alpha_compare));
2546 /* Return the branch comparison. */
2547 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
2550 /* Certain simplifications can be done to make invalid setcc operations
2551 valid. Return the final comparison, or NULL if we can't work. */
2554 alpha_emit_setcc (enum rtx_code code)
2556 enum rtx_code cmp_code;
2557 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
2558 int fp_p = alpha_compare.fp_p;
2559 rtx tmp;
2561 /* Zero the operands. */
2562 memset (&alpha_compare, 0, sizeof (alpha_compare));
2564 if (fp_p && GET_MODE (op0) == TFmode)
2566 op0 = alpha_emit_xfloating_compare (&code, op0, op1);
2567 op1 = const0_rtx;
2568 fp_p = 0;
2571 if (fp_p && !TARGET_FIX)
2572 return NULL_RTX;
2574 /* The general case: fold the comparison code to the types of compares
2575 that we have, choosing the branch as necessary. */
2577 cmp_code = UNKNOWN;
2578 switch (code)
2580 case EQ: case LE: case LT: case LEU: case LTU:
2581 case UNORDERED:
2582 /* We have these compares. */
2583 if (fp_p)
2584 cmp_code = code, code = NE;
2585 break;
2587 case NE:
2588 if (!fp_p && op1 == const0_rtx)
2589 break;
2590 /* FALLTHRU */
2592 case ORDERED:
2593 cmp_code = reverse_condition (code);
2594 code = EQ;
2595 break;
2597 case GE: case GT: case GEU: case GTU:
2598 /* These normally need swapping, but for integer zero we have
2599 special patterns that recognize swapped operands. */
2600 if (!fp_p && op1 == const0_rtx)
2601 break;
2602 code = swap_condition (code);
2603 if (fp_p)
2604 cmp_code = code, code = NE;
2605 tmp = op0, op0 = op1, op1 = tmp;
2606 break;
2608 default:
2609 gcc_unreachable ();
2612 if (!fp_p)
2614 if (!register_operand (op0, DImode))
2615 op0 = force_reg (DImode, op0);
2616 if (!reg_or_8bit_operand (op1, DImode))
2617 op1 = force_reg (DImode, op1);
2620 /* Emit an initial compare instruction, if necessary. */
2621 if (cmp_code != UNKNOWN)
2623 enum machine_mode mode = fp_p ? DFmode : DImode;
2625 tmp = gen_reg_rtx (mode);
2626 emit_insn (gen_rtx_SET (VOIDmode, tmp,
2627 gen_rtx_fmt_ee (cmp_code, mode, op0, op1)));
2629 op0 = fp_p ? gen_lowpart (DImode, tmp) : tmp;
2630 op1 = const0_rtx;
2633 /* Return the setcc comparison. */
2634 return gen_rtx_fmt_ee (code, DImode, op0, op1);
2638 /* Rewrite a comparison against zero CMP of the form
2639 (CODE (cc0) (const_int 0)) so it can be written validly in
2640 a conditional move (if_then_else CMP ...).
2641 If both of the operands that set cc0 are nonzero we must emit
2642 an insn to perform the compare (it can't be done within
2643 the conditional move). */
2646 alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
2648 enum rtx_code code = GET_CODE (cmp);
2649 enum rtx_code cmov_code = NE;
2650 rtx op0 = alpha_compare.op0;
2651 rtx op1 = alpha_compare.op1;
2652 int fp_p = alpha_compare.fp_p;
2653 enum machine_mode cmp_mode
2654 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
2655 enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
2656 enum machine_mode cmov_mode = VOIDmode;
2657 int local_fast_math = flag_unsafe_math_optimizations;
2658 rtx tem;
2660 /* Zero the operands. */
2661 memset (&alpha_compare, 0, sizeof (alpha_compare));
2663 if (fp_p != FLOAT_MODE_P (mode))
2665 enum rtx_code cmp_code;
2667 if (! TARGET_FIX)
2668 return 0;
2670 /* If we have fp<->int register move instructions, do a cmov by
2671 performing the comparison in fp registers, and move the
2672 zero/nonzero value to integer registers, where we can then
2673 use a normal cmov, or vice-versa. */
2675 switch (code)
2677 case EQ: case LE: case LT: case LEU: case LTU:
2678 /* We have these compares. */
2679 cmp_code = code, code = NE;
2680 break;
2682 case NE:
2683 /* This must be reversed. */
2684 cmp_code = EQ, code = EQ;
2685 break;
2687 case GE: case GT: case GEU: case GTU:
2688 /* These normally need swapping, but for integer zero we have
2689 special patterns that recognize swapped operands. */
2690 if (!fp_p && op1 == const0_rtx)
2691 cmp_code = code, code = NE;
2692 else
2694 cmp_code = swap_condition (code);
2695 code = NE;
2696 tem = op0, op0 = op1, op1 = tem;
2698 break;
2700 default:
2701 gcc_unreachable ();
2704 tem = gen_reg_rtx (cmp_op_mode);
2705 emit_insn (gen_rtx_SET (VOIDmode, tem,
2706 gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
2707 op0, op1)));
2709 cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
2710 op0 = gen_lowpart (cmp_op_mode, tem);
2711 op1 = CONST0_RTX (cmp_op_mode);
2712 fp_p = !fp_p;
2713 local_fast_math = 1;
2716 /* We may be able to use a conditional move directly.
2717 This avoids emitting spurious compares. */
2718 if (signed_comparison_operator (cmp, VOIDmode)
2719 && (!fp_p || local_fast_math)
2720 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
2721 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
2723 /* We can't put the comparison inside the conditional move;
2724 emit a compare instruction and put that inside the
2725 conditional move. Make sure we emit only comparisons we have;
2726 swap or reverse as necessary. */
2728 if (!can_create_pseudo_p ())
2729 return NULL_RTX;
2731 switch (code)
2733 case EQ: case LE: case LT: case LEU: case LTU:
2734 /* We have these compares: */
2735 break;
2737 case NE:
2738 /* This must be reversed. */
2739 code = reverse_condition (code);
2740 cmov_code = EQ;
2741 break;
2743 case GE: case GT: case GEU: case GTU:
2744 /* These must be swapped. */
2745 if (op1 != CONST0_RTX (cmp_mode))
2747 code = swap_condition (code);
2748 tem = op0, op0 = op1, op1 = tem;
2750 break;
2752 default:
2753 gcc_unreachable ();
2756 if (!fp_p)
2758 if (!reg_or_0_operand (op0, DImode))
2759 op0 = force_reg (DImode, op0);
2760 if (!reg_or_8bit_operand (op1, DImode))
2761 op1 = force_reg (DImode, op1);
2764 /* ??? We mark the branch mode to be CCmode to prevent the compare
2765 and cmov from being combined, since the compare insn follows IEEE
2766 rules that the cmov does not. */
2767 if (fp_p && !local_fast_math)
2768 cmov_mode = CCmode;
2770 tem = gen_reg_rtx (cmp_op_mode);
2771 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
2772 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
2775 /* Simplify a conditional move of two constants into a setcc with
2776 arithmetic. This is done with a splitter since combine would
2777 just undo the work if done during code generation. It also catches
2778 cases we wouldn't have before cse. */
2781 alpha_split_conditional_move (enum rtx_code code, rtx dest, rtx cond,
2782 rtx t_rtx, rtx f_rtx)
2784 HOST_WIDE_INT t, f, diff;
2785 enum machine_mode mode;
2786 rtx target, subtarget, tmp;
2788 mode = GET_MODE (dest);
2789 t = INTVAL (t_rtx);
2790 f = INTVAL (f_rtx);
2791 diff = t - f;
2793 if (((code == NE || code == EQ) && diff < 0)
2794 || (code == GE || code == GT))
2796 code = reverse_condition (code);
2797 diff = t, t = f, f = diff;
2798 diff = t - f;
2801 subtarget = target = dest;
2802 if (mode != DImode)
2804 target = gen_lowpart (DImode, dest);
2805 if (can_create_pseudo_p ())
2806 subtarget = gen_reg_rtx (DImode);
2807 else
2808 subtarget = target;
2810 /* Below, we must be careful to use copy_rtx on target and subtarget
2811 in intermediate insns, as they may be a subreg rtx, which may not
2812 be shared. */
2814 if (f == 0 && exact_log2 (diff) > 0
2815 /* On EV6, we've got enough shifters to make non-arithmetic shifts
2816 viable over a longer latency cmove. On EV5, the E0 slot is a
2817 scarce resource, and on EV4 shift has the same latency as a cmove. */
2818 && (diff <= 8 || alpha_tune == PROCESSOR_EV6))
2820 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2821 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2823 tmp = gen_rtx_ASHIFT (DImode, copy_rtx (subtarget),
2824 GEN_INT (exact_log2 (t)));
2825 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
2827 else if (f == 0 && t == -1)
2829 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2830 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2832 emit_insn (gen_negdi2 (target, copy_rtx (subtarget)));
2834 else if (diff == 1 || diff == 4 || diff == 8)
2836 rtx add_op;
2838 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2839 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2841 if (diff == 1)
2842 emit_insn (gen_adddi3 (target, copy_rtx (subtarget), GEN_INT (f)));
2843 else
2845 add_op = GEN_INT (f);
2846 if (sext_add_operand (add_op, mode))
2848 tmp = gen_rtx_MULT (DImode, copy_rtx (subtarget),
2849 GEN_INT (diff));
2850 tmp = gen_rtx_PLUS (DImode, tmp, add_op);
2851 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
2853 else
2854 return 0;
2857 else
2858 return 0;
2860 return 1;
2863 /* Look up the function X_floating library function name for the
2864 given operation. */
2866 struct xfloating_op GTY(())
2868 const enum rtx_code code;
2869 const char *const GTY((skip)) osf_func;
2870 const char *const GTY((skip)) vms_func;
2871 rtx libcall;
2874 static GTY(()) struct xfloating_op xfloating_ops[] =
2876 { PLUS, "_OtsAddX", "OTS$ADD_X", 0 },
2877 { MINUS, "_OtsSubX", "OTS$SUB_X", 0 },
2878 { MULT, "_OtsMulX", "OTS$MUL_X", 0 },
2879 { DIV, "_OtsDivX", "OTS$DIV_X", 0 },
2880 { EQ, "_OtsEqlX", "OTS$EQL_X", 0 },
2881 { NE, "_OtsNeqX", "OTS$NEQ_X", 0 },
2882 { LT, "_OtsLssX", "OTS$LSS_X", 0 },
2883 { LE, "_OtsLeqX", "OTS$LEQ_X", 0 },
2884 { GT, "_OtsGtrX", "OTS$GTR_X", 0 },
2885 { GE, "_OtsGeqX", "OTS$GEQ_X", 0 },
2886 { FIX, "_OtsCvtXQ", "OTS$CVTXQ", 0 },
2887 { FLOAT, "_OtsCvtQX", "OTS$CVTQX", 0 },
2888 { UNSIGNED_FLOAT, "_OtsCvtQUX", "OTS$CVTQUX", 0 },
2889 { FLOAT_EXTEND, "_OtsConvertFloatTX", "OTS$CVT_FLOAT_T_X", 0 },
2890 { FLOAT_TRUNCATE, "_OtsConvertFloatXT", "OTS$CVT_FLOAT_X_T", 0 }
2893 static GTY(()) struct xfloating_op vax_cvt_ops[] =
2895 { FLOAT_EXTEND, "_OtsConvertFloatGX", "OTS$CVT_FLOAT_G_X", 0 },
2896 { FLOAT_TRUNCATE, "_OtsConvertFloatXG", "OTS$CVT_FLOAT_X_G", 0 }
2899 static rtx
2900 alpha_lookup_xfloating_lib_func (enum rtx_code code)
2902 struct xfloating_op *ops = xfloating_ops;
2903 long n = ARRAY_SIZE (xfloating_ops);
2904 long i;
2906 gcc_assert (TARGET_HAS_XFLOATING_LIBS);
2908 /* How irritating. Nothing to key off for the main table. */
2909 if (TARGET_FLOAT_VAX && (code == FLOAT_EXTEND || code == FLOAT_TRUNCATE))
2911 ops = vax_cvt_ops;
2912 n = ARRAY_SIZE (vax_cvt_ops);
2915 for (i = 0; i < n; ++i, ++ops)
2916 if (ops->code == code)
2918 rtx func = ops->libcall;
2919 if (!func)
2921 func = init_one_libfunc (TARGET_ABI_OPEN_VMS
2922 ? ops->vms_func : ops->osf_func);
2923 ops->libcall = func;
2925 return func;
2928 gcc_unreachable ();
2931 /* Most X_floating operations take the rounding mode as an argument.
2932 Compute that here. */
2934 static int
2935 alpha_compute_xfloating_mode_arg (enum rtx_code code,
2936 enum alpha_fp_rounding_mode round)
2938 int mode;
2940 switch (round)
2942 case ALPHA_FPRM_NORM:
2943 mode = 2;
2944 break;
2945 case ALPHA_FPRM_MINF:
2946 mode = 1;
2947 break;
2948 case ALPHA_FPRM_CHOP:
2949 mode = 0;
2950 break;
2951 case ALPHA_FPRM_DYN:
2952 mode = 4;
2953 break;
2954 default:
2955 gcc_unreachable ();
2957 /* XXX For reference, round to +inf is mode = 3. */
2960 if (code == FLOAT_TRUNCATE && alpha_fptm == ALPHA_FPTM_N)
2961 mode |= 0x10000;
2963 return mode;
2966 /* Emit an X_floating library function call.
2968 Note that these functions do not follow normal calling conventions:
2969 TFmode arguments are passed in two integer registers (as opposed to
2970 indirect); TFmode return values appear in R16+R17.
2972 FUNC is the function to call.
2973 TARGET is where the output belongs.
2974 OPERANDS are the inputs.
2975 NOPERANDS is the count of inputs.
2976 EQUIV is the expression equivalent for the function.
2979 static void
2980 alpha_emit_xfloating_libcall (rtx func, rtx target, rtx operands[],
2981 int noperands, rtx equiv)
2983 rtx usage = NULL_RTX, tmp, reg;
2984 int regno = 16, i;
2986 start_sequence ();
2988 for (i = 0; i < noperands; ++i)
2990 switch (GET_MODE (operands[i]))
2992 case TFmode:
2993 reg = gen_rtx_REG (TFmode, regno);
2994 regno += 2;
2995 break;
2997 case DFmode:
2998 reg = gen_rtx_REG (DFmode, regno + 32);
2999 regno += 1;
3000 break;
3002 case VOIDmode:
3003 gcc_assert (GET_CODE (operands[i]) == CONST_INT);
3004 /* FALLTHRU */
3005 case DImode:
3006 reg = gen_rtx_REG (DImode, regno);
3007 regno += 1;
3008 break;
3010 default:
3011 gcc_unreachable ();
3014 emit_move_insn (reg, operands[i]);
3015 usage = alloc_EXPR_LIST (0, gen_rtx_USE (VOIDmode, reg), usage);
3018 switch (GET_MODE (target))
3020 case TFmode:
3021 reg = gen_rtx_REG (TFmode, 16);
3022 break;
3023 case DFmode:
3024 reg = gen_rtx_REG (DFmode, 32);
3025 break;
3026 case DImode:
3027 reg = gen_rtx_REG (DImode, 0);
3028 break;
3029 default:
3030 gcc_unreachable ();
3033 tmp = gen_rtx_MEM (QImode, func);
3034 tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
3035 const0_rtx, const0_rtx));
3036 CALL_INSN_FUNCTION_USAGE (tmp) = usage;
3037 RTL_CONST_CALL_P (tmp) = 1;
3039 tmp = get_insns ();
3040 end_sequence ();
3042 emit_libcall_block (tmp, target, reg, equiv);
3045 /* Emit an X_floating library function call for arithmetic (+,-,*,/). */
3047 void
3048 alpha_emit_xfloating_arith (enum rtx_code code, rtx operands[])
3050 rtx func;
3051 int mode;
3052 rtx out_operands[3];
3054 func = alpha_lookup_xfloating_lib_func (code);
3055 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
3057 out_operands[0] = operands[1];
3058 out_operands[1] = operands[2];
3059 out_operands[2] = GEN_INT (mode);
3060 alpha_emit_xfloating_libcall (func, operands[0], out_operands, 3,
3061 gen_rtx_fmt_ee (code, TFmode, operands[1],
3062 operands[2]));
3065 /* Emit an X_floating library function call for a comparison. */
3067 static rtx
3068 alpha_emit_xfloating_compare (enum rtx_code *pcode, rtx op0, rtx op1)
3070 enum rtx_code cmp_code, res_code;
3071 rtx func, out, operands[2], note;
3073 /* X_floating library comparison functions return
3074 -1 unordered
3075 0 false
3076 1 true
3077 Convert the compare against the raw return value. */
3079 cmp_code = *pcode;
3080 switch (cmp_code)
3082 case UNORDERED:
3083 cmp_code = EQ;
3084 res_code = LT;
3085 break;
3086 case ORDERED:
3087 cmp_code = EQ;
3088 res_code = GE;
3089 break;
3090 case NE:
3091 res_code = NE;
3092 break;
3093 case EQ:
3094 case LT:
3095 case GT:
3096 case LE:
3097 case GE:
3098 res_code = GT;
3099 break;
3100 default:
3101 gcc_unreachable ();
3103 *pcode = res_code;
3105 func = alpha_lookup_xfloating_lib_func (cmp_code);
3107 operands[0] = op0;
3108 operands[1] = op1;
3109 out = gen_reg_rtx (DImode);
3111 /* What's actually returned is -1,0,1, not a proper boolean value,
3112 so use an EXPR_LIST as with a generic libcall instead of a
3113 comparison type expression. */
3114 note = gen_rtx_EXPR_LIST (VOIDmode, op1, NULL_RTX);
3115 note = gen_rtx_EXPR_LIST (VOIDmode, op0, note);
3116 note = gen_rtx_EXPR_LIST (VOIDmode, func, note);
3117 alpha_emit_xfloating_libcall (func, out, operands, 2, note);
3119 return out;
3122 /* Emit an X_floating library function call for a conversion. */
3124 void
3125 alpha_emit_xfloating_cvt (enum rtx_code orig_code, rtx operands[])
3127 int noperands = 1, mode;
3128 rtx out_operands[2];
3129 rtx func;
3130 enum rtx_code code = orig_code;
3132 if (code == UNSIGNED_FIX)
3133 code = FIX;
3135 func = alpha_lookup_xfloating_lib_func (code);
3137 out_operands[0] = operands[1];
3139 switch (code)
3141 case FIX:
3142 mode = alpha_compute_xfloating_mode_arg (code, ALPHA_FPRM_CHOP);
3143 out_operands[1] = GEN_INT (mode);
3144 noperands = 2;
3145 break;
3146 case FLOAT_TRUNCATE:
3147 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
3148 out_operands[1] = GEN_INT (mode);
3149 noperands = 2;
3150 break;
3151 default:
3152 break;
3155 alpha_emit_xfloating_libcall (func, operands[0], out_operands, noperands,
3156 gen_rtx_fmt_e (orig_code,
3157 GET_MODE (operands[0]),
3158 operands[1]));
3161 /* Split a TImode or TFmode move from OP[1] to OP[0] into a pair of
3162 DImode moves from OP[2,3] to OP[0,1]. If FIXUP_OVERLAP is true,
3163 guarantee that the sequence
3164 set (OP[0] OP[2])
3165 set (OP[1] OP[3])
3166 is valid. Naturally, output operand ordering is little-endian.
3167 This is used by *movtf_internal and *movti_internal. */
3169 void
3170 alpha_split_tmode_pair (rtx operands[4], enum machine_mode mode,
3171 bool fixup_overlap)
3173 switch (GET_CODE (operands[1]))
3175 case REG:
3176 operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
3177 operands[2] = gen_rtx_REG (DImode, REGNO (operands[1]));
3178 break;
3180 case MEM:
3181 operands[3] = adjust_address (operands[1], DImode, 8);
3182 operands[2] = adjust_address (operands[1], DImode, 0);
3183 break;
3185 case CONST_INT:
3186 case CONST_DOUBLE:
3187 gcc_assert (operands[1] == CONST0_RTX (mode));
3188 operands[2] = operands[3] = const0_rtx;
3189 break;
3191 default:
3192 gcc_unreachable ();
3195 switch (GET_CODE (operands[0]))
3197 case REG:
3198 operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
3199 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
3200 break;
3202 case MEM:
3203 operands[1] = adjust_address (operands[0], DImode, 8);
3204 operands[0] = adjust_address (operands[0], DImode, 0);
3205 break;
3207 default:
3208 gcc_unreachable ();
3211 if (fixup_overlap && reg_overlap_mentioned_p (operands[0], operands[3]))
3213 rtx tmp;
3214 tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
3215 tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
3219 /* Implement negtf2 or abstf2. Op0 is destination, op1 is source,
3220 op2 is a register containing the sign bit, operation is the
3221 logical operation to be performed. */
3223 void
3224 alpha_split_tfmode_frobsign (rtx operands[3], rtx (*operation) (rtx, rtx, rtx))
3226 rtx high_bit = operands[2];
3227 rtx scratch;
3228 int move;
3230 alpha_split_tmode_pair (operands, TFmode, false);
3232 /* Detect three flavors of operand overlap. */
3233 move = 1;
3234 if (rtx_equal_p (operands[0], operands[2]))
3235 move = 0;
3236 else if (rtx_equal_p (operands[1], operands[2]))
3238 if (rtx_equal_p (operands[0], high_bit))
3239 move = 2;
3240 else
3241 move = -1;
3244 if (move < 0)
3245 emit_move_insn (operands[0], operands[2]);
3247 /* ??? If the destination overlaps both source tf and high_bit, then
3248 assume source tf is dead in its entirety and use the other half
3249 for a scratch register. Otherwise "scratch" is just the proper
3250 destination register. */
3251 scratch = operands[move < 2 ? 1 : 3];
3253 emit_insn ((*operation) (scratch, high_bit, operands[3]));
3255 if (move > 0)
3257 emit_move_insn (operands[0], operands[2]);
3258 if (move > 1)
3259 emit_move_insn (operands[1], scratch);
3263 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
3264 unaligned data:
3266 unsigned: signed:
3267 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
3268 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
3269 lda r3,X(r11) lda r3,X+2(r11)
3270 extwl r1,r3,r1 extql r1,r3,r1
3271 extwh r2,r3,r2 extqh r2,r3,r2
3272 or r1.r2.r1 or r1,r2,r1
3273 sra r1,48,r1
3275 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
3276 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
3277 lda r3,X(r11) lda r3,X(r11)
3278 extll r1,r3,r1 extll r1,r3,r1
3279 extlh r2,r3,r2 extlh r2,r3,r2
3280 or r1.r2.r1 addl r1,r2,r1
3282 quad: ldq_u r1,X(r11)
3283 ldq_u r2,X+7(r11)
3284 lda r3,X(r11)
3285 extql r1,r3,r1
3286 extqh r2,r3,r2
3287 or r1.r2.r1
3290 void
3291 alpha_expand_unaligned_load (rtx tgt, rtx mem, HOST_WIDE_INT size,
3292 HOST_WIDE_INT ofs, int sign)
3294 rtx meml, memh, addr, extl, exth, tmp, mema;
3295 enum machine_mode mode;
3297 if (TARGET_BWX && size == 2)
3299 meml = adjust_address (mem, QImode, ofs);
3300 memh = adjust_address (mem, QImode, ofs+1);
3301 if (BYTES_BIG_ENDIAN)
3302 tmp = meml, meml = memh, memh = tmp;
3303 extl = gen_reg_rtx (DImode);
3304 exth = gen_reg_rtx (DImode);
3305 emit_insn (gen_zero_extendqidi2 (extl, meml));
3306 emit_insn (gen_zero_extendqidi2 (exth, memh));
3307 exth = expand_simple_binop (DImode, ASHIFT, exth, GEN_INT (8),
3308 NULL, 1, OPTAB_LIB_WIDEN);
3309 addr = expand_simple_binop (DImode, IOR, extl, exth,
3310 NULL, 1, OPTAB_LIB_WIDEN);
3312 if (sign && GET_MODE (tgt) != HImode)
3314 addr = gen_lowpart (HImode, addr);
3315 emit_insn (gen_extend_insn (tgt, addr, GET_MODE (tgt), HImode, 0));
3317 else
3319 if (GET_MODE (tgt) != DImode)
3320 addr = gen_lowpart (GET_MODE (tgt), addr);
3321 emit_move_insn (tgt, addr);
3323 return;
3326 meml = gen_reg_rtx (DImode);
3327 memh = gen_reg_rtx (DImode);
3328 addr = gen_reg_rtx (DImode);
3329 extl = gen_reg_rtx (DImode);
3330 exth = gen_reg_rtx (DImode);
3332 mema = XEXP (mem, 0);
3333 if (GET_CODE (mema) == LO_SUM)
3334 mema = force_reg (Pmode, mema);
3336 /* AND addresses cannot be in any alias set, since they may implicitly
3337 alias surrounding code. Ideally we'd have some alias set that
3338 covered all types except those with alignment 8 or higher. */
3340 tmp = change_address (mem, DImode,
3341 gen_rtx_AND (DImode,
3342 plus_constant (mema, ofs),
3343 GEN_INT (-8)));
3344 set_mem_alias_set (tmp, 0);
3345 emit_move_insn (meml, tmp);
3347 tmp = change_address (mem, DImode,
3348 gen_rtx_AND (DImode,
3349 plus_constant (mema, ofs + size - 1),
3350 GEN_INT (-8)));
3351 set_mem_alias_set (tmp, 0);
3352 emit_move_insn (memh, tmp);
3354 if (WORDS_BIG_ENDIAN && sign && (size == 2 || size == 4))
3356 emit_move_insn (addr, plus_constant (mema, -1));
3358 emit_insn (gen_extqh_be (extl, meml, addr));
3359 emit_insn (gen_extxl_be (exth, memh, GEN_INT (64), addr));
3361 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
3362 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (64 - size*8),
3363 addr, 1, OPTAB_WIDEN);
3365 else if (sign && size == 2)
3367 emit_move_insn (addr, plus_constant (mema, ofs+2));
3369 emit_insn (gen_extxl_le (extl, meml, GEN_INT (64), addr));
3370 emit_insn (gen_extqh_le (exth, memh, addr));
3372 /* We must use tgt here for the target. Alpha-vms port fails if we use
3373 addr for the target, because addr is marked as a pointer and combine
3374 knows that pointers are always sign-extended 32-bit values. */
3375 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
3376 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
3377 addr, 1, OPTAB_WIDEN);
3379 else
3381 if (WORDS_BIG_ENDIAN)
3383 emit_move_insn (addr, plus_constant (mema, ofs+size-1));
3384 switch ((int) size)
3386 case 2:
3387 emit_insn (gen_extwh_be (extl, meml, addr));
3388 mode = HImode;
3389 break;
3391 case 4:
3392 emit_insn (gen_extlh_be (extl, meml, addr));
3393 mode = SImode;
3394 break;
3396 case 8:
3397 emit_insn (gen_extqh_be (extl, meml, addr));
3398 mode = DImode;
3399 break;
3401 default:
3402 gcc_unreachable ();
3404 emit_insn (gen_extxl_be (exth, memh, GEN_INT (size*8), addr));
3406 else
3408 emit_move_insn (addr, plus_constant (mema, ofs));
3409 emit_insn (gen_extxl_le (extl, meml, GEN_INT (size*8), addr));
3410 switch ((int) size)
3412 case 2:
3413 emit_insn (gen_extwh_le (exth, memh, addr));
3414 mode = HImode;
3415 break;
3417 case 4:
3418 emit_insn (gen_extlh_le (exth, memh, addr));
3419 mode = SImode;
3420 break;
3422 case 8:
3423 emit_insn (gen_extqh_le (exth, memh, addr));
3424 mode = DImode;
3425 break;
3427 default:
3428 gcc_unreachable ();
3432 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
3433 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
3434 sign, OPTAB_WIDEN);
3437 if (addr != tgt)
3438 emit_move_insn (tgt, gen_lowpart (GET_MODE (tgt), addr));
3441 /* Similarly, use ins and msk instructions to perform unaligned stores. */
3443 void
3444 alpha_expand_unaligned_store (rtx dst, rtx src,
3445 HOST_WIDE_INT size, HOST_WIDE_INT ofs)
3447 rtx dstl, dsth, addr, insl, insh, meml, memh, dsta;
3449 if (TARGET_BWX && size == 2)
3451 if (src != const0_rtx)
3453 dstl = gen_lowpart (QImode, src);
3454 dsth = expand_simple_binop (DImode, LSHIFTRT, src, GEN_INT (8),
3455 NULL, 1, OPTAB_LIB_WIDEN);
3456 dsth = gen_lowpart (QImode, dsth);
3458 else
3459 dstl = dsth = const0_rtx;
3461 meml = adjust_address (dst, QImode, ofs);
3462 memh = adjust_address (dst, QImode, ofs+1);
3463 if (BYTES_BIG_ENDIAN)
3464 addr = meml, meml = memh, memh = addr;
3466 emit_move_insn (meml, dstl);
3467 emit_move_insn (memh, dsth);
3468 return;
3471 dstl = gen_reg_rtx (DImode);
3472 dsth = gen_reg_rtx (DImode);
3473 insl = gen_reg_rtx (DImode);
3474 insh = gen_reg_rtx (DImode);
3476 dsta = XEXP (dst, 0);
3477 if (GET_CODE (dsta) == LO_SUM)
3478 dsta = force_reg (Pmode, dsta);
3480 /* AND addresses cannot be in any alias set, since they may implicitly
3481 alias surrounding code. Ideally we'd have some alias set that
3482 covered all types except those with alignment 8 or higher. */
3484 meml = change_address (dst, DImode,
3485 gen_rtx_AND (DImode,
3486 plus_constant (dsta, ofs),
3487 GEN_INT (-8)));
3488 set_mem_alias_set (meml, 0);
3490 memh = change_address (dst, DImode,
3491 gen_rtx_AND (DImode,
3492 plus_constant (dsta, ofs + size - 1),
3493 GEN_INT (-8)));
3494 set_mem_alias_set (memh, 0);
3496 emit_move_insn (dsth, memh);
3497 emit_move_insn (dstl, meml);
3498 if (WORDS_BIG_ENDIAN)
3500 addr = copy_addr_to_reg (plus_constant (dsta, ofs+size-1));
3502 if (src != const0_rtx)
3504 switch ((int) size)
3506 case 2:
3507 emit_insn (gen_inswl_be (insh, gen_lowpart (HImode,src), addr));
3508 break;
3509 case 4:
3510 emit_insn (gen_insll_be (insh, gen_lowpart (SImode,src), addr));
3511 break;
3512 case 8:
3513 emit_insn (gen_insql_be (insh, gen_lowpart (DImode,src), addr));
3514 break;
3516 emit_insn (gen_insxh (insl, gen_lowpart (DImode, src),
3517 GEN_INT (size*8), addr));
3520 switch ((int) size)
3522 case 2:
3523 emit_insn (gen_mskxl_be (dsth, dsth, GEN_INT (0xffff), addr));
3524 break;
3525 case 4:
3527 rtx msk = immed_double_const (0xffffffff, 0, DImode);
3528 emit_insn (gen_mskxl_be (dsth, dsth, msk, addr));
3529 break;
3531 case 8:
3532 emit_insn (gen_mskxl_be (dsth, dsth, constm1_rtx, addr));
3533 break;
3536 emit_insn (gen_mskxh (dstl, dstl, GEN_INT (size*8), addr));
3538 else
3540 addr = copy_addr_to_reg (plus_constant (dsta, ofs));
3542 if (src != CONST0_RTX (GET_MODE (src)))
3544 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
3545 GEN_INT (size*8), addr));
3547 switch ((int) size)
3549 case 2:
3550 emit_insn (gen_inswl_le (insl, gen_lowpart (HImode, src), addr));
3551 break;
3552 case 4:
3553 emit_insn (gen_insll_le (insl, gen_lowpart (SImode, src), addr));
3554 break;
3555 case 8:
3556 emit_insn (gen_insql_le (insl, gen_lowpart (DImode, src), addr));
3557 break;
3561 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
3563 switch ((int) size)
3565 case 2:
3566 emit_insn (gen_mskxl_le (dstl, dstl, GEN_INT (0xffff), addr));
3567 break;
3568 case 4:
3570 rtx msk = immed_double_const (0xffffffff, 0, DImode);
3571 emit_insn (gen_mskxl_le (dstl, dstl, msk, addr));
3572 break;
3574 case 8:
3575 emit_insn (gen_mskxl_le (dstl, dstl, constm1_rtx, addr));
3576 break;
3580 if (src != CONST0_RTX (GET_MODE (src)))
3582 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
3583 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
3586 if (WORDS_BIG_ENDIAN)
3588 emit_move_insn (meml, dstl);
3589 emit_move_insn (memh, dsth);
3591 else
3593 /* Must store high before low for degenerate case of aligned. */
3594 emit_move_insn (memh, dsth);
3595 emit_move_insn (meml, dstl);
3599 /* The block move code tries to maximize speed by separating loads and
3600 stores at the expense of register pressure: we load all of the data
3601 before we store it back out. There are two secondary effects worth
3602 mentioning, that this speeds copying to/from aligned and unaligned
3603 buffers, and that it makes the code significantly easier to write. */
3605 #define MAX_MOVE_WORDS 8
3607 /* Load an integral number of consecutive unaligned quadwords. */
3609 static void
3610 alpha_expand_unaligned_load_words (rtx *out_regs, rtx smem,
3611 HOST_WIDE_INT words, HOST_WIDE_INT ofs)
3613 rtx const im8 = GEN_INT (-8);
3614 rtx const i64 = GEN_INT (64);
3615 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
3616 rtx sreg, areg, tmp, smema;
3617 HOST_WIDE_INT i;
3619 smema = XEXP (smem, 0);
3620 if (GET_CODE (smema) == LO_SUM)
3621 smema = force_reg (Pmode, smema);
3623 /* Generate all the tmp registers we need. */
3624 for (i = 0; i < words; ++i)
3626 data_regs[i] = out_regs[i];
3627 ext_tmps[i] = gen_reg_rtx (DImode);
3629 data_regs[words] = gen_reg_rtx (DImode);
3631 if (ofs != 0)
3632 smem = adjust_address (smem, GET_MODE (smem), ofs);
3634 /* Load up all of the source data. */
3635 for (i = 0; i < words; ++i)
3637 tmp = change_address (smem, DImode,
3638 gen_rtx_AND (DImode,
3639 plus_constant (smema, 8*i),
3640 im8));
3641 set_mem_alias_set (tmp, 0);
3642 emit_move_insn (data_regs[i], tmp);
3645 tmp = change_address (smem, DImode,
3646 gen_rtx_AND (DImode,
3647 plus_constant (smema, 8*words - 1),
3648 im8));
3649 set_mem_alias_set (tmp, 0);
3650 emit_move_insn (data_regs[words], tmp);
3652 /* Extract the half-word fragments. Unfortunately DEC decided to make
3653 extxh with offset zero a noop instead of zeroing the register, so
3654 we must take care of that edge condition ourselves with cmov. */
3656 sreg = copy_addr_to_reg (smema);
3657 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
3658 1, OPTAB_WIDEN);
3659 if (WORDS_BIG_ENDIAN)
3660 emit_move_insn (sreg, plus_constant (sreg, 7));
3661 for (i = 0; i < words; ++i)
3663 if (WORDS_BIG_ENDIAN)
3665 emit_insn (gen_extqh_be (data_regs[i], data_regs[i], sreg));
3666 emit_insn (gen_extxl_be (ext_tmps[i], data_regs[i+1], i64, sreg));
3668 else
3670 emit_insn (gen_extxl_le (data_regs[i], data_regs[i], i64, sreg));
3671 emit_insn (gen_extqh_le (ext_tmps[i], data_regs[i+1], sreg));
3673 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
3674 gen_rtx_IF_THEN_ELSE (DImode,
3675 gen_rtx_EQ (DImode, areg,
3676 const0_rtx),
3677 const0_rtx, ext_tmps[i])));
3680 /* Merge the half-words into whole words. */
3681 for (i = 0; i < words; ++i)
3683 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
3684 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
3688 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
3689 may be NULL to store zeros. */
3691 static void
3692 alpha_expand_unaligned_store_words (rtx *data_regs, rtx dmem,
3693 HOST_WIDE_INT words, HOST_WIDE_INT ofs)
3695 rtx const im8 = GEN_INT (-8);
3696 rtx const i64 = GEN_INT (64);
3697 rtx ins_tmps[MAX_MOVE_WORDS];
3698 rtx st_tmp_1, st_tmp_2, dreg;
3699 rtx st_addr_1, st_addr_2, dmema;
3700 HOST_WIDE_INT i;
3702 dmema = XEXP (dmem, 0);
3703 if (GET_CODE (dmema) == LO_SUM)
3704 dmema = force_reg (Pmode, dmema);
3706 /* Generate all the tmp registers we need. */
3707 if (data_regs != NULL)
3708 for (i = 0; i < words; ++i)
3709 ins_tmps[i] = gen_reg_rtx(DImode);
3710 st_tmp_1 = gen_reg_rtx(DImode);
3711 st_tmp_2 = gen_reg_rtx(DImode);
3713 if (ofs != 0)
3714 dmem = adjust_address (dmem, GET_MODE (dmem), ofs);
3716 st_addr_2 = change_address (dmem, DImode,
3717 gen_rtx_AND (DImode,
3718 plus_constant (dmema, words*8 - 1),
3719 im8));
3720 set_mem_alias_set (st_addr_2, 0);
3722 st_addr_1 = change_address (dmem, DImode,
3723 gen_rtx_AND (DImode, dmema, im8));
3724 set_mem_alias_set (st_addr_1, 0);
3726 /* Load up the destination end bits. */
3727 emit_move_insn (st_tmp_2, st_addr_2);
3728 emit_move_insn (st_tmp_1, st_addr_1);
3730 /* Shift the input data into place. */
3731 dreg = copy_addr_to_reg (dmema);
3732 if (WORDS_BIG_ENDIAN)
3733 emit_move_insn (dreg, plus_constant (dreg, 7));
3734 if (data_regs != NULL)
3736 for (i = words-1; i >= 0; --i)
3738 if (WORDS_BIG_ENDIAN)
3740 emit_insn (gen_insql_be (ins_tmps[i], data_regs[i], dreg));
3741 emit_insn (gen_insxh (data_regs[i], data_regs[i], i64, dreg));
3743 else
3745 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
3746 emit_insn (gen_insql_le (data_regs[i], data_regs[i], dreg));
3749 for (i = words-1; i > 0; --i)
3751 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
3752 ins_tmps[i-1], ins_tmps[i-1], 1,
3753 OPTAB_WIDEN);
3757 /* Split and merge the ends with the destination data. */
3758 if (WORDS_BIG_ENDIAN)
3760 emit_insn (gen_mskxl_be (st_tmp_2, st_tmp_2, constm1_rtx, dreg));
3761 emit_insn (gen_mskxh (st_tmp_1, st_tmp_1, i64, dreg));
3763 else
3765 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
3766 emit_insn (gen_mskxl_le (st_tmp_1, st_tmp_1, constm1_rtx, dreg));
3769 if (data_regs != NULL)
3771 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
3772 st_tmp_2, 1, OPTAB_WIDEN);
3773 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
3774 st_tmp_1, 1, OPTAB_WIDEN);
3777 /* Store it all. */
3778 if (WORDS_BIG_ENDIAN)
3779 emit_move_insn (st_addr_1, st_tmp_1);
3780 else
3781 emit_move_insn (st_addr_2, st_tmp_2);
3782 for (i = words-1; i > 0; --i)
3784 rtx tmp = change_address (dmem, DImode,
3785 gen_rtx_AND (DImode,
3786 plus_constant(dmema,
3787 WORDS_BIG_ENDIAN ? i*8-1 : i*8),
3788 im8));
3789 set_mem_alias_set (tmp, 0);
3790 emit_move_insn (tmp, data_regs ? ins_tmps[i-1] : const0_rtx);
3792 if (WORDS_BIG_ENDIAN)
3793 emit_move_insn (st_addr_2, st_tmp_2);
3794 else
3795 emit_move_insn (st_addr_1, st_tmp_1);
3799 /* Expand string/block move operations.
3801 operands[0] is the pointer to the destination.
3802 operands[1] is the pointer to the source.
3803 operands[2] is the number of bytes to move.
3804 operands[3] is the alignment. */
3807 alpha_expand_block_move (rtx operands[])
3809 rtx bytes_rtx = operands[2];
3810 rtx align_rtx = operands[3];
3811 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
3812 HOST_WIDE_INT bytes = orig_bytes;
3813 HOST_WIDE_INT src_align = INTVAL (align_rtx) * BITS_PER_UNIT;
3814 HOST_WIDE_INT dst_align = src_align;
3815 rtx orig_src = operands[1];
3816 rtx orig_dst = operands[0];
3817 rtx data_regs[2 * MAX_MOVE_WORDS + 16];
3818 rtx tmp;
3819 unsigned int i, words, ofs, nregs = 0;
3821 if (orig_bytes <= 0)
3822 return 1;
3823 else if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
3824 return 0;
3826 /* Look for additional alignment information from recorded register info. */
3828 tmp = XEXP (orig_src, 0);
3829 if (GET_CODE (tmp) == REG)
3830 src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3831 else if (GET_CODE (tmp) == PLUS
3832 && GET_CODE (XEXP (tmp, 0)) == REG
3833 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3835 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3836 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3838 if (a > src_align)
3840 if (a >= 64 && c % 8 == 0)
3841 src_align = 64;
3842 else if (a >= 32 && c % 4 == 0)
3843 src_align = 32;
3844 else if (a >= 16 && c % 2 == 0)
3845 src_align = 16;
3849 tmp = XEXP (orig_dst, 0);
3850 if (GET_CODE (tmp) == REG)
3851 dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3852 else if (GET_CODE (tmp) == PLUS
3853 && GET_CODE (XEXP (tmp, 0)) == REG
3854 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3856 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3857 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3859 if (a > dst_align)
3861 if (a >= 64 && c % 8 == 0)
3862 dst_align = 64;
3863 else if (a >= 32 && c % 4 == 0)
3864 dst_align = 32;
3865 else if (a >= 16 && c % 2 == 0)
3866 dst_align = 16;
3870 ofs = 0;
3871 if (src_align >= 64 && bytes >= 8)
3873 words = bytes / 8;
3875 for (i = 0; i < words; ++i)
3876 data_regs[nregs + i] = gen_reg_rtx (DImode);
3878 for (i = 0; i < words; ++i)
3879 emit_move_insn (data_regs[nregs + i],
3880 adjust_address (orig_src, DImode, ofs + i * 8));
3882 nregs += words;
3883 bytes -= words * 8;
3884 ofs += words * 8;
3887 if (src_align >= 32 && bytes >= 4)
3889 words = bytes / 4;
3891 for (i = 0; i < words; ++i)
3892 data_regs[nregs + i] = gen_reg_rtx (SImode);
3894 for (i = 0; i < words; ++i)
3895 emit_move_insn (data_regs[nregs + i],
3896 adjust_address (orig_src, SImode, ofs + i * 4));
3898 nregs += words;
3899 bytes -= words * 4;
3900 ofs += words * 4;
3903 if (bytes >= 8)
3905 words = bytes / 8;
3907 for (i = 0; i < words+1; ++i)
3908 data_regs[nregs + i] = gen_reg_rtx (DImode);
3910 alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,
3911 words, ofs);
3913 nregs += words;
3914 bytes -= words * 8;
3915 ofs += words * 8;
3918 if (! TARGET_BWX && bytes >= 4)
3920 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
3921 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
3922 bytes -= 4;
3923 ofs += 4;
3926 if (bytes >= 2)
3928 if (src_align >= 16)
3930 do {
3931 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
3932 emit_move_insn (tmp, adjust_address (orig_src, HImode, ofs));
3933 bytes -= 2;
3934 ofs += 2;
3935 } while (bytes >= 2);
3937 else if (! TARGET_BWX)
3939 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
3940 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
3941 bytes -= 2;
3942 ofs += 2;
3946 while (bytes > 0)
3948 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
3949 emit_move_insn (tmp, adjust_address (orig_src, QImode, ofs));
3950 bytes -= 1;
3951 ofs += 1;
3954 gcc_assert (nregs <= ARRAY_SIZE (data_regs));
3956 /* Now save it back out again. */
3958 i = 0, ofs = 0;
3960 /* Write out the data in whatever chunks reading the source allowed. */
3961 if (dst_align >= 64)
3963 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
3965 emit_move_insn (adjust_address (orig_dst, DImode, ofs),
3966 data_regs[i]);
3967 ofs += 8;
3968 i++;
3972 if (dst_align >= 32)
3974 /* If the source has remaining DImode regs, write them out in
3975 two pieces. */
3976 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
3978 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
3979 NULL_RTX, 1, OPTAB_WIDEN);
3981 emit_move_insn (adjust_address (orig_dst, SImode, ofs),
3982 gen_lowpart (SImode, data_regs[i]));
3983 emit_move_insn (adjust_address (orig_dst, SImode, ofs + 4),
3984 gen_lowpart (SImode, tmp));
3985 ofs += 8;
3986 i++;
3989 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
3991 emit_move_insn (adjust_address (orig_dst, SImode, ofs),
3992 data_regs[i]);
3993 ofs += 4;
3994 i++;
3998 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
4000 /* Write out a remaining block of words using unaligned methods. */
4002 for (words = 1; i + words < nregs; words++)
4003 if (GET_MODE (data_regs[i + words]) != DImode)
4004 break;
4006 if (words == 1)
4007 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
4008 else
4009 alpha_expand_unaligned_store_words (data_regs + i, orig_dst,
4010 words, ofs);
4012 i += words;
4013 ofs += words * 8;
4016 /* Due to the above, this won't be aligned. */
4017 /* ??? If we have more than one of these, consider constructing full
4018 words in registers and using alpha_expand_unaligned_store_words. */
4019 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
4021 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
4022 ofs += 4;
4023 i++;
4026 if (dst_align >= 16)
4027 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
4029 emit_move_insn (adjust_address (orig_dst, HImode, ofs), data_regs[i]);
4030 i++;
4031 ofs += 2;
4033 else
4034 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
4036 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
4037 i++;
4038 ofs += 2;
4041 /* The remainder must be byte copies. */
4042 while (i < nregs)
4044 gcc_assert (GET_MODE (data_regs[i]) == QImode);
4045 emit_move_insn (adjust_address (orig_dst, QImode, ofs), data_regs[i]);
4046 i++;
4047 ofs += 1;
4050 return 1;
4054 alpha_expand_block_clear (rtx operands[])
4056 rtx bytes_rtx = operands[1];
4057 rtx align_rtx = operands[3];
4058 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
4059 HOST_WIDE_INT bytes = orig_bytes;
4060 HOST_WIDE_INT align = INTVAL (align_rtx) * BITS_PER_UNIT;
4061 HOST_WIDE_INT alignofs = 0;
4062 rtx orig_dst = operands[0];
4063 rtx tmp;
4064 int i, words, ofs = 0;
4066 if (orig_bytes <= 0)
4067 return 1;
4068 if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
4069 return 0;
4071 /* Look for stricter alignment. */
4072 tmp = XEXP (orig_dst, 0);
4073 if (GET_CODE (tmp) == REG)
4074 align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp)));
4075 else if (GET_CODE (tmp) == PLUS
4076 && GET_CODE (XEXP (tmp, 0)) == REG
4077 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
4079 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
4080 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
4082 if (a > align)
4084 if (a >= 64)
4085 align = a, alignofs = 8 - c % 8;
4086 else if (a >= 32)
4087 align = a, alignofs = 4 - c % 4;
4088 else if (a >= 16)
4089 align = a, alignofs = 2 - c % 2;
4093 /* Handle an unaligned prefix first. */
4095 if (alignofs > 0)
4097 #if HOST_BITS_PER_WIDE_INT >= 64
4098 /* Given that alignofs is bounded by align, the only time BWX could
4099 generate three stores is for a 7 byte fill. Prefer two individual
4100 stores over a load/mask/store sequence. */
4101 if ((!TARGET_BWX || alignofs == 7)
4102 && align >= 32
4103 && !(alignofs == 4 && bytes >= 4))
4105 enum machine_mode mode = (align >= 64 ? DImode : SImode);
4106 int inv_alignofs = (align >= 64 ? 8 : 4) - alignofs;
4107 rtx mem, tmp;
4108 HOST_WIDE_INT mask;
4110 mem = adjust_address (orig_dst, mode, ofs - inv_alignofs);
4111 set_mem_alias_set (mem, 0);
4113 mask = ~(~(HOST_WIDE_INT)0 << (inv_alignofs * 8));
4114 if (bytes < alignofs)
4116 mask |= ~(HOST_WIDE_INT)0 << ((inv_alignofs + bytes) * 8);
4117 ofs += bytes;
4118 bytes = 0;
4120 else
4122 bytes -= alignofs;
4123 ofs += alignofs;
4125 alignofs = 0;
4127 tmp = expand_binop (mode, and_optab, mem, GEN_INT (mask),
4128 NULL_RTX, 1, OPTAB_WIDEN);
4130 emit_move_insn (mem, tmp);
4132 #endif
4134 if (TARGET_BWX && (alignofs & 1) && bytes >= 1)
4136 emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
4137 bytes -= 1;
4138 ofs += 1;
4139 alignofs -= 1;
4141 if (TARGET_BWX && align >= 16 && (alignofs & 3) == 2 && bytes >= 2)
4143 emit_move_insn (adjust_address (orig_dst, HImode, ofs), const0_rtx);
4144 bytes -= 2;
4145 ofs += 2;
4146 alignofs -= 2;
4148 if (alignofs == 4 && bytes >= 4)
4150 emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
4151 bytes -= 4;
4152 ofs += 4;
4153 alignofs = 0;
4156 /* If we've not used the extra lead alignment information by now,
4157 we won't be able to. Downgrade align to match what's left over. */
4158 if (alignofs > 0)
4160 alignofs = alignofs & -alignofs;
4161 align = MIN (align, alignofs * BITS_PER_UNIT);
4165 /* Handle a block of contiguous long-words. */
4167 if (align >= 64 && bytes >= 8)
4169 words = bytes / 8;
4171 for (i = 0; i < words; ++i)
4172 emit_move_insn (adjust_address (orig_dst, DImode, ofs + i * 8),
4173 const0_rtx);
4175 bytes -= words * 8;
4176 ofs += words * 8;
4179 /* If the block is large and appropriately aligned, emit a single
4180 store followed by a sequence of stq_u insns. */
4182 if (align >= 32 && bytes > 16)
4184 rtx orig_dsta;
4186 emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
4187 bytes -= 4;
4188 ofs += 4;
4190 orig_dsta = XEXP (orig_dst, 0);
4191 if (GET_CODE (orig_dsta) == LO_SUM)
4192 orig_dsta = force_reg (Pmode, orig_dsta);
4194 words = bytes / 8;
4195 for (i = 0; i < words; ++i)
4197 rtx mem
4198 = change_address (orig_dst, DImode,
4199 gen_rtx_AND (DImode,
4200 plus_constant (orig_dsta, ofs + i*8),
4201 GEN_INT (-8)));
4202 set_mem_alias_set (mem, 0);
4203 emit_move_insn (mem, const0_rtx);
4206 /* Depending on the alignment, the first stq_u may have overlapped
4207 with the initial stl, which means that the last stq_u didn't
4208 write as much as it would appear. Leave those questionable bytes
4209 unaccounted for. */
4210 bytes -= words * 8 - 4;
4211 ofs += words * 8 - 4;
4214 /* Handle a smaller block of aligned words. */
4216 if ((align >= 64 && bytes == 4)
4217 || (align == 32 && bytes >= 4))
4219 words = bytes / 4;
4221 for (i = 0; i < words; ++i)
4222 emit_move_insn (adjust_address (orig_dst, SImode, ofs + i * 4),
4223 const0_rtx);
4225 bytes -= words * 4;
4226 ofs += words * 4;
4229 /* An unaligned block uses stq_u stores for as many as possible. */
4231 if (bytes >= 8)
4233 words = bytes / 8;
4235 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
4237 bytes -= words * 8;
4238 ofs += words * 8;
4241 /* Next clean up any trailing pieces. */
4243 #if HOST_BITS_PER_WIDE_INT >= 64
4244 /* Count the number of bits in BYTES for which aligned stores could
4245 be emitted. */
4246 words = 0;
4247 for (i = (TARGET_BWX ? 1 : 4); i * BITS_PER_UNIT <= align ; i <<= 1)
4248 if (bytes & i)
4249 words += 1;
4251 /* If we have appropriate alignment (and it wouldn't take too many
4252 instructions otherwise), mask out the bytes we need. */
4253 if (TARGET_BWX ? words > 2 : bytes > 0)
4255 if (align >= 64)
4257 rtx mem, tmp;
4258 HOST_WIDE_INT mask;
4260 mem = adjust_address (orig_dst, DImode, ofs);
4261 set_mem_alias_set (mem, 0);
4263 mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
4265 tmp = expand_binop (DImode, and_optab, mem, GEN_INT (mask),
4266 NULL_RTX, 1, OPTAB_WIDEN);
4268 emit_move_insn (mem, tmp);
4269 return 1;
4271 else if (align >= 32 && bytes < 4)
4273 rtx mem, tmp;
4274 HOST_WIDE_INT mask;
4276 mem = adjust_address (orig_dst, SImode, ofs);
4277 set_mem_alias_set (mem, 0);
4279 mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
4281 tmp = expand_binop (SImode, and_optab, mem, GEN_INT (mask),
4282 NULL_RTX, 1, OPTAB_WIDEN);
4284 emit_move_insn (mem, tmp);
4285 return 1;
4288 #endif
4290 if (!TARGET_BWX && bytes >= 4)
4292 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
4293 bytes -= 4;
4294 ofs += 4;
4297 if (bytes >= 2)
4299 if (align >= 16)
4301 do {
4302 emit_move_insn (adjust_address (orig_dst, HImode, ofs),
4303 const0_rtx);
4304 bytes -= 2;
4305 ofs += 2;
4306 } while (bytes >= 2);
4308 else if (! TARGET_BWX)
4310 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
4311 bytes -= 2;
4312 ofs += 2;
4316 while (bytes > 0)
4318 emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
4319 bytes -= 1;
4320 ofs += 1;
4323 return 1;
4326 /* Returns a mask so that zap(x, value) == x & mask. */
4329 alpha_expand_zap_mask (HOST_WIDE_INT value)
4331 rtx result;
4332 int i;
4334 if (HOST_BITS_PER_WIDE_INT >= 64)
4336 HOST_WIDE_INT mask = 0;
4338 for (i = 7; i >= 0; --i)
4340 mask <<= 8;
4341 if (!((value >> i) & 1))
4342 mask |= 0xff;
4345 result = gen_int_mode (mask, DImode);
4347 else
4349 HOST_WIDE_INT mask_lo = 0, mask_hi = 0;
4351 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
4353 for (i = 7; i >= 4; --i)
4355 mask_hi <<= 8;
4356 if (!((value >> i) & 1))
4357 mask_hi |= 0xff;
4360 for (i = 3; i >= 0; --i)
4362 mask_lo <<= 8;
4363 if (!((value >> i) & 1))
4364 mask_lo |= 0xff;
4367 result = immed_double_const (mask_lo, mask_hi, DImode);
4370 return result;
4373 void
4374 alpha_expand_builtin_vector_binop (rtx (*gen) (rtx, rtx, rtx),
4375 enum machine_mode mode,
4376 rtx op0, rtx op1, rtx op2)
4378 op0 = gen_lowpart (mode, op0);
4380 if (op1 == const0_rtx)
4381 op1 = CONST0_RTX (mode);
4382 else
4383 op1 = gen_lowpart (mode, op1);
4385 if (op2 == const0_rtx)
4386 op2 = CONST0_RTX (mode);
4387 else
4388 op2 = gen_lowpart (mode, op2);
4390 emit_insn ((*gen) (op0, op1, op2));
4393 /* A subroutine of the atomic operation splitters. Jump to LABEL if
4394 COND is true. Mark the jump as unlikely to be taken. */
4396 static void
4397 emit_unlikely_jump (rtx cond, rtx label)
4399 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
4400 rtx x;
4402 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
4403 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
4404 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
4407 /* A subroutine of the atomic operation splitters. Emit a load-locked
4408 instruction in MODE. */
4410 static void
4411 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
4413 rtx (*fn) (rtx, rtx) = NULL;
4414 if (mode == SImode)
4415 fn = gen_load_locked_si;
4416 else if (mode == DImode)
4417 fn = gen_load_locked_di;
4418 emit_insn (fn (reg, mem));
4421 /* A subroutine of the atomic operation splitters. Emit a store-conditional
4422 instruction in MODE. */
4424 static void
4425 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
4427 rtx (*fn) (rtx, rtx, rtx) = NULL;
4428 if (mode == SImode)
4429 fn = gen_store_conditional_si;
4430 else if (mode == DImode)
4431 fn = gen_store_conditional_di;
4432 emit_insn (fn (res, mem, val));
4435 /* A subroutine of the atomic operation splitters. Emit an insxl
4436 instruction in MODE. */
4438 static rtx
4439 emit_insxl (enum machine_mode mode, rtx op1, rtx op2)
4441 rtx ret = gen_reg_rtx (DImode);
4442 rtx (*fn) (rtx, rtx, rtx);
4444 if (WORDS_BIG_ENDIAN)
4446 if (mode == QImode)
4447 fn = gen_insbl_be;
4448 else
4449 fn = gen_inswl_be;
4451 else
4453 if (mode == QImode)
4454 fn = gen_insbl_le;
4455 else
4456 fn = gen_inswl_le;
4458 /* The insbl and inswl patterns require a register operand. */
4459 op1 = force_reg (mode, op1);
4460 emit_insn (fn (ret, op1, op2));
4462 return ret;
4465 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
4466 to perform. MEM is the memory on which to operate. VAL is the second
4467 operand of the binary operator. BEFORE and AFTER are optional locations to
4468 return the value of MEM either before of after the operation. SCRATCH is
4469 a scratch register. */
4471 void
4472 alpha_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
4473 rtx before, rtx after, rtx scratch)
4475 enum machine_mode mode = GET_MODE (mem);
4476 rtx label, x, cond = gen_rtx_REG (DImode, REGNO (scratch));
4478 emit_insn (gen_memory_barrier ());
4480 label = gen_label_rtx ();
4481 emit_label (label);
4482 label = gen_rtx_LABEL_REF (DImode, label);
4484 if (before == NULL)
4485 before = scratch;
4486 emit_load_locked (mode, before, mem);
4488 if (code == NOT)
4490 x = gen_rtx_AND (mode, before, val);
4491 emit_insn (gen_rtx_SET (VOIDmode, val, x));
4493 x = gen_rtx_NOT (mode, val);
4495 else
4496 x = gen_rtx_fmt_ee (code, mode, before, val);
4497 if (after)
4498 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
4499 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
4501 emit_store_conditional (mode, cond, mem, scratch);
4503 x = gen_rtx_EQ (DImode, cond, const0_rtx);
4504 emit_unlikely_jump (x, label);
4506 emit_insn (gen_memory_barrier ());
4509 /* Expand a compare and swap operation. */
4511 void
4512 alpha_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
4513 rtx scratch)
4515 enum machine_mode mode = GET_MODE (mem);
4516 rtx label1, label2, x, cond = gen_lowpart (DImode, scratch);
4518 emit_insn (gen_memory_barrier ());
4520 label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4521 label2 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4522 emit_label (XEXP (label1, 0));
4524 emit_load_locked (mode, retval, mem);
4526 x = gen_lowpart (DImode, retval);
4527 if (oldval == const0_rtx)
4528 x = gen_rtx_NE (DImode, x, const0_rtx);
4529 else
4531 x = gen_rtx_EQ (DImode, x, oldval);
4532 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
4533 x = gen_rtx_EQ (DImode, cond, const0_rtx);
4535 emit_unlikely_jump (x, label2);
4537 emit_move_insn (scratch, newval);
4538 emit_store_conditional (mode, cond, mem, scratch);
4540 x = gen_rtx_EQ (DImode, cond, const0_rtx);
4541 emit_unlikely_jump (x, label1);
4543 emit_insn (gen_memory_barrier ());
4544 emit_label (XEXP (label2, 0));
4547 void
4548 alpha_expand_compare_and_swap_12 (rtx dst, rtx mem, rtx oldval, rtx newval)
4550 enum machine_mode mode = GET_MODE (mem);
4551 rtx addr, align, wdst;
4552 rtx (*fn5) (rtx, rtx, rtx, rtx, rtx);
4554 addr = force_reg (DImode, XEXP (mem, 0));
4555 align = expand_simple_binop (Pmode, AND, addr, GEN_INT (-8),
4556 NULL_RTX, 1, OPTAB_DIRECT);
4558 oldval = convert_modes (DImode, mode, oldval, 1);
4559 newval = emit_insxl (mode, newval, addr);
4561 wdst = gen_reg_rtx (DImode);
4562 if (mode == QImode)
4563 fn5 = gen_sync_compare_and_swapqi_1;
4564 else
4565 fn5 = gen_sync_compare_and_swaphi_1;
4566 emit_insn (fn5 (wdst, addr, oldval, newval, align));
4568 emit_move_insn (dst, gen_lowpart (mode, wdst));
4571 void
4572 alpha_split_compare_and_swap_12 (enum machine_mode mode, rtx dest, rtx addr,
4573 rtx oldval, rtx newval, rtx align,
4574 rtx scratch, rtx cond)
4576 rtx label1, label2, mem, width, mask, x;
4578 mem = gen_rtx_MEM (DImode, align);
4579 MEM_VOLATILE_P (mem) = 1;
4581 emit_insn (gen_memory_barrier ());
4582 label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4583 label2 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4584 emit_label (XEXP (label1, 0));
4586 emit_load_locked (DImode, scratch, mem);
4588 width = GEN_INT (GET_MODE_BITSIZE (mode));
4589 mask = GEN_INT (mode == QImode ? 0xff : 0xffff);
4590 if (WORDS_BIG_ENDIAN)
4591 emit_insn (gen_extxl_be (dest, scratch, width, addr));
4592 else
4593 emit_insn (gen_extxl_le (dest, scratch, width, addr));
4595 if (oldval == const0_rtx)
4596 x = gen_rtx_NE (DImode, dest, const0_rtx);
4597 else
4599 x = gen_rtx_EQ (DImode, dest, oldval);
4600 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
4601 x = gen_rtx_EQ (DImode, cond, const0_rtx);
4603 emit_unlikely_jump (x, label2);
4605 if (WORDS_BIG_ENDIAN)
4606 emit_insn (gen_mskxl_be (scratch, scratch, mask, addr));
4607 else
4608 emit_insn (gen_mskxl_le (scratch, scratch, mask, addr));
4609 emit_insn (gen_iordi3 (scratch, scratch, newval));
4611 emit_store_conditional (DImode, scratch, mem, scratch);
4613 x = gen_rtx_EQ (DImode, scratch, const0_rtx);
4614 emit_unlikely_jump (x, label1);
4616 emit_insn (gen_memory_barrier ());
4617 emit_label (XEXP (label2, 0));
4620 /* Expand an atomic exchange operation. */
4622 void
4623 alpha_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
4625 enum machine_mode mode = GET_MODE (mem);
4626 rtx label, x, cond = gen_lowpart (DImode, scratch);
4628 label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4629 emit_label (XEXP (label, 0));
4631 emit_load_locked (mode, retval, mem);
4632 emit_move_insn (scratch, val);
4633 emit_store_conditional (mode, cond, mem, scratch);
4635 x = gen_rtx_EQ (DImode, cond, const0_rtx);
4636 emit_unlikely_jump (x, label);
4638 emit_insn (gen_memory_barrier ());
4641 void
4642 alpha_expand_lock_test_and_set_12 (rtx dst, rtx mem, rtx val)
4644 enum machine_mode mode = GET_MODE (mem);
4645 rtx addr, align, wdst;
4646 rtx (*fn4) (rtx, rtx, rtx, rtx);
4648 /* Force the address into a register. */
4649 addr = force_reg (DImode, XEXP (mem, 0));
4651 /* Align it to a multiple of 8. */
4652 align = expand_simple_binop (Pmode, AND, addr, GEN_INT (-8),
4653 NULL_RTX, 1, OPTAB_DIRECT);
4655 /* Insert val into the correct byte location within the word. */
4656 val = emit_insxl (mode, val, addr);
4658 wdst = gen_reg_rtx (DImode);
4659 if (mode == QImode)
4660 fn4 = gen_sync_lock_test_and_setqi_1;
4661 else
4662 fn4 = gen_sync_lock_test_and_sethi_1;
4663 emit_insn (fn4 (wdst, addr, val, align));
4665 emit_move_insn (dst, gen_lowpart (mode, wdst));
4668 void
4669 alpha_split_lock_test_and_set_12 (enum machine_mode mode, rtx dest, rtx addr,
4670 rtx val, rtx align, rtx scratch)
4672 rtx label, mem, width, mask, x;
4674 mem = gen_rtx_MEM (DImode, align);
4675 MEM_VOLATILE_P (mem) = 1;
4677 label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4678 emit_label (XEXP (label, 0));
4680 emit_load_locked (DImode, scratch, mem);
4682 width = GEN_INT (GET_MODE_BITSIZE (mode));
4683 mask = GEN_INT (mode == QImode ? 0xff : 0xffff);
4684 if (WORDS_BIG_ENDIAN)
4686 emit_insn (gen_extxl_be (dest, scratch, width, addr));
4687 emit_insn (gen_mskxl_be (scratch, scratch, mask, addr));
4689 else
4691 emit_insn (gen_extxl_le (dest, scratch, width, addr));
4692 emit_insn (gen_mskxl_le (scratch, scratch, mask, addr));
4694 emit_insn (gen_iordi3 (scratch, scratch, val));
4696 emit_store_conditional (DImode, scratch, mem, scratch);
4698 x = gen_rtx_EQ (DImode, scratch, const0_rtx);
4699 emit_unlikely_jump (x, label);
4701 emit_insn (gen_memory_barrier ());
4704 /* Adjust the cost of a scheduling dependency. Return the new cost of
4705 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
4707 static int
4708 alpha_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
4710 enum attr_type insn_type, dep_insn_type;
4712 /* If the dependence is an anti-dependence, there is no cost. For an
4713 output dependence, there is sometimes a cost, but it doesn't seem
4714 worth handling those few cases. */
4715 if (REG_NOTE_KIND (link) != 0)
4716 return cost;
4718 /* If we can't recognize the insns, we can't really do anything. */
4719 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
4720 return cost;
4722 insn_type = get_attr_type (insn);
4723 dep_insn_type = get_attr_type (dep_insn);
4725 /* Bring in the user-defined memory latency. */
4726 if (dep_insn_type == TYPE_ILD
4727 || dep_insn_type == TYPE_FLD
4728 || dep_insn_type == TYPE_LDSYM)
4729 cost += alpha_memory_latency-1;
4731 /* Everything else handled in DFA bypasses now. */
4733 return cost;
4736 /* The number of instructions that can be issued per cycle. */
4738 static int
4739 alpha_issue_rate (void)
4741 return (alpha_tune == PROCESSOR_EV4 ? 2 : 4);
4744 /* How many alternative schedules to try. This should be as wide as the
4745 scheduling freedom in the DFA, but no wider. Making this value too
4746 large results extra work for the scheduler.
4748 For EV4, loads can be issued to either IB0 or IB1, thus we have 2
4749 alternative schedules. For EV5, we can choose between E0/E1 and
4750 FA/FM. For EV6, an arithmetic insn can be issued to U0/U1/L0/L1. */
4752 static int
4753 alpha_multipass_dfa_lookahead (void)
4755 return (alpha_tune == PROCESSOR_EV6 ? 4 : 2);
4758 /* Machine-specific function data. */
4760 struct machine_function GTY(())
4762 /* For unicosmk. */
4763 /* List of call information words for calls from this function. */
4764 struct rtx_def *first_ciw;
4765 struct rtx_def *last_ciw;
4766 int ciw_count;
4768 /* List of deferred case vectors. */
4769 struct rtx_def *addr_list;
4771 /* For OSF. */
4772 const char *some_ld_name;
4774 /* For TARGET_LD_BUGGY_LDGP. */
4775 struct rtx_def *gp_save_rtx;
4778 /* How to allocate a 'struct machine_function'. */
4780 static struct machine_function *
4781 alpha_init_machine_status (void)
4783 return ((struct machine_function *)
4784 ggc_alloc_cleared (sizeof (struct machine_function)));
4787 /* Functions to save and restore alpha_return_addr_rtx. */
4789 /* Start the ball rolling with RETURN_ADDR_RTX. */
4792 alpha_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
4794 if (count != 0)
4795 return const0_rtx;
4797 return get_hard_reg_initial_val (Pmode, REG_RA);
4800 /* Return or create a memory slot containing the gp value for the current
4801 function. Needed only if TARGET_LD_BUGGY_LDGP. */
4804 alpha_gp_save_rtx (void)
4806 rtx seq, m = cfun->machine->gp_save_rtx;
4808 if (m == NULL)
4810 start_sequence ();
4812 m = assign_stack_local (DImode, UNITS_PER_WORD, BITS_PER_WORD);
4813 m = validize_mem (m);
4814 emit_move_insn (m, pic_offset_table_rtx);
4816 seq = get_insns ();
4817 end_sequence ();
4819 /* We used to simply emit the sequence after entry_of_function.
4820 However this breaks the CFG if the first instruction in the
4821 first block is not the NOTE_INSN_BASIC_BLOCK, for example a
4822 label. Emit the sequence properly on the edge. We are only
4823 invoked from dw2_build_landing_pads and finish_eh_generation
4824 will call commit_edge_insertions thanks to a kludge. */
4825 insert_insn_on_edge (seq, single_succ_edge (ENTRY_BLOCK_PTR));
4827 cfun->machine->gp_save_rtx = m;
4830 return m;
4833 static int
4834 alpha_ra_ever_killed (void)
4836 rtx top;
4838 if (!has_hard_reg_initial_val (Pmode, REG_RA))
4839 return (int)df_regs_ever_live_p (REG_RA);
4841 push_topmost_sequence ();
4842 top = get_insns ();
4843 pop_topmost_sequence ();
4845 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
4849 /* Return the trap mode suffix applicable to the current
4850 instruction, or NULL. */
4852 static const char *
4853 get_trap_mode_suffix (void)
4855 enum attr_trap_suffix s = get_attr_trap_suffix (current_output_insn);
4857 switch (s)
4859 case TRAP_SUFFIX_NONE:
4860 return NULL;
4862 case TRAP_SUFFIX_SU:
4863 if (alpha_fptm >= ALPHA_FPTM_SU)
4864 return "su";
4865 return NULL;
4867 case TRAP_SUFFIX_SUI:
4868 if (alpha_fptm >= ALPHA_FPTM_SUI)
4869 return "sui";
4870 return NULL;
4872 case TRAP_SUFFIX_V_SV:
4873 switch (alpha_fptm)
4875 case ALPHA_FPTM_N:
4876 return NULL;
4877 case ALPHA_FPTM_U:
4878 return "v";
4879 case ALPHA_FPTM_SU:
4880 case ALPHA_FPTM_SUI:
4881 return "sv";
4882 default:
4883 gcc_unreachable ();
4886 case TRAP_SUFFIX_V_SV_SVI:
4887 switch (alpha_fptm)
4889 case ALPHA_FPTM_N:
4890 return NULL;
4891 case ALPHA_FPTM_U:
4892 return "v";
4893 case ALPHA_FPTM_SU:
4894 return "sv";
4895 case ALPHA_FPTM_SUI:
4896 return "svi";
4897 default:
4898 gcc_unreachable ();
4900 break;
4902 case TRAP_SUFFIX_U_SU_SUI:
4903 switch (alpha_fptm)
4905 case ALPHA_FPTM_N:
4906 return NULL;
4907 case ALPHA_FPTM_U:
4908 return "u";
4909 case ALPHA_FPTM_SU:
4910 return "su";
4911 case ALPHA_FPTM_SUI:
4912 return "sui";
4913 default:
4914 gcc_unreachable ();
4916 break;
4918 default:
4919 gcc_unreachable ();
4921 gcc_unreachable ();
4924 /* Return the rounding mode suffix applicable to the current
4925 instruction, or NULL. */
4927 static const char *
4928 get_round_mode_suffix (void)
4930 enum attr_round_suffix s = get_attr_round_suffix (current_output_insn);
4932 switch (s)
4934 case ROUND_SUFFIX_NONE:
4935 return NULL;
4936 case ROUND_SUFFIX_NORMAL:
4937 switch (alpha_fprm)
4939 case ALPHA_FPRM_NORM:
4940 return NULL;
4941 case ALPHA_FPRM_MINF:
4942 return "m";
4943 case ALPHA_FPRM_CHOP:
4944 return "c";
4945 case ALPHA_FPRM_DYN:
4946 return "d";
4947 default:
4948 gcc_unreachable ();
4950 break;
4952 case ROUND_SUFFIX_C:
4953 return "c";
4955 default:
4956 gcc_unreachable ();
4958 gcc_unreachable ();
4961 /* Locate some local-dynamic symbol still in use by this function
4962 so that we can print its name in some movdi_er_tlsldm pattern. */
4964 static int
4965 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
4967 rtx x = *px;
4969 if (GET_CODE (x) == SYMBOL_REF
4970 && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
4972 cfun->machine->some_ld_name = XSTR (x, 0);
4973 return 1;
4976 return 0;
4979 static const char *
4980 get_some_local_dynamic_name (void)
4982 rtx insn;
4984 if (cfun->machine->some_ld_name)
4985 return cfun->machine->some_ld_name;
4987 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
4988 if (INSN_P (insn)
4989 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
4990 return cfun->machine->some_ld_name;
4992 gcc_unreachable ();
4995 /* Print an operand. Recognize special options, documented below. */
4997 void
4998 print_operand (FILE *file, rtx x, int code)
5000 int i;
5002 switch (code)
5004 case '~':
5005 /* Print the assembler name of the current function. */
5006 assemble_name (file, alpha_fnname);
5007 break;
5009 case '&':
5010 assemble_name (file, get_some_local_dynamic_name ());
5011 break;
5013 case '/':
5015 const char *trap = get_trap_mode_suffix ();
5016 const char *round = get_round_mode_suffix ();
5018 if (trap || round)
5019 fprintf (file, (TARGET_AS_SLASH_BEFORE_SUFFIX ? "/%s%s" : "%s%s"),
5020 (trap ? trap : ""), (round ? round : ""));
5021 break;
5024 case ',':
5025 /* Generates single precision instruction suffix. */
5026 fputc ((TARGET_FLOAT_VAX ? 'f' : 's'), file);
5027 break;
5029 case '-':
5030 /* Generates double precision instruction suffix. */
5031 fputc ((TARGET_FLOAT_VAX ? 'g' : 't'), file);
5032 break;
5034 case '#':
5035 if (alpha_this_literal_sequence_number == 0)
5036 alpha_this_literal_sequence_number = alpha_next_sequence_number++;
5037 fprintf (file, "%d", alpha_this_literal_sequence_number);
5038 break;
5040 case '*':
5041 if (alpha_this_gpdisp_sequence_number == 0)
5042 alpha_this_gpdisp_sequence_number = alpha_next_sequence_number++;
5043 fprintf (file, "%d", alpha_this_gpdisp_sequence_number);
5044 break;
5046 case 'H':
5047 if (GET_CODE (x) == HIGH)
5048 output_addr_const (file, XEXP (x, 0));
5049 else
5050 output_operand_lossage ("invalid %%H value");
5051 break;
5053 case 'J':
5055 const char *lituse;
5057 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD_CALL)
5059 x = XVECEXP (x, 0, 0);
5060 lituse = "lituse_tlsgd";
5062 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM_CALL)
5064 x = XVECEXP (x, 0, 0);
5065 lituse = "lituse_tlsldm";
5067 else if (GET_CODE (x) == CONST_INT)
5068 lituse = "lituse_jsr";
5069 else
5071 output_operand_lossage ("invalid %%J value");
5072 break;
5075 if (x != const0_rtx)
5076 fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x));
5078 break;
5080 case 'j':
5082 const char *lituse;
5084 #ifdef HAVE_AS_JSRDIRECT_RELOCS
5085 lituse = "lituse_jsrdirect";
5086 #else
5087 lituse = "lituse_jsr";
5088 #endif
5090 gcc_assert (INTVAL (x) != 0);
5091 fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x));
5093 break;
5094 case 'r':
5095 /* If this operand is the constant zero, write it as "$31". */
5096 if (GET_CODE (x) == REG)
5097 fprintf (file, "%s", reg_names[REGNO (x)]);
5098 else if (x == CONST0_RTX (GET_MODE (x)))
5099 fprintf (file, "$31");
5100 else
5101 output_operand_lossage ("invalid %%r value");
5102 break;
5104 case 'R':
5105 /* Similar, but for floating-point. */
5106 if (GET_CODE (x) == REG)
5107 fprintf (file, "%s", reg_names[REGNO (x)]);
5108 else if (x == CONST0_RTX (GET_MODE (x)))
5109 fprintf (file, "$f31");
5110 else
5111 output_operand_lossage ("invalid %%R value");
5112 break;
5114 case 'N':
5115 /* Write the 1's complement of a constant. */
5116 if (GET_CODE (x) != CONST_INT)
5117 output_operand_lossage ("invalid %%N value");
5119 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
5120 break;
5122 case 'P':
5123 /* Write 1 << C, for a constant C. */
5124 if (GET_CODE (x) != CONST_INT)
5125 output_operand_lossage ("invalid %%P value");
5127 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
5128 break;
5130 case 'h':
5131 /* Write the high-order 16 bits of a constant, sign-extended. */
5132 if (GET_CODE (x) != CONST_INT)
5133 output_operand_lossage ("invalid %%h value");
5135 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
5136 break;
5138 case 'L':
5139 /* Write the low-order 16 bits of a constant, sign-extended. */
5140 if (GET_CODE (x) != CONST_INT)
5141 output_operand_lossage ("invalid %%L value");
5143 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
5144 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
5145 break;
5147 case 'm':
5148 /* Write mask for ZAP insn. */
5149 if (GET_CODE (x) == CONST_DOUBLE)
5151 HOST_WIDE_INT mask = 0;
5152 HOST_WIDE_INT value;
5154 value = CONST_DOUBLE_LOW (x);
5155 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
5156 i++, value >>= 8)
5157 if (value & 0xff)
5158 mask |= (1 << i);
5160 value = CONST_DOUBLE_HIGH (x);
5161 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
5162 i++, value >>= 8)
5163 if (value & 0xff)
5164 mask |= (1 << (i + sizeof (int)));
5166 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
5169 else if (GET_CODE (x) == CONST_INT)
5171 HOST_WIDE_INT mask = 0, value = INTVAL (x);
5173 for (i = 0; i < 8; i++, value >>= 8)
5174 if (value & 0xff)
5175 mask |= (1 << i);
5177 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
5179 else
5180 output_operand_lossage ("invalid %%m value");
5181 break;
5183 case 'M':
5184 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
5185 if (GET_CODE (x) != CONST_INT
5186 || (INTVAL (x) != 8 && INTVAL (x) != 16
5187 && INTVAL (x) != 32 && INTVAL (x) != 64))
5188 output_operand_lossage ("invalid %%M value");
5190 fprintf (file, "%s",
5191 (INTVAL (x) == 8 ? "b"
5192 : INTVAL (x) == 16 ? "w"
5193 : INTVAL (x) == 32 ? "l"
5194 : "q"));
5195 break;
5197 case 'U':
5198 /* Similar, except do it from the mask. */
5199 if (GET_CODE (x) == CONST_INT)
5201 HOST_WIDE_INT value = INTVAL (x);
5203 if (value == 0xff)
5205 fputc ('b', file);
5206 break;
5208 if (value == 0xffff)
5210 fputc ('w', file);
5211 break;
5213 if (value == 0xffffffff)
5215 fputc ('l', file);
5216 break;
5218 if (value == -1)
5220 fputc ('q', file);
5221 break;
5224 else if (HOST_BITS_PER_WIDE_INT == 32
5225 && GET_CODE (x) == CONST_DOUBLE
5226 && CONST_DOUBLE_LOW (x) == 0xffffffff
5227 && CONST_DOUBLE_HIGH (x) == 0)
5229 fputc ('l', file);
5230 break;
5232 output_operand_lossage ("invalid %%U value");
5233 break;
5235 case 's':
5236 /* Write the constant value divided by 8 for little-endian mode or
5237 (56 - value) / 8 for big-endian mode. */
5239 if (GET_CODE (x) != CONST_INT
5240 || (unsigned HOST_WIDE_INT) INTVAL (x) >= (WORDS_BIG_ENDIAN
5241 ? 56
5242 : 64)
5243 || (INTVAL (x) & 7) != 0)
5244 output_operand_lossage ("invalid %%s value");
5246 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
5247 WORDS_BIG_ENDIAN
5248 ? (56 - INTVAL (x)) / 8
5249 : INTVAL (x) / 8);
5250 break;
5252 case 'S':
5253 /* Same, except compute (64 - c) / 8 */
5255 if (GET_CODE (x) != CONST_INT
5256 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
5257 && (INTVAL (x) & 7) != 8)
5258 output_operand_lossage ("invalid %%s value");
5260 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
5261 break;
5263 case 't':
5265 /* On Unicos/Mk systems: use a DEX expression if the symbol
5266 clashes with a register name. */
5267 int dex = unicosmk_need_dex (x);
5268 if (dex)
5269 fprintf (file, "DEX(%d)", dex);
5270 else
5271 output_addr_const (file, x);
5273 break;
5275 case 'C': case 'D': case 'c': case 'd':
5276 /* Write out comparison name. */
5278 enum rtx_code c = GET_CODE (x);
5280 if (!COMPARISON_P (x))
5281 output_operand_lossage ("invalid %%C value");
5283 else if (code == 'D')
5284 c = reverse_condition (c);
5285 else if (code == 'c')
5286 c = swap_condition (c);
5287 else if (code == 'd')
5288 c = swap_condition (reverse_condition (c));
5290 if (c == LEU)
5291 fprintf (file, "ule");
5292 else if (c == LTU)
5293 fprintf (file, "ult");
5294 else if (c == UNORDERED)
5295 fprintf (file, "un");
5296 else
5297 fprintf (file, "%s", GET_RTX_NAME (c));
5299 break;
5301 case 'E':
5302 /* Write the divide or modulus operator. */
5303 switch (GET_CODE (x))
5305 case DIV:
5306 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
5307 break;
5308 case UDIV:
5309 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
5310 break;
5311 case MOD:
5312 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
5313 break;
5314 case UMOD:
5315 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
5316 break;
5317 default:
5318 output_operand_lossage ("invalid %%E value");
5319 break;
5321 break;
5323 case 'A':
5324 /* Write "_u" for unaligned access. */
5325 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
5326 fprintf (file, "_u");
5327 break;
5329 case 0:
5330 if (GET_CODE (x) == REG)
5331 fprintf (file, "%s", reg_names[REGNO (x)]);
5332 else if (GET_CODE (x) == MEM)
5333 output_address (XEXP (x, 0));
5334 else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
5336 switch (XINT (XEXP (x, 0), 1))
5338 case UNSPEC_DTPREL:
5339 case UNSPEC_TPREL:
5340 output_addr_const (file, XVECEXP (XEXP (x, 0), 0, 0));
5341 break;
5342 default:
5343 output_operand_lossage ("unknown relocation unspec");
5344 break;
5347 else
5348 output_addr_const (file, x);
5349 break;
5351 default:
5352 output_operand_lossage ("invalid %%xn code");
5356 void
5357 print_operand_address (FILE *file, rtx addr)
5359 int basereg = 31;
5360 HOST_WIDE_INT offset = 0;
5362 if (GET_CODE (addr) == AND)
5363 addr = XEXP (addr, 0);
5365 if (GET_CODE (addr) == PLUS
5366 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5368 offset = INTVAL (XEXP (addr, 1));
5369 addr = XEXP (addr, 0);
5372 if (GET_CODE (addr) == LO_SUM)
5374 const char *reloc16, *reloclo;
5375 rtx op1 = XEXP (addr, 1);
5377 if (GET_CODE (op1) == CONST && GET_CODE (XEXP (op1, 0)) == UNSPEC)
5379 op1 = XEXP (op1, 0);
5380 switch (XINT (op1, 1))
5382 case UNSPEC_DTPREL:
5383 reloc16 = NULL;
5384 reloclo = (alpha_tls_size == 16 ? "dtprel" : "dtprello");
5385 break;
5386 case UNSPEC_TPREL:
5387 reloc16 = NULL;
5388 reloclo = (alpha_tls_size == 16 ? "tprel" : "tprello");
5389 break;
5390 default:
5391 output_operand_lossage ("unknown relocation unspec");
5392 return;
5395 output_addr_const (file, XVECEXP (op1, 0, 0));
5397 else
5399 reloc16 = "gprel";
5400 reloclo = "gprellow";
5401 output_addr_const (file, op1);
5404 if (offset)
5405 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
5407 addr = XEXP (addr, 0);
5408 switch (GET_CODE (addr))
5410 case REG:
5411 basereg = REGNO (addr);
5412 break;
5414 case SUBREG:
5415 basereg = subreg_regno (addr);
5416 break;
5418 default:
5419 gcc_unreachable ();
5422 fprintf (file, "($%d)\t\t!%s", basereg,
5423 (basereg == 29 ? reloc16 : reloclo));
5424 return;
5427 switch (GET_CODE (addr))
5429 case REG:
5430 basereg = REGNO (addr);
5431 break;
5433 case SUBREG:
5434 basereg = subreg_regno (addr);
5435 break;
5437 case CONST_INT:
5438 offset = INTVAL (addr);
5439 break;
5441 #if TARGET_ABI_OPEN_VMS
5442 case SYMBOL_REF:
5443 fprintf (file, "%s", XSTR (addr, 0));
5444 return;
5446 case CONST:
5447 gcc_assert (GET_CODE (XEXP (addr, 0)) == PLUS
5448 && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF);
5449 fprintf (file, "%s+" HOST_WIDE_INT_PRINT_DEC,
5450 XSTR (XEXP (XEXP (addr, 0), 0), 0),
5451 INTVAL (XEXP (XEXP (addr, 0), 1)));
5452 return;
5454 #endif
5455 default:
5456 gcc_unreachable ();
5459 fprintf (file, HOST_WIDE_INT_PRINT_DEC "($%d)", offset, basereg);
5462 /* Emit RTL insns to initialize the variable parts of a trampoline at
5463 TRAMP. FNADDR is an RTX for the address of the function's pure
5464 code. CXT is an RTX for the static chain value for the function.
5466 The three offset parameters are for the individual template's
5467 layout. A JMPOFS < 0 indicates that the trampoline does not
5468 contain instructions at all.
5470 We assume here that a function will be called many more times than
5471 its address is taken (e.g., it might be passed to qsort), so we
5472 take the trouble to initialize the "hint" field in the JMP insn.
5473 Note that the hint field is PC (new) + 4 * bits 13:0. */
5475 void
5476 alpha_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt,
5477 int fnofs, int cxtofs, int jmpofs)
5479 rtx addr;
5480 /* VMS really uses DImode pointers in memory at this point. */
5481 enum machine_mode mode = TARGET_ABI_OPEN_VMS ? Pmode : ptr_mode;
5483 #ifdef POINTERS_EXTEND_UNSIGNED
5484 fnaddr = convert_memory_address (mode, fnaddr);
5485 cxt = convert_memory_address (mode, cxt);
5486 #endif
5488 /* Store function address and CXT. */
5489 addr = memory_address (mode, plus_constant (tramp, fnofs));
5490 emit_move_insn (gen_rtx_MEM (mode, addr), fnaddr);
5491 addr = memory_address (mode, plus_constant (tramp, cxtofs));
5492 emit_move_insn (gen_rtx_MEM (mode, addr), cxt);
5494 #ifdef ENABLE_EXECUTE_STACK
5495 emit_library_call (init_one_libfunc ("__enable_execute_stack"),
5496 0, VOIDmode, 1, tramp, Pmode);
5497 #endif
5499 if (jmpofs >= 0)
5500 emit_insn (gen_imb ());
5503 /* Determine where to put an argument to a function.
5504 Value is zero to push the argument on the stack,
5505 or a hard register in which to store the argument.
5507 MODE is the argument's machine mode.
5508 TYPE is the data type of the argument (as a tree).
5509 This is null for libcalls where that information may
5510 not be available.
5511 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5512 the preceding args and about the function being called.
5513 NAMED is nonzero if this argument is a named parameter
5514 (otherwise it is an extra parameter matching an ellipsis).
5516 On Alpha the first 6 words of args are normally in registers
5517 and the rest are pushed. */
5520 function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode, tree type,
5521 int named ATTRIBUTE_UNUSED)
5523 int basereg;
5524 int num_args;
5526 /* Don't get confused and pass small structures in FP registers. */
5527 if (type && AGGREGATE_TYPE_P (type))
5528 basereg = 16;
5529 else
5531 #ifdef ENABLE_CHECKING
5532 /* With alpha_split_complex_arg, we shouldn't see any raw complex
5533 values here. */
5534 gcc_assert (!COMPLEX_MODE_P (mode));
5535 #endif
5537 /* Set up defaults for FP operands passed in FP registers, and
5538 integral operands passed in integer registers. */
5539 if (TARGET_FPREGS && GET_MODE_CLASS (mode) == MODE_FLOAT)
5540 basereg = 32 + 16;
5541 else
5542 basereg = 16;
5545 /* ??? Irritatingly, the definition of CUMULATIVE_ARGS is different for
5546 the three platforms, so we can't avoid conditional compilation. */
5547 #if TARGET_ABI_OPEN_VMS
5549 if (mode == VOIDmode)
5550 return alpha_arg_info_reg_val (cum);
5552 num_args = cum.num_args;
5553 if (num_args >= 6
5554 || targetm.calls.must_pass_in_stack (mode, type))
5555 return NULL_RTX;
5557 #elif TARGET_ABI_UNICOSMK
5559 int size;
5561 /* If this is the last argument, generate the call info word (CIW). */
5562 /* ??? We don't include the caller's line number in the CIW because
5563 I don't know how to determine it if debug infos are turned off. */
5564 if (mode == VOIDmode)
5566 int i;
5567 HOST_WIDE_INT lo;
5568 HOST_WIDE_INT hi;
5569 rtx ciw;
5571 lo = 0;
5573 for (i = 0; i < cum.num_reg_words && i < 5; i++)
5574 if (cum.reg_args_type[i])
5575 lo |= (1 << (7 - i));
5577 if (cum.num_reg_words == 6 && cum.reg_args_type[5])
5578 lo |= 7;
5579 else
5580 lo |= cum.num_reg_words;
5582 #if HOST_BITS_PER_WIDE_INT == 32
5583 hi = (cum.num_args << 20) | cum.num_arg_words;
5584 #else
5585 lo = lo | ((HOST_WIDE_INT) cum.num_args << 52)
5586 | ((HOST_WIDE_INT) cum.num_arg_words << 32);
5587 hi = 0;
5588 #endif
5589 ciw = immed_double_const (lo, hi, DImode);
5591 return gen_rtx_UNSPEC (DImode, gen_rtvec (1, ciw),
5592 UNSPEC_UMK_LOAD_CIW);
5595 size = ALPHA_ARG_SIZE (mode, type, named);
5596 num_args = cum.num_reg_words;
5597 if (cum.force_stack
5598 || cum.num_reg_words + size > 6
5599 || targetm.calls.must_pass_in_stack (mode, type))
5600 return NULL_RTX;
5601 else if (type && TYPE_MODE (type) == BLKmode)
5603 rtx reg1, reg2;
5605 reg1 = gen_rtx_REG (DImode, num_args + 16);
5606 reg1 = gen_rtx_EXPR_LIST (DImode, reg1, const0_rtx);
5608 /* The argument fits in two registers. Note that we still need to
5609 reserve a register for empty structures. */
5610 if (size == 0)
5611 return NULL_RTX;
5612 else if (size == 1)
5613 return gen_rtx_PARALLEL (mode, gen_rtvec (1, reg1));
5614 else
5616 reg2 = gen_rtx_REG (DImode, num_args + 17);
5617 reg2 = gen_rtx_EXPR_LIST (DImode, reg2, GEN_INT (8));
5618 return gen_rtx_PARALLEL (mode, gen_rtvec (2, reg1, reg2));
5622 #elif TARGET_ABI_OSF
5624 if (cum >= 6)
5625 return NULL_RTX;
5626 num_args = cum;
5628 /* VOID is passed as a special flag for "last argument". */
5629 if (type == void_type_node)
5630 basereg = 16;
5631 else if (targetm.calls.must_pass_in_stack (mode, type))
5632 return NULL_RTX;
5634 #else
5635 #error Unhandled ABI
5636 #endif
5638 return gen_rtx_REG (mode, num_args + basereg);
5641 static int
5642 alpha_arg_partial_bytes (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
5643 enum machine_mode mode ATTRIBUTE_UNUSED,
5644 tree type ATTRIBUTE_UNUSED,
5645 bool named ATTRIBUTE_UNUSED)
5647 int words = 0;
5649 #if TARGET_ABI_OPEN_VMS
5650 if (cum->num_args < 6
5651 && 6 < cum->num_args + ALPHA_ARG_SIZE (mode, type, named))
5652 words = 6 - cum->num_args;
5653 #elif TARGET_ABI_UNICOSMK
5654 /* Never any split arguments. */
5655 #elif TARGET_ABI_OSF
5656 if (*cum < 6 && 6 < *cum + ALPHA_ARG_SIZE (mode, type, named))
5657 words = 6 - *cum;
5658 #else
5659 #error Unhandled ABI
5660 #endif
5662 return words * UNITS_PER_WORD;
5666 /* Return true if TYPE must be returned in memory, instead of in registers. */
5668 static bool
5669 alpha_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
5671 enum machine_mode mode = VOIDmode;
5672 int size;
5674 if (type)
5676 mode = TYPE_MODE (type);
5678 /* All aggregates are returned in memory. */
5679 if (AGGREGATE_TYPE_P (type))
5680 return true;
5683 size = GET_MODE_SIZE (mode);
5684 switch (GET_MODE_CLASS (mode))
5686 case MODE_VECTOR_FLOAT:
5687 /* Pass all float vectors in memory, like an aggregate. */
5688 return true;
5690 case MODE_COMPLEX_FLOAT:
5691 /* We judge complex floats on the size of their element,
5692 not the size of the whole type. */
5693 size = GET_MODE_UNIT_SIZE (mode);
5694 break;
5696 case MODE_INT:
5697 case MODE_FLOAT:
5698 case MODE_COMPLEX_INT:
5699 case MODE_VECTOR_INT:
5700 break;
5702 default:
5703 /* ??? We get called on all sorts of random stuff from
5704 aggregate_value_p. We must return something, but it's not
5705 clear what's safe to return. Pretend it's a struct I
5706 guess. */
5707 return true;
5710 /* Otherwise types must fit in one register. */
5711 return size > UNITS_PER_WORD;
5714 /* Return true if TYPE should be passed by invisible reference. */
5716 static bool
5717 alpha_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
5718 enum machine_mode mode,
5719 const_tree type ATTRIBUTE_UNUSED,
5720 bool named ATTRIBUTE_UNUSED)
5722 return mode == TFmode || mode == TCmode;
5725 /* Define how to find the value returned by a function. VALTYPE is the
5726 data type of the value (as a tree). If the precise function being
5727 called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0.
5728 MODE is set instead of VALTYPE for libcalls.
5730 On Alpha the value is found in $0 for integer functions and
5731 $f0 for floating-point functions. */
5734 function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
5735 enum machine_mode mode)
5737 unsigned int regnum, dummy;
5738 enum mode_class mclass;
5740 gcc_assert (!valtype || !alpha_return_in_memory (valtype, func));
5742 if (valtype)
5743 mode = TYPE_MODE (valtype);
5745 mclass = GET_MODE_CLASS (mode);
5746 switch (mclass)
5748 case MODE_INT:
5749 PROMOTE_MODE (mode, dummy, valtype);
5750 /* FALLTHRU */
5752 case MODE_COMPLEX_INT:
5753 case MODE_VECTOR_INT:
5754 regnum = 0;
5755 break;
5757 case MODE_FLOAT:
5758 regnum = 32;
5759 break;
5761 case MODE_COMPLEX_FLOAT:
5763 enum machine_mode cmode = GET_MODE_INNER (mode);
5765 return gen_rtx_PARALLEL
5766 (VOIDmode,
5767 gen_rtvec (2,
5768 gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 32),
5769 const0_rtx),
5770 gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 33),
5771 GEN_INT (GET_MODE_SIZE (cmode)))));
5774 default:
5775 gcc_unreachable ();
5778 return gen_rtx_REG (mode, regnum);
5781 /* TCmode complex values are passed by invisible reference. We
5782 should not split these values. */
5784 static bool
5785 alpha_split_complex_arg (const_tree type)
5787 return TYPE_MODE (type) != TCmode;
5790 static tree
5791 alpha_build_builtin_va_list (void)
5793 tree base, ofs, space, record, type_decl;
5795 if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
5796 return ptr_type_node;
5798 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
5799 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
5800 TREE_CHAIN (record) = type_decl;
5801 TYPE_NAME (record) = type_decl;
5803 /* C++? SET_IS_AGGR_TYPE (record, 1); */
5805 /* Dummy field to prevent alignment warnings. */
5806 space = build_decl (FIELD_DECL, NULL_TREE, integer_type_node);
5807 DECL_FIELD_CONTEXT (space) = record;
5808 DECL_ARTIFICIAL (space) = 1;
5809 DECL_IGNORED_P (space) = 1;
5811 ofs = build_decl (FIELD_DECL, get_identifier ("__offset"),
5812 integer_type_node);
5813 DECL_FIELD_CONTEXT (ofs) = record;
5814 TREE_CHAIN (ofs) = space;
5816 base = build_decl (FIELD_DECL, get_identifier ("__base"),
5817 ptr_type_node);
5818 DECL_FIELD_CONTEXT (base) = record;
5819 TREE_CHAIN (base) = ofs;
5821 TYPE_FIELDS (record) = base;
5822 layout_type (record);
5824 va_list_gpr_counter_field = ofs;
5825 return record;
5828 #if TARGET_ABI_OSF
5829 /* Helper function for alpha_stdarg_optimize_hook. Skip over casts
5830 and constant additions. */
5832 static gimple
5833 va_list_skip_additions (tree lhs)
5835 gimple stmt;
5837 for (;;)
5839 enum tree_code code;
5841 stmt = SSA_NAME_DEF_STMT (lhs);
5843 if (gimple_code (stmt) == GIMPLE_PHI)
5844 return stmt;
5846 if (!is_gimple_assign (stmt)
5847 || gimple_assign_lhs (stmt) != lhs)
5848 return NULL;
5850 if (TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME)
5851 return stmt;
5852 code = gimple_assign_rhs_code (stmt);
5853 if (!CONVERT_EXPR_CODE_P (code)
5854 && ((code != PLUS_EXPR && code != POINTER_PLUS_EXPR)
5855 || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST
5856 || !host_integerp (gimple_assign_rhs2 (stmt), 1)))
5857 return stmt;
5859 lhs = gimple_assign_rhs1 (stmt);
5863 /* Check if LHS = RHS statement is
5864 LHS = *(ap.__base + ap.__offset + cst)
5866 LHS = *(ap.__base
5867 + ((ap.__offset + cst <= 47)
5868 ? ap.__offset + cst - 48 : ap.__offset + cst) + cst2).
5869 If the former, indicate that GPR registers are needed,
5870 if the latter, indicate that FPR registers are needed.
5872 Also look for LHS = (*ptr).field, where ptr is one of the forms
5873 listed above.
5875 On alpha, cfun->va_list_gpr_size is used as size of the needed
5876 regs and cfun->va_list_fpr_size is a bitmask, bit 0 set if GPR
5877 registers are needed and bit 1 set if FPR registers are needed.
5878 Return true if va_list references should not be scanned for the
5879 current statement. */
5881 static bool
5882 alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt)
5884 tree base, offset, rhs;
5885 int offset_arg = 1;
5886 gimple base_stmt;
5888 if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
5889 != GIMPLE_SINGLE_RHS)
5890 return false;
5892 rhs = gimple_assign_rhs1 (stmt);
5893 while (handled_component_p (rhs))
5894 rhs = TREE_OPERAND (rhs, 0);
5895 if (TREE_CODE (rhs) != INDIRECT_REF
5896 || TREE_CODE (TREE_OPERAND (rhs, 0)) != SSA_NAME)
5897 return false;
5899 stmt = va_list_skip_additions (TREE_OPERAND (rhs, 0));
5900 if (stmt == NULL
5901 || !is_gimple_assign (stmt)
5902 || gimple_assign_rhs_code (stmt) != POINTER_PLUS_EXPR)
5903 return false;
5905 base = gimple_assign_rhs1 (stmt);
5906 if (TREE_CODE (base) == SSA_NAME)
5908 base_stmt = va_list_skip_additions (base);
5909 if (base_stmt
5910 && is_gimple_assign (base_stmt)
5911 && gimple_assign_rhs_code (base_stmt) == COMPONENT_REF)
5912 base = gimple_assign_rhs1 (base_stmt);
5915 if (TREE_CODE (base) != COMPONENT_REF
5916 || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node))
5918 base = gimple_assign_rhs2 (stmt);
5919 if (TREE_CODE (base) == SSA_NAME)
5921 base_stmt = va_list_skip_additions (base);
5922 if (base_stmt
5923 && is_gimple_assign (base_stmt)
5924 && gimple_assign_rhs_code (base_stmt) == COMPONENT_REF)
5925 base = gimple_assign_rhs1 (base_stmt);
5928 if (TREE_CODE (base) != COMPONENT_REF
5929 || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node))
5930 return false;
5932 offset_arg = 0;
5935 base = get_base_address (base);
5936 if (TREE_CODE (base) != VAR_DECL
5937 || !bitmap_bit_p (si->va_list_vars, DECL_UID (base)))
5938 return false;
5940 offset = gimple_op (stmt, 1 + offset_arg);
5941 if (TREE_CODE (offset) == SSA_NAME)
5943 gimple offset_stmt = va_list_skip_additions (offset);
5945 if (offset_stmt
5946 && gimple_code (offset_stmt) == GIMPLE_PHI)
5948 HOST_WIDE_INT sub;
5949 gimple arg1_stmt, arg2_stmt;
5950 tree arg1, arg2;
5951 enum tree_code code1, code2;
5953 if (gimple_phi_num_args (offset_stmt) != 2)
5954 goto escapes;
5956 arg1_stmt
5957 = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 0));
5958 arg2_stmt
5959 = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 1));
5960 if (arg1_stmt == NULL
5961 || !is_gimple_assign (arg1_stmt)
5962 || arg2_stmt == NULL
5963 || !is_gimple_assign (arg2_stmt))
5964 goto escapes;
5966 code1 = gimple_assign_rhs_code (arg1_stmt);
5967 code2 = gimple_assign_rhs_code (arg2_stmt);
5968 if (code1 == COMPONENT_REF
5969 && (code2 == MINUS_EXPR || code2 == PLUS_EXPR))
5970 /* Do nothing. */;
5971 else if (code2 == COMPONENT_REF
5972 && (code1 == MINUS_EXPR || code1 == PLUS_EXPR))
5974 gimple tem = arg1_stmt;
5975 code2 = code1;
5976 arg1_stmt = arg2_stmt;
5977 arg2_stmt = tem;
5979 else
5980 goto escapes;
5982 if (!host_integerp (gimple_assign_rhs2 (arg2_stmt), 0))
5983 goto escapes;
5985 sub = tree_low_cst (gimple_assign_rhs2 (arg2_stmt), 0);
5986 if (code2 == MINUS_EXPR)
5987 sub = -sub;
5988 if (sub < -48 || sub > -32)
5989 goto escapes;
5991 arg1 = gimple_assign_rhs1 (arg1_stmt);
5992 arg2 = gimple_assign_rhs1 (arg2_stmt);
5993 if (TREE_CODE (arg2) == SSA_NAME)
5995 arg2_stmt = va_list_skip_additions (arg2);
5996 if (arg2_stmt == NULL
5997 || !is_gimple_assign (arg2_stmt)
5998 || gimple_assign_rhs_code (arg2_stmt) != COMPONENT_REF)
5999 goto escapes;
6000 arg2 = gimple_assign_rhs1 (arg2_stmt);
6002 if (arg1 != arg2)
6003 goto escapes;
6005 if (TREE_CODE (arg1) != COMPONENT_REF
6006 || TREE_OPERAND (arg1, 1) != va_list_gpr_counter_field
6007 || get_base_address (arg1) != base)
6008 goto escapes;
6010 /* Need floating point regs. */
6011 cfun->va_list_fpr_size |= 2;
6012 return false;
6014 if (offset_stmt
6015 && is_gimple_assign (offset_stmt)
6016 && gimple_assign_rhs_code (offset_stmt) == COMPONENT_REF)
6017 offset = gimple_assign_rhs1 (offset_stmt);
6019 if (TREE_CODE (offset) != COMPONENT_REF
6020 || TREE_OPERAND (offset, 1) != va_list_gpr_counter_field
6021 || get_base_address (offset) != base)
6022 goto escapes;
6023 else
6024 /* Need general regs. */
6025 cfun->va_list_fpr_size |= 1;
6026 return false;
6028 escapes:
6029 si->va_list_escapes = true;
6030 return false;
6032 #endif
6034 /* Perform any needed actions needed for a function that is receiving a
6035 variable number of arguments. */
6037 static void
6038 alpha_setup_incoming_varargs (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
6039 tree type, int *pretend_size, int no_rtl)
6041 CUMULATIVE_ARGS cum = *pcum;
6043 /* Skip the current argument. */
6044 FUNCTION_ARG_ADVANCE (cum, mode, type, 1);
6046 #if TARGET_ABI_UNICOSMK
6047 /* On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
6048 arguments on the stack. Unfortunately, it doesn't always store the first
6049 one (i.e. the one that arrives in $16 or $f16). This is not a problem
6050 with stdargs as we always have at least one named argument there. */
6051 if (cum.num_reg_words < 6)
6053 if (!no_rtl)
6055 emit_insn (gen_umk_mismatch_args (GEN_INT (cum.num_reg_words)));
6056 emit_insn (gen_arg_home_umk ());
6058 *pretend_size = 0;
6060 #elif TARGET_ABI_OPEN_VMS
6061 /* For VMS, we allocate space for all 6 arg registers plus a count.
6063 However, if NO registers need to be saved, don't allocate any space.
6064 This is not only because we won't need the space, but because AP
6065 includes the current_pretend_args_size and we don't want to mess up
6066 any ap-relative addresses already made. */
6067 if (cum.num_args < 6)
6069 if (!no_rtl)
6071 emit_move_insn (gen_rtx_REG (DImode, 1), virtual_incoming_args_rtx);
6072 emit_insn (gen_arg_home ());
6074 *pretend_size = 7 * UNITS_PER_WORD;
6076 #else
6077 /* On OSF/1 and friends, we allocate space for all 12 arg registers, but
6078 only push those that are remaining. However, if NO registers need to
6079 be saved, don't allocate any space. This is not only because we won't
6080 need the space, but because AP includes the current_pretend_args_size
6081 and we don't want to mess up any ap-relative addresses already made.
6083 If we are not to use the floating-point registers, save the integer
6084 registers where we would put the floating-point registers. This is
6085 not the most efficient way to implement varargs with just one register
6086 class, but it isn't worth doing anything more efficient in this rare
6087 case. */
6088 if (cum >= 6)
6089 return;
6091 if (!no_rtl)
6093 int count;
6094 alias_set_type set = get_varargs_alias_set ();
6095 rtx tmp;
6097 count = cfun->va_list_gpr_size / UNITS_PER_WORD;
6098 if (count > 6 - cum)
6099 count = 6 - cum;
6101 /* Detect whether integer registers or floating-point registers
6102 are needed by the detected va_arg statements. See above for
6103 how these values are computed. Note that the "escape" value
6104 is VA_LIST_MAX_FPR_SIZE, which is 255, which has both of
6105 these bits set. */
6106 gcc_assert ((VA_LIST_MAX_FPR_SIZE & 3) == 3);
6108 if (cfun->va_list_fpr_size & 1)
6110 tmp = gen_rtx_MEM (BLKmode,
6111 plus_constant (virtual_incoming_args_rtx,
6112 (cum + 6) * UNITS_PER_WORD));
6113 MEM_NOTRAP_P (tmp) = 1;
6114 set_mem_alias_set (tmp, set);
6115 move_block_from_reg (16 + cum, tmp, count);
6118 if (cfun->va_list_fpr_size & 2)
6120 tmp = gen_rtx_MEM (BLKmode,
6121 plus_constant (virtual_incoming_args_rtx,
6122 cum * UNITS_PER_WORD));
6123 MEM_NOTRAP_P (tmp) = 1;
6124 set_mem_alias_set (tmp, set);
6125 move_block_from_reg (16 + cum + TARGET_FPREGS*32, tmp, count);
6128 *pretend_size = 12 * UNITS_PER_WORD;
6129 #endif
6132 static void
6133 alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
6135 HOST_WIDE_INT offset;
6136 tree t, offset_field, base_field;
6138 if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
6139 return;
6141 if (TARGET_ABI_UNICOSMK)
6142 std_expand_builtin_va_start (valist, nextarg);
6144 /* For Unix, TARGET_SETUP_INCOMING_VARARGS moves the starting address base
6145 up by 48, storing fp arg registers in the first 48 bytes, and the
6146 integer arg registers in the next 48 bytes. This is only done,
6147 however, if any integer registers need to be stored.
6149 If no integer registers need be stored, then we must subtract 48
6150 in order to account for the integer arg registers which are counted
6151 in argsize above, but which are not actually stored on the stack.
6152 Must further be careful here about structures straddling the last
6153 integer argument register; that futzes with pretend_args_size,
6154 which changes the meaning of AP. */
6156 if (NUM_ARGS < 6)
6157 offset = TARGET_ABI_OPEN_VMS ? UNITS_PER_WORD : 6 * UNITS_PER_WORD;
6158 else
6159 offset = -6 * UNITS_PER_WORD + crtl->args.pretend_args_size;
6161 if (TARGET_ABI_OPEN_VMS)
6163 nextarg = plus_constant (nextarg, offset);
6164 nextarg = plus_constant (nextarg, NUM_ARGS * UNITS_PER_WORD);
6165 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
6166 make_tree (ptr_type_node, nextarg));
6167 TREE_SIDE_EFFECTS (t) = 1;
6169 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6171 else
6173 base_field = TYPE_FIELDS (TREE_TYPE (valist));
6174 offset_field = TREE_CHAIN (base_field);
6176 base_field = build3 (COMPONENT_REF, TREE_TYPE (base_field),
6177 valist, base_field, NULL_TREE);
6178 offset_field = build3 (COMPONENT_REF, TREE_TYPE (offset_field),
6179 valist, offset_field, NULL_TREE);
6181 t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
6182 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
6183 size_int (offset));
6184 t = build2 (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
6185 TREE_SIDE_EFFECTS (t) = 1;
6186 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6188 t = build_int_cst (NULL_TREE, NUM_ARGS * UNITS_PER_WORD);
6189 t = build2 (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
6190 TREE_SIDE_EFFECTS (t) = 1;
6191 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6195 static tree
6196 alpha_gimplify_va_arg_1 (tree type, tree base, tree offset,
6197 gimple_seq *pre_p)
6199 tree type_size, ptr_type, addend, t, addr;
6200 gimple_seq internal_post;
6202 /* If the type could not be passed in registers, skip the block
6203 reserved for the registers. */
6204 if (targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
6206 t = build_int_cst (TREE_TYPE (offset), 6*8);
6207 gimplify_assign (offset,
6208 build2 (MAX_EXPR, TREE_TYPE (offset), offset, t),
6209 pre_p);
6212 addend = offset;
6213 ptr_type = build_pointer_type (type);
6215 if (TREE_CODE (type) == COMPLEX_TYPE)
6217 tree real_part, imag_part, real_temp;
6219 real_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
6220 offset, pre_p);
6222 /* Copy the value into a new temporary, lest the formal temporary
6223 be reused out from under us. */
6224 real_temp = get_initialized_tmp_var (real_part, pre_p, NULL);
6226 imag_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
6227 offset, pre_p);
6229 return build2 (COMPLEX_EXPR, type, real_temp, imag_part);
6231 else if (TREE_CODE (type) == REAL_TYPE)
6233 tree fpaddend, cond, fourtyeight;
6235 fourtyeight = build_int_cst (TREE_TYPE (addend), 6*8);
6236 fpaddend = fold_build2 (MINUS_EXPR, TREE_TYPE (addend),
6237 addend, fourtyeight);
6238 cond = fold_build2 (LT_EXPR, boolean_type_node, addend, fourtyeight);
6239 addend = fold_build3 (COND_EXPR, TREE_TYPE (addend), cond,
6240 fpaddend, addend);
6243 /* Build the final address and force that value into a temporary. */
6244 addr = build2 (POINTER_PLUS_EXPR, ptr_type, fold_convert (ptr_type, base),
6245 fold_convert (sizetype, addend));
6246 internal_post = NULL;
6247 gimplify_expr (&addr, pre_p, &internal_post, is_gimple_val, fb_rvalue);
6248 gimple_seq_add_seq (pre_p, internal_post);
6250 /* Update the offset field. */
6251 type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type));
6252 if (type_size == NULL || TREE_OVERFLOW (type_size))
6253 t = size_zero_node;
6254 else
6256 t = size_binop (PLUS_EXPR, type_size, size_int (7));
6257 t = size_binop (TRUNC_DIV_EXPR, t, size_int (8));
6258 t = size_binop (MULT_EXPR, t, size_int (8));
6260 t = fold_convert (TREE_TYPE (offset), t);
6261 gimplify_assign (offset, build2 (PLUS_EXPR, TREE_TYPE (offset), offset, t),
6262 pre_p);
6264 return build_va_arg_indirect_ref (addr);
6267 static tree
6268 alpha_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
6269 gimple_seq *post_p)
6271 tree offset_field, base_field, offset, base, t, r;
6272 bool indirect;
6274 if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
6275 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
6277 base_field = TYPE_FIELDS (va_list_type_node);
6278 offset_field = TREE_CHAIN (base_field);
6279 base_field = build3 (COMPONENT_REF, TREE_TYPE (base_field),
6280 valist, base_field, NULL_TREE);
6281 offset_field = build3 (COMPONENT_REF, TREE_TYPE (offset_field),
6282 valist, offset_field, NULL_TREE);
6284 /* Pull the fields of the structure out into temporaries. Since we never
6285 modify the base field, we can use a formal temporary. Sign-extend the
6286 offset field so that it's the proper width for pointer arithmetic. */
6287 base = get_formal_tmp_var (base_field, pre_p);
6289 t = fold_convert (lang_hooks.types.type_for_size (64, 0), offset_field);
6290 offset = get_initialized_tmp_var (t, pre_p, NULL);
6292 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
6293 if (indirect)
6294 type = build_pointer_type (type);
6296 /* Find the value. Note that this will be a stable indirection, or
6297 a composite of stable indirections in the case of complex. */
6298 r = alpha_gimplify_va_arg_1 (type, base, offset, pre_p);
6300 /* Stuff the offset temporary back into its field. */
6301 gimplify_assign (unshare_expr (offset_field),
6302 fold_convert (TREE_TYPE (offset_field), offset), pre_p);
6304 if (indirect)
6305 r = build_va_arg_indirect_ref (r);
6307 return r;
6310 /* Builtins. */
6312 enum alpha_builtin
6314 ALPHA_BUILTIN_CMPBGE,
6315 ALPHA_BUILTIN_EXTBL,
6316 ALPHA_BUILTIN_EXTWL,
6317 ALPHA_BUILTIN_EXTLL,
6318 ALPHA_BUILTIN_EXTQL,
6319 ALPHA_BUILTIN_EXTWH,
6320 ALPHA_BUILTIN_EXTLH,
6321 ALPHA_BUILTIN_EXTQH,
6322 ALPHA_BUILTIN_INSBL,
6323 ALPHA_BUILTIN_INSWL,
6324 ALPHA_BUILTIN_INSLL,
6325 ALPHA_BUILTIN_INSQL,
6326 ALPHA_BUILTIN_INSWH,
6327 ALPHA_BUILTIN_INSLH,
6328 ALPHA_BUILTIN_INSQH,
6329 ALPHA_BUILTIN_MSKBL,
6330 ALPHA_BUILTIN_MSKWL,
6331 ALPHA_BUILTIN_MSKLL,
6332 ALPHA_BUILTIN_MSKQL,
6333 ALPHA_BUILTIN_MSKWH,
6334 ALPHA_BUILTIN_MSKLH,
6335 ALPHA_BUILTIN_MSKQH,
6336 ALPHA_BUILTIN_UMULH,
6337 ALPHA_BUILTIN_ZAP,
6338 ALPHA_BUILTIN_ZAPNOT,
6339 ALPHA_BUILTIN_AMASK,
6340 ALPHA_BUILTIN_IMPLVER,
6341 ALPHA_BUILTIN_RPCC,
6342 ALPHA_BUILTIN_THREAD_POINTER,
6343 ALPHA_BUILTIN_SET_THREAD_POINTER,
6345 /* TARGET_MAX */
6346 ALPHA_BUILTIN_MINUB8,
6347 ALPHA_BUILTIN_MINSB8,
6348 ALPHA_BUILTIN_MINUW4,
6349 ALPHA_BUILTIN_MINSW4,
6350 ALPHA_BUILTIN_MAXUB8,
6351 ALPHA_BUILTIN_MAXSB8,
6352 ALPHA_BUILTIN_MAXUW4,
6353 ALPHA_BUILTIN_MAXSW4,
6354 ALPHA_BUILTIN_PERR,
6355 ALPHA_BUILTIN_PKLB,
6356 ALPHA_BUILTIN_PKWB,
6357 ALPHA_BUILTIN_UNPKBL,
6358 ALPHA_BUILTIN_UNPKBW,
6360 /* TARGET_CIX */
6361 ALPHA_BUILTIN_CTTZ,
6362 ALPHA_BUILTIN_CTLZ,
6363 ALPHA_BUILTIN_CTPOP,
6365 ALPHA_BUILTIN_max
6368 static unsigned int const code_for_builtin[ALPHA_BUILTIN_max] = {
6369 CODE_FOR_builtin_cmpbge,
6370 CODE_FOR_builtin_extbl,
6371 CODE_FOR_builtin_extwl,
6372 CODE_FOR_builtin_extll,
6373 CODE_FOR_builtin_extql,
6374 CODE_FOR_builtin_extwh,
6375 CODE_FOR_builtin_extlh,
6376 CODE_FOR_builtin_extqh,
6377 CODE_FOR_builtin_insbl,
6378 CODE_FOR_builtin_inswl,
6379 CODE_FOR_builtin_insll,
6380 CODE_FOR_builtin_insql,
6381 CODE_FOR_builtin_inswh,
6382 CODE_FOR_builtin_inslh,
6383 CODE_FOR_builtin_insqh,
6384 CODE_FOR_builtin_mskbl,
6385 CODE_FOR_builtin_mskwl,
6386 CODE_FOR_builtin_mskll,
6387 CODE_FOR_builtin_mskql,
6388 CODE_FOR_builtin_mskwh,
6389 CODE_FOR_builtin_msklh,
6390 CODE_FOR_builtin_mskqh,
6391 CODE_FOR_umuldi3_highpart,
6392 CODE_FOR_builtin_zap,
6393 CODE_FOR_builtin_zapnot,
6394 CODE_FOR_builtin_amask,
6395 CODE_FOR_builtin_implver,
6396 CODE_FOR_builtin_rpcc,
6397 CODE_FOR_load_tp,
6398 CODE_FOR_set_tp,
6400 /* TARGET_MAX */
6401 CODE_FOR_builtin_minub8,
6402 CODE_FOR_builtin_minsb8,
6403 CODE_FOR_builtin_minuw4,
6404 CODE_FOR_builtin_minsw4,
6405 CODE_FOR_builtin_maxub8,
6406 CODE_FOR_builtin_maxsb8,
6407 CODE_FOR_builtin_maxuw4,
6408 CODE_FOR_builtin_maxsw4,
6409 CODE_FOR_builtin_perr,
6410 CODE_FOR_builtin_pklb,
6411 CODE_FOR_builtin_pkwb,
6412 CODE_FOR_builtin_unpkbl,
6413 CODE_FOR_builtin_unpkbw,
6415 /* TARGET_CIX */
6416 CODE_FOR_ctzdi2,
6417 CODE_FOR_clzdi2,
6418 CODE_FOR_popcountdi2
6421 struct alpha_builtin_def
6423 const char *name;
6424 enum alpha_builtin code;
6425 unsigned int target_mask;
6426 bool is_const;
6429 static struct alpha_builtin_def const zero_arg_builtins[] = {
6430 { "__builtin_alpha_implver", ALPHA_BUILTIN_IMPLVER, 0, true },
6431 { "__builtin_alpha_rpcc", ALPHA_BUILTIN_RPCC, 0, false }
6434 static struct alpha_builtin_def const one_arg_builtins[] = {
6435 { "__builtin_alpha_amask", ALPHA_BUILTIN_AMASK, 0, true },
6436 { "__builtin_alpha_pklb", ALPHA_BUILTIN_PKLB, MASK_MAX, true },
6437 { "__builtin_alpha_pkwb", ALPHA_BUILTIN_PKWB, MASK_MAX, true },
6438 { "__builtin_alpha_unpkbl", ALPHA_BUILTIN_UNPKBL, MASK_MAX, true },
6439 { "__builtin_alpha_unpkbw", ALPHA_BUILTIN_UNPKBW, MASK_MAX, true },
6440 { "__builtin_alpha_cttz", ALPHA_BUILTIN_CTTZ, MASK_CIX, true },
6441 { "__builtin_alpha_ctlz", ALPHA_BUILTIN_CTLZ, MASK_CIX, true },
6442 { "__builtin_alpha_ctpop", ALPHA_BUILTIN_CTPOP, MASK_CIX, true }
6445 static struct alpha_builtin_def const two_arg_builtins[] = {
6446 { "__builtin_alpha_cmpbge", ALPHA_BUILTIN_CMPBGE, 0, true },
6447 { "__builtin_alpha_extbl", ALPHA_BUILTIN_EXTBL, 0, true },
6448 { "__builtin_alpha_extwl", ALPHA_BUILTIN_EXTWL, 0, true },
6449 { "__builtin_alpha_extll", ALPHA_BUILTIN_EXTLL, 0, true },
6450 { "__builtin_alpha_extql", ALPHA_BUILTIN_EXTQL, 0, true },
6451 { "__builtin_alpha_extwh", ALPHA_BUILTIN_EXTWH, 0, true },
6452 { "__builtin_alpha_extlh", ALPHA_BUILTIN_EXTLH, 0, true },
6453 { "__builtin_alpha_extqh", ALPHA_BUILTIN_EXTQH, 0, true },
6454 { "__builtin_alpha_insbl", ALPHA_BUILTIN_INSBL, 0, true },
6455 { "__builtin_alpha_inswl", ALPHA_BUILTIN_INSWL, 0, true },
6456 { "__builtin_alpha_insll", ALPHA_BUILTIN_INSLL, 0, true },
6457 { "__builtin_alpha_insql", ALPHA_BUILTIN_INSQL, 0, true },
6458 { "__builtin_alpha_inswh", ALPHA_BUILTIN_INSWH, 0, true },
6459 { "__builtin_alpha_inslh", ALPHA_BUILTIN_INSLH, 0, true },
6460 { "__builtin_alpha_insqh", ALPHA_BUILTIN_INSQH, 0, true },
6461 { "__builtin_alpha_mskbl", ALPHA_BUILTIN_MSKBL, 0, true },
6462 { "__builtin_alpha_mskwl", ALPHA_BUILTIN_MSKWL, 0, true },
6463 { "__builtin_alpha_mskll", ALPHA_BUILTIN_MSKLL, 0, true },
6464 { "__builtin_alpha_mskql", ALPHA_BUILTIN_MSKQL, 0, true },
6465 { "__builtin_alpha_mskwh", ALPHA_BUILTIN_MSKWH, 0, true },
6466 { "__builtin_alpha_msklh", ALPHA_BUILTIN_MSKLH, 0, true },
6467 { "__builtin_alpha_mskqh", ALPHA_BUILTIN_MSKQH, 0, true },
6468 { "__builtin_alpha_umulh", ALPHA_BUILTIN_UMULH, 0, true },
6469 { "__builtin_alpha_zap", ALPHA_BUILTIN_ZAP, 0, true },
6470 { "__builtin_alpha_zapnot", ALPHA_BUILTIN_ZAPNOT, 0, true },
6471 { "__builtin_alpha_minub8", ALPHA_BUILTIN_MINUB8, MASK_MAX, true },
6472 { "__builtin_alpha_minsb8", ALPHA_BUILTIN_MINSB8, MASK_MAX, true },
6473 { "__builtin_alpha_minuw4", ALPHA_BUILTIN_MINUW4, MASK_MAX, true },
6474 { "__builtin_alpha_minsw4", ALPHA_BUILTIN_MINSW4, MASK_MAX, true },
6475 { "__builtin_alpha_maxub8", ALPHA_BUILTIN_MAXUB8, MASK_MAX, true },
6476 { "__builtin_alpha_maxsb8", ALPHA_BUILTIN_MAXSB8, MASK_MAX, true },
6477 { "__builtin_alpha_maxuw4", ALPHA_BUILTIN_MAXUW4, MASK_MAX, true },
6478 { "__builtin_alpha_maxsw4", ALPHA_BUILTIN_MAXSW4, MASK_MAX, true },
6479 { "__builtin_alpha_perr", ALPHA_BUILTIN_PERR, MASK_MAX, true }
6482 static GTY(()) tree alpha_v8qi_u;
6483 static GTY(()) tree alpha_v8qi_s;
6484 static GTY(()) tree alpha_v4hi_u;
6485 static GTY(()) tree alpha_v4hi_s;
6487 /* Helper function of alpha_init_builtins. Add the COUNT built-in
6488 functions pointed to by P, with function type FTYPE. */
6490 static void
6491 alpha_add_builtins (const struct alpha_builtin_def *p, size_t count,
6492 tree ftype)
6494 tree decl;
6495 size_t i;
6497 for (i = 0; i < count; ++i, ++p)
6498 if ((target_flags & p->target_mask) == p->target_mask)
6500 decl = add_builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
6501 NULL, NULL);
6502 if (p->is_const)
6503 TREE_READONLY (decl) = 1;
6504 TREE_NOTHROW (decl) = 1;
6509 static void
6510 alpha_init_builtins (void)
6512 tree dimode_integer_type_node;
6513 tree ftype, decl;
6515 dimode_integer_type_node = lang_hooks.types.type_for_mode (DImode, 0);
6517 ftype = build_function_type (dimode_integer_type_node, void_list_node);
6518 alpha_add_builtins (zero_arg_builtins, ARRAY_SIZE (zero_arg_builtins),
6519 ftype);
6521 ftype = build_function_type_list (dimode_integer_type_node,
6522 dimode_integer_type_node, NULL_TREE);
6523 alpha_add_builtins (one_arg_builtins, ARRAY_SIZE (one_arg_builtins),
6524 ftype);
6526 ftype = build_function_type_list (dimode_integer_type_node,
6527 dimode_integer_type_node,
6528 dimode_integer_type_node, NULL_TREE);
6529 alpha_add_builtins (two_arg_builtins, ARRAY_SIZE (two_arg_builtins),
6530 ftype);
6532 ftype = build_function_type (ptr_type_node, void_list_node);
6533 decl = add_builtin_function ("__builtin_thread_pointer", ftype,
6534 ALPHA_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
6535 NULL, NULL);
6536 TREE_NOTHROW (decl) = 1;
6538 ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
6539 decl = add_builtin_function ("__builtin_set_thread_pointer", ftype,
6540 ALPHA_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
6541 NULL, NULL);
6542 TREE_NOTHROW (decl) = 1;
6544 alpha_v8qi_u = build_vector_type (unsigned_intQI_type_node, 8);
6545 alpha_v8qi_s = build_vector_type (intQI_type_node, 8);
6546 alpha_v4hi_u = build_vector_type (unsigned_intHI_type_node, 4);
6547 alpha_v4hi_s = build_vector_type (intHI_type_node, 4);
6550 /* Expand an expression EXP that calls a built-in function,
6551 with result going to TARGET if that's convenient
6552 (and in mode MODE if that's convenient).
6553 SUBTARGET may be used as the target for computing one of EXP's operands.
6554 IGNORE is nonzero if the value is to be ignored. */
6556 static rtx
6557 alpha_expand_builtin (tree exp, rtx target,
6558 rtx subtarget ATTRIBUTE_UNUSED,
6559 enum machine_mode mode ATTRIBUTE_UNUSED,
6560 int ignore ATTRIBUTE_UNUSED)
6562 #define MAX_ARGS 2
6564 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
6565 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
6566 tree arg;
6567 call_expr_arg_iterator iter;
6568 enum insn_code icode;
6569 rtx op[MAX_ARGS], pat;
6570 int arity;
6571 bool nonvoid;
6573 if (fcode >= ALPHA_BUILTIN_max)
6574 internal_error ("bad builtin fcode");
6575 icode = code_for_builtin[fcode];
6576 if (icode == 0)
6577 internal_error ("bad builtin fcode");
6579 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
6581 arity = 0;
6582 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6584 const struct insn_operand_data *insn_op;
6586 if (arg == error_mark_node)
6587 return NULL_RTX;
6588 if (arity > MAX_ARGS)
6589 return NULL_RTX;
6591 insn_op = &insn_data[icode].operand[arity + nonvoid];
6593 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
6595 if (!(*insn_op->predicate) (op[arity], insn_op->mode))
6596 op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
6597 arity++;
6600 if (nonvoid)
6602 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6603 if (!target
6604 || GET_MODE (target) != tmode
6605 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
6606 target = gen_reg_rtx (tmode);
6609 switch (arity)
6611 case 0:
6612 pat = GEN_FCN (icode) (target);
6613 break;
6614 case 1:
6615 if (nonvoid)
6616 pat = GEN_FCN (icode) (target, op[0]);
6617 else
6618 pat = GEN_FCN (icode) (op[0]);
6619 break;
6620 case 2:
6621 pat = GEN_FCN (icode) (target, op[0], op[1]);
6622 break;
6623 default:
6624 gcc_unreachable ();
6626 if (!pat)
6627 return NULL_RTX;
6628 emit_insn (pat);
6630 if (nonvoid)
6631 return target;
6632 else
6633 return const0_rtx;
6637 /* Several bits below assume HWI >= 64 bits. This should be enforced
6638 by config.gcc. */
6639 #if HOST_BITS_PER_WIDE_INT < 64
6640 # error "HOST_WIDE_INT too small"
6641 #endif
6643 /* Fold the builtin for the CMPBGE instruction. This is a vector comparison
6644 with an 8-bit output vector. OPINT contains the integer operands; bit N
6645 of OP_CONST is set if OPINT[N] is valid. */
6647 static tree
6648 alpha_fold_builtin_cmpbge (unsigned HOST_WIDE_INT opint[], long op_const)
6650 if (op_const == 3)
6652 int i, val;
6653 for (i = 0, val = 0; i < 8; ++i)
6655 unsigned HOST_WIDE_INT c0 = (opint[0] >> (i * 8)) & 0xff;
6656 unsigned HOST_WIDE_INT c1 = (opint[1] >> (i * 8)) & 0xff;
6657 if (c0 >= c1)
6658 val |= 1 << i;
6660 return build_int_cst (long_integer_type_node, val);
6662 else if (op_const == 2 && opint[1] == 0)
6663 return build_int_cst (long_integer_type_node, 0xff);
6664 return NULL;
6667 /* Fold the builtin for the ZAPNOT instruction. This is essentially a
6668 specialized form of an AND operation. Other byte manipulation instructions
6669 are defined in terms of this instruction, so this is also used as a
6670 subroutine for other builtins.
6672 OP contains the tree operands; OPINT contains the extracted integer values.
6673 Bit N of OP_CONST it set if OPINT[N] is valid. OP may be null if only
6674 OPINT may be considered. */
6676 static tree
6677 alpha_fold_builtin_zapnot (tree *op, unsigned HOST_WIDE_INT opint[],
6678 long op_const)
6680 if (op_const & 2)
6682 unsigned HOST_WIDE_INT mask = 0;
6683 int i;
6685 for (i = 0; i < 8; ++i)
6686 if ((opint[1] >> i) & 1)
6687 mask |= (unsigned HOST_WIDE_INT)0xff << (i * 8);
6689 if (op_const & 1)
6690 return build_int_cst (long_integer_type_node, opint[0] & mask);
6692 if (op)
6693 return fold_build2 (BIT_AND_EXPR, long_integer_type_node, op[0],
6694 build_int_cst (long_integer_type_node, mask));
6696 else if ((op_const & 1) && opint[0] == 0)
6697 return build_int_cst (long_integer_type_node, 0);
6698 return NULL;
6701 /* Fold the builtins for the EXT family of instructions. */
6703 static tree
6704 alpha_fold_builtin_extxx (tree op[], unsigned HOST_WIDE_INT opint[],
6705 long op_const, unsigned HOST_WIDE_INT bytemask,
6706 bool is_high)
6708 long zap_const = 2;
6709 tree *zap_op = NULL;
6711 if (op_const & 2)
6713 unsigned HOST_WIDE_INT loc;
6715 loc = opint[1] & 7;
6716 if (BYTES_BIG_ENDIAN)
6717 loc ^= 7;
6718 loc *= 8;
6720 if (loc != 0)
6722 if (op_const & 1)
6724 unsigned HOST_WIDE_INT temp = opint[0];
6725 if (is_high)
6726 temp <<= loc;
6727 else
6728 temp >>= loc;
6729 opint[0] = temp;
6730 zap_const = 3;
6733 else
6734 zap_op = op;
6737 opint[1] = bytemask;
6738 return alpha_fold_builtin_zapnot (zap_op, opint, zap_const);
6741 /* Fold the builtins for the INS family of instructions. */
6743 static tree
6744 alpha_fold_builtin_insxx (tree op[], unsigned HOST_WIDE_INT opint[],
6745 long op_const, unsigned HOST_WIDE_INT bytemask,
6746 bool is_high)
6748 if ((op_const & 1) && opint[0] == 0)
6749 return build_int_cst (long_integer_type_node, 0);
6751 if (op_const & 2)
6753 unsigned HOST_WIDE_INT temp, loc, byteloc;
6754 tree *zap_op = NULL;
6756 loc = opint[1] & 7;
6757 if (BYTES_BIG_ENDIAN)
6758 loc ^= 7;
6759 bytemask <<= loc;
6761 temp = opint[0];
6762 if (is_high)
6764 byteloc = (64 - (loc * 8)) & 0x3f;
6765 if (byteloc == 0)
6766 zap_op = op;
6767 else
6768 temp >>= byteloc;
6769 bytemask >>= 8;
6771 else
6773 byteloc = loc * 8;
6774 if (byteloc == 0)
6775 zap_op = op;
6776 else
6777 temp <<= byteloc;
6780 opint[0] = temp;
6781 opint[1] = bytemask;
6782 return alpha_fold_builtin_zapnot (zap_op, opint, op_const);
6785 return NULL;
6788 static tree
6789 alpha_fold_builtin_mskxx (tree op[], unsigned HOST_WIDE_INT opint[],
6790 long op_const, unsigned HOST_WIDE_INT bytemask,
6791 bool is_high)
6793 if (op_const & 2)
6795 unsigned HOST_WIDE_INT loc;
6797 loc = opint[1] & 7;
6798 if (BYTES_BIG_ENDIAN)
6799 loc ^= 7;
6800 bytemask <<= loc;
6802 if (is_high)
6803 bytemask >>= 8;
6805 opint[1] = bytemask ^ 0xff;
6808 return alpha_fold_builtin_zapnot (op, opint, op_const);
6811 static tree
6812 alpha_fold_builtin_umulh (unsigned HOST_WIDE_INT opint[], long op_const)
6814 switch (op_const)
6816 case 3:
6818 unsigned HOST_WIDE_INT l;
6819 HOST_WIDE_INT h;
6821 mul_double (opint[0], 0, opint[1], 0, &l, &h);
6823 #if HOST_BITS_PER_WIDE_INT > 64
6824 # error fixme
6825 #endif
6827 return build_int_cst (long_integer_type_node, h);
6830 case 1:
6831 opint[1] = opint[0];
6832 /* FALLTHRU */
6833 case 2:
6834 /* Note that (X*1) >> 64 == 0. */
6835 if (opint[1] == 0 || opint[1] == 1)
6836 return build_int_cst (long_integer_type_node, 0);
6837 break;
6839 return NULL;
6842 static tree
6843 alpha_fold_vector_minmax (enum tree_code code, tree op[], tree vtype)
6845 tree op0 = fold_convert (vtype, op[0]);
6846 tree op1 = fold_convert (vtype, op[1]);
6847 tree val = fold_build2 (code, vtype, op0, op1);
6848 return fold_build1 (VIEW_CONVERT_EXPR, long_integer_type_node, val);
6851 static tree
6852 alpha_fold_builtin_perr (unsigned HOST_WIDE_INT opint[], long op_const)
6854 unsigned HOST_WIDE_INT temp = 0;
6855 int i;
6857 if (op_const != 3)
6858 return NULL;
6860 for (i = 0; i < 8; ++i)
6862 unsigned HOST_WIDE_INT a = (opint[0] >> (i * 8)) & 0xff;
6863 unsigned HOST_WIDE_INT b = (opint[1] >> (i * 8)) & 0xff;
6864 if (a >= b)
6865 temp += a - b;
6866 else
6867 temp += b - a;
6870 return build_int_cst (long_integer_type_node, temp);
6873 static tree
6874 alpha_fold_builtin_pklb (unsigned HOST_WIDE_INT opint[], long op_const)
6876 unsigned HOST_WIDE_INT temp;
6878 if (op_const == 0)
6879 return NULL;
6881 temp = opint[0] & 0xff;
6882 temp |= (opint[0] >> 24) & 0xff00;
6884 return build_int_cst (long_integer_type_node, temp);
6887 static tree
6888 alpha_fold_builtin_pkwb (unsigned HOST_WIDE_INT opint[], long op_const)
6890 unsigned HOST_WIDE_INT temp;
6892 if (op_const == 0)
6893 return NULL;
6895 temp = opint[0] & 0xff;
6896 temp |= (opint[0] >> 8) & 0xff00;
6897 temp |= (opint[0] >> 16) & 0xff0000;
6898 temp |= (opint[0] >> 24) & 0xff000000;
6900 return build_int_cst (long_integer_type_node, temp);
6903 static tree
6904 alpha_fold_builtin_unpkbl (unsigned HOST_WIDE_INT opint[], long op_const)
6906 unsigned HOST_WIDE_INT temp;
6908 if (op_const == 0)
6909 return NULL;
6911 temp = opint[0] & 0xff;
6912 temp |= (opint[0] & 0xff00) << 24;
6914 return build_int_cst (long_integer_type_node, temp);
6917 static tree
6918 alpha_fold_builtin_unpkbw (unsigned HOST_WIDE_INT opint[], long op_const)
6920 unsigned HOST_WIDE_INT temp;
6922 if (op_const == 0)
6923 return NULL;
6925 temp = opint[0] & 0xff;
6926 temp |= (opint[0] & 0x0000ff00) << 8;
6927 temp |= (opint[0] & 0x00ff0000) << 16;
6928 temp |= (opint[0] & 0xff000000) << 24;
6930 return build_int_cst (long_integer_type_node, temp);
6933 static tree
6934 alpha_fold_builtin_cttz (unsigned HOST_WIDE_INT opint[], long op_const)
6936 unsigned HOST_WIDE_INT temp;
6938 if (op_const == 0)
6939 return NULL;
6941 if (opint[0] == 0)
6942 temp = 64;
6943 else
6944 temp = exact_log2 (opint[0] & -opint[0]);
6946 return build_int_cst (long_integer_type_node, temp);
6949 static tree
6950 alpha_fold_builtin_ctlz (unsigned HOST_WIDE_INT opint[], long op_const)
6952 unsigned HOST_WIDE_INT temp;
6954 if (op_const == 0)
6955 return NULL;
6957 if (opint[0] == 0)
6958 temp = 64;
6959 else
6960 temp = 64 - floor_log2 (opint[0]) - 1;
6962 return build_int_cst (long_integer_type_node, temp);
6965 static tree
6966 alpha_fold_builtin_ctpop (unsigned HOST_WIDE_INT opint[], long op_const)
6968 unsigned HOST_WIDE_INT temp, op;
6970 if (op_const == 0)
6971 return NULL;
6973 op = opint[0];
6974 temp = 0;
6975 while (op)
6976 temp++, op &= op - 1;
6978 return build_int_cst (long_integer_type_node, temp);
6981 /* Fold one of our builtin functions. */
6983 static tree
6984 alpha_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
6986 tree op[MAX_ARGS], t;
6987 unsigned HOST_WIDE_INT opint[MAX_ARGS];
6988 long op_const = 0, arity = 0;
6990 for (t = arglist; t ; t = TREE_CHAIN (t), ++arity)
6992 tree arg = TREE_VALUE (t);
6993 if (arg == error_mark_node)
6994 return NULL;
6995 if (arity >= MAX_ARGS)
6996 return NULL;
6998 op[arity] = arg;
6999 opint[arity] = 0;
7000 if (TREE_CODE (arg) == INTEGER_CST)
7002 op_const |= 1L << arity;
7003 opint[arity] = int_cst_value (arg);
7007 switch (DECL_FUNCTION_CODE (fndecl))
7009 case ALPHA_BUILTIN_CMPBGE:
7010 return alpha_fold_builtin_cmpbge (opint, op_const);
7012 case ALPHA_BUILTIN_EXTBL:
7013 return alpha_fold_builtin_extxx (op, opint, op_const, 0x01, false);
7014 case ALPHA_BUILTIN_EXTWL:
7015 return alpha_fold_builtin_extxx (op, opint, op_const, 0x03, false);
7016 case ALPHA_BUILTIN_EXTLL:
7017 return alpha_fold_builtin_extxx (op, opint, op_const, 0x0f, false);
7018 case ALPHA_BUILTIN_EXTQL:
7019 return alpha_fold_builtin_extxx (op, opint, op_const, 0xff, false);
7020 case ALPHA_BUILTIN_EXTWH:
7021 return alpha_fold_builtin_extxx (op, opint, op_const, 0x03, true);
7022 case ALPHA_BUILTIN_EXTLH:
7023 return alpha_fold_builtin_extxx (op, opint, op_const, 0x0f, true);
7024 case ALPHA_BUILTIN_EXTQH:
7025 return alpha_fold_builtin_extxx (op, opint, op_const, 0xff, true);
7027 case ALPHA_BUILTIN_INSBL:
7028 return alpha_fold_builtin_insxx (op, opint, op_const, 0x01, false);
7029 case ALPHA_BUILTIN_INSWL:
7030 return alpha_fold_builtin_insxx (op, opint, op_const, 0x03, false);
7031 case ALPHA_BUILTIN_INSLL:
7032 return alpha_fold_builtin_insxx (op, opint, op_const, 0x0f, false);
7033 case ALPHA_BUILTIN_INSQL:
7034 return alpha_fold_builtin_insxx (op, opint, op_const, 0xff, false);
7035 case ALPHA_BUILTIN_INSWH:
7036 return alpha_fold_builtin_insxx (op, opint, op_const, 0x03, true);
7037 case ALPHA_BUILTIN_INSLH:
7038 return alpha_fold_builtin_insxx (op, opint, op_const, 0x0f, true);
7039 case ALPHA_BUILTIN_INSQH:
7040 return alpha_fold_builtin_insxx (op, opint, op_const, 0xff, true);
7042 case ALPHA_BUILTIN_MSKBL:
7043 return alpha_fold_builtin_mskxx (op, opint, op_const, 0x01, false);
7044 case ALPHA_BUILTIN_MSKWL:
7045 return alpha_fold_builtin_mskxx (op, opint, op_const, 0x03, false);
7046 case ALPHA_BUILTIN_MSKLL:
7047 return alpha_fold_builtin_mskxx (op, opint, op_const, 0x0f, false);
7048 case ALPHA_BUILTIN_MSKQL:
7049 return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, false);
7050 case ALPHA_BUILTIN_MSKWH:
7051 return alpha_fold_builtin_mskxx (op, opint, op_const, 0x03, true);
7052 case ALPHA_BUILTIN_MSKLH:
7053 return alpha_fold_builtin_mskxx (op, opint, op_const, 0x0f, true);
7054 case ALPHA_BUILTIN_MSKQH:
7055 return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, true);
7057 case ALPHA_BUILTIN_UMULH:
7058 return alpha_fold_builtin_umulh (opint, op_const);
7060 case ALPHA_BUILTIN_ZAP:
7061 opint[1] ^= 0xff;
7062 /* FALLTHRU */
7063 case ALPHA_BUILTIN_ZAPNOT:
7064 return alpha_fold_builtin_zapnot (op, opint, op_const);
7066 case ALPHA_BUILTIN_MINUB8:
7067 return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v8qi_u);
7068 case ALPHA_BUILTIN_MINSB8:
7069 return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v8qi_s);
7070 case ALPHA_BUILTIN_MINUW4:
7071 return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v4hi_u);
7072 case ALPHA_BUILTIN_MINSW4:
7073 return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v4hi_s);
7074 case ALPHA_BUILTIN_MAXUB8:
7075 return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v8qi_u);
7076 case ALPHA_BUILTIN_MAXSB8:
7077 return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v8qi_s);
7078 case ALPHA_BUILTIN_MAXUW4:
7079 return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v4hi_u);
7080 case ALPHA_BUILTIN_MAXSW4:
7081 return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v4hi_s);
7083 case ALPHA_BUILTIN_PERR:
7084 return alpha_fold_builtin_perr (opint, op_const);
7085 case ALPHA_BUILTIN_PKLB:
7086 return alpha_fold_builtin_pklb (opint, op_const);
7087 case ALPHA_BUILTIN_PKWB:
7088 return alpha_fold_builtin_pkwb (opint, op_const);
7089 case ALPHA_BUILTIN_UNPKBL:
7090 return alpha_fold_builtin_unpkbl (opint, op_const);
7091 case ALPHA_BUILTIN_UNPKBW:
7092 return alpha_fold_builtin_unpkbw (opint, op_const);
7094 case ALPHA_BUILTIN_CTTZ:
7095 return alpha_fold_builtin_cttz (opint, op_const);
7096 case ALPHA_BUILTIN_CTLZ:
7097 return alpha_fold_builtin_ctlz (opint, op_const);
7098 case ALPHA_BUILTIN_CTPOP:
7099 return alpha_fold_builtin_ctpop (opint, op_const);
7101 case ALPHA_BUILTIN_AMASK:
7102 case ALPHA_BUILTIN_IMPLVER:
7103 case ALPHA_BUILTIN_RPCC:
7104 case ALPHA_BUILTIN_THREAD_POINTER:
7105 case ALPHA_BUILTIN_SET_THREAD_POINTER:
7106 /* None of these are foldable at compile-time. */
7107 default:
7108 return NULL;
7112 /* This page contains routines that are used to determine what the function
7113 prologue and epilogue code will do and write them out. */
7115 /* Compute the size of the save area in the stack. */
7117 /* These variables are used for communication between the following functions.
7118 They indicate various things about the current function being compiled
7119 that are used to tell what kind of prologue, epilogue and procedure
7120 descriptor to generate. */
7122 /* Nonzero if we need a stack procedure. */
7123 enum alpha_procedure_types {PT_NULL = 0, PT_REGISTER = 1, PT_STACK = 2};
7124 static enum alpha_procedure_types alpha_procedure_type;
7126 /* Register number (either FP or SP) that is used to unwind the frame. */
7127 static int vms_unwind_regno;
7129 /* Register number used to save FP. We need not have one for RA since
7130 we don't modify it for register procedures. This is only defined
7131 for register frame procedures. */
7132 static int vms_save_fp_regno;
7134 /* Register number used to reference objects off our PV. */
7135 static int vms_base_regno;
7137 /* Compute register masks for saved registers. */
7139 static void
7140 alpha_sa_mask (unsigned long *imaskP, unsigned long *fmaskP)
7142 unsigned long imask = 0;
7143 unsigned long fmask = 0;
7144 unsigned int i;
7146 /* When outputting a thunk, we don't have valid register life info,
7147 but assemble_start_function wants to output .frame and .mask
7148 directives. */
7149 if (cfun->is_thunk)
7151 *imaskP = 0;
7152 *fmaskP = 0;
7153 return;
7156 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
7157 imask |= (1UL << HARD_FRAME_POINTER_REGNUM);
7159 /* One for every register we have to save. */
7160 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
7161 if (! fixed_regs[i] && ! call_used_regs[i]
7162 && df_regs_ever_live_p (i) && i != REG_RA
7163 && (!TARGET_ABI_UNICOSMK || i != HARD_FRAME_POINTER_REGNUM))
7165 if (i < 32)
7166 imask |= (1UL << i);
7167 else
7168 fmask |= (1UL << (i - 32));
7171 /* We need to restore these for the handler. */
7172 if (crtl->calls_eh_return)
7174 for (i = 0; ; ++i)
7176 unsigned regno = EH_RETURN_DATA_REGNO (i);
7177 if (regno == INVALID_REGNUM)
7178 break;
7179 imask |= 1UL << regno;
7183 /* If any register spilled, then spill the return address also. */
7184 /* ??? This is required by the Digital stack unwind specification
7185 and isn't needed if we're doing Dwarf2 unwinding. */
7186 if (imask || fmask || alpha_ra_ever_killed ())
7187 imask |= (1UL << REG_RA);
7189 *imaskP = imask;
7190 *fmaskP = fmask;
7194 alpha_sa_size (void)
7196 unsigned long mask[2];
7197 int sa_size = 0;
7198 int i, j;
7200 alpha_sa_mask (&mask[0], &mask[1]);
7202 if (TARGET_ABI_UNICOSMK)
7204 if (mask[0] || mask[1])
7205 sa_size = 14;
7207 else
7209 for (j = 0; j < 2; ++j)
7210 for (i = 0; i < 32; ++i)
7211 if ((mask[j] >> i) & 1)
7212 sa_size++;
7215 if (TARGET_ABI_UNICOSMK)
7217 /* We might not need to generate a frame if we don't make any calls
7218 (including calls to __T3E_MISMATCH if this is a vararg function),
7219 don't have any local variables which require stack slots, don't
7220 use alloca and have not determined that we need a frame for other
7221 reasons. */
7223 alpha_procedure_type
7224 = (sa_size || get_frame_size() != 0
7225 || crtl->outgoing_args_size
7226 || cfun->stdarg || cfun->calls_alloca
7227 || frame_pointer_needed)
7228 ? PT_STACK : PT_REGISTER;
7230 /* Always reserve space for saving callee-saved registers if we
7231 need a frame as required by the calling convention. */
7232 if (alpha_procedure_type == PT_STACK)
7233 sa_size = 14;
7235 else if (TARGET_ABI_OPEN_VMS)
7237 /* Start by assuming we can use a register procedure if we don't
7238 make any calls (REG_RA not used) or need to save any
7239 registers and a stack procedure if we do. */
7240 if ((mask[0] >> REG_RA) & 1)
7241 alpha_procedure_type = PT_STACK;
7242 else if (get_frame_size() != 0)
7243 alpha_procedure_type = PT_REGISTER;
7244 else
7245 alpha_procedure_type = PT_NULL;
7247 /* Don't reserve space for saving FP & RA yet. Do that later after we've
7248 made the final decision on stack procedure vs register procedure. */
7249 if (alpha_procedure_type == PT_STACK)
7250 sa_size -= 2;
7252 /* Decide whether to refer to objects off our PV via FP or PV.
7253 If we need FP for something else or if we receive a nonlocal
7254 goto (which expects PV to contain the value), we must use PV.
7255 Otherwise, start by assuming we can use FP. */
7257 vms_base_regno
7258 = (frame_pointer_needed
7259 || cfun->has_nonlocal_label
7260 || alpha_procedure_type == PT_STACK
7261 || crtl->outgoing_args_size)
7262 ? REG_PV : HARD_FRAME_POINTER_REGNUM;
7264 /* If we want to copy PV into FP, we need to find some register
7265 in which to save FP. */
7267 vms_save_fp_regno = -1;
7268 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
7269 for (i = 0; i < 32; i++)
7270 if (! fixed_regs[i] && call_used_regs[i] && ! df_regs_ever_live_p (i))
7271 vms_save_fp_regno = i;
7273 if (vms_save_fp_regno == -1 && alpha_procedure_type == PT_REGISTER)
7274 vms_base_regno = REG_PV, alpha_procedure_type = PT_STACK;
7275 else if (alpha_procedure_type == PT_NULL)
7276 vms_base_regno = REG_PV;
7278 /* Stack unwinding should be done via FP unless we use it for PV. */
7279 vms_unwind_regno = (vms_base_regno == REG_PV
7280 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
7282 /* If this is a stack procedure, allow space for saving FP and RA. */
7283 if (alpha_procedure_type == PT_STACK)
7284 sa_size += 2;
7286 else
7288 /* Our size must be even (multiple of 16 bytes). */
7289 if (sa_size & 1)
7290 sa_size++;
7293 return sa_size * 8;
7296 /* Define the offset between two registers, one to be eliminated,
7297 and the other its replacement, at the start of a routine. */
7299 HOST_WIDE_INT
7300 alpha_initial_elimination_offset (unsigned int from,
7301 unsigned int to ATTRIBUTE_UNUSED)
7303 HOST_WIDE_INT ret;
7305 ret = alpha_sa_size ();
7306 ret += ALPHA_ROUND (crtl->outgoing_args_size);
7308 switch (from)
7310 case FRAME_POINTER_REGNUM:
7311 break;
7313 case ARG_POINTER_REGNUM:
7314 ret += (ALPHA_ROUND (get_frame_size ()
7315 + crtl->args.pretend_args_size)
7316 - crtl->args.pretend_args_size);
7317 break;
7319 default:
7320 gcc_unreachable ();
7323 return ret;
7327 alpha_pv_save_size (void)
7329 alpha_sa_size ();
7330 return alpha_procedure_type == PT_STACK ? 8 : 0;
7334 alpha_using_fp (void)
7336 alpha_sa_size ();
7337 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
7340 #if TARGET_ABI_OPEN_VMS
7342 const struct attribute_spec vms_attribute_table[] =
7344 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
7345 { "overlaid", 0, 0, true, false, false, NULL },
7346 { "global", 0, 0, true, false, false, NULL },
7347 { "initialize", 0, 0, true, false, false, NULL },
7348 { NULL, 0, 0, false, false, false, NULL }
7351 #endif
7353 static int
7354 find_lo_sum_using_gp (rtx *px, void *data ATTRIBUTE_UNUSED)
7356 return GET_CODE (*px) == LO_SUM && XEXP (*px, 0) == pic_offset_table_rtx;
7360 alpha_find_lo_sum_using_gp (rtx insn)
7362 return for_each_rtx (&PATTERN (insn), find_lo_sum_using_gp, NULL) > 0;
7365 static int
7366 alpha_does_function_need_gp (void)
7368 rtx insn;
7370 /* The GP being variable is an OSF abi thing. */
7371 if (! TARGET_ABI_OSF)
7372 return 0;
7374 /* We need the gp to load the address of __mcount. */
7375 if (TARGET_PROFILING_NEEDS_GP && crtl->profile)
7376 return 1;
7378 /* The code emitted by alpha_output_mi_thunk_osf uses the gp. */
7379 if (cfun->is_thunk)
7380 return 1;
7382 /* The nonlocal receiver pattern assumes that the gp is valid for
7383 the nested function. Reasonable because it's almost always set
7384 correctly already. For the cases where that's wrong, make sure
7385 the nested function loads its gp on entry. */
7386 if (crtl->has_nonlocal_goto)
7387 return 1;
7389 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
7390 Even if we are a static function, we still need to do this in case
7391 our address is taken and passed to something like qsort. */
7393 push_topmost_sequence ();
7394 insn = get_insns ();
7395 pop_topmost_sequence ();
7397 for (; insn; insn = NEXT_INSN (insn))
7398 if (INSN_P (insn)
7399 && ! JUMP_TABLE_DATA_P (insn)
7400 && GET_CODE (PATTERN (insn)) != USE
7401 && GET_CODE (PATTERN (insn)) != CLOBBER
7402 && get_attr_usegp (insn))
7403 return 1;
7405 return 0;
7409 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
7410 sequences. */
7412 static rtx
7413 set_frame_related_p (void)
7415 rtx seq = get_insns ();
7416 rtx insn;
7418 end_sequence ();
7420 if (!seq)
7421 return NULL_RTX;
7423 if (INSN_P (seq))
7425 insn = seq;
7426 while (insn != NULL_RTX)
7428 RTX_FRAME_RELATED_P (insn) = 1;
7429 insn = NEXT_INSN (insn);
7431 seq = emit_insn (seq);
7433 else
7435 seq = emit_insn (seq);
7436 RTX_FRAME_RELATED_P (seq) = 1;
7438 return seq;
7441 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
7443 /* Generates a store with the proper unwind info attached. VALUE is
7444 stored at BASE_REG+BASE_OFS. If FRAME_BIAS is nonzero, then BASE_REG
7445 contains SP+FRAME_BIAS, and that is the unwind info that should be
7446 generated. If FRAME_REG != VALUE, then VALUE is being stored on
7447 behalf of FRAME_REG, and FRAME_REG should be present in the unwind. */
7449 static void
7450 emit_frame_store_1 (rtx value, rtx base_reg, HOST_WIDE_INT frame_bias,
7451 HOST_WIDE_INT base_ofs, rtx frame_reg)
7453 rtx addr, mem, insn;
7455 addr = plus_constant (base_reg, base_ofs);
7456 mem = gen_rtx_MEM (DImode, addr);
7457 set_mem_alias_set (mem, alpha_sr_alias_set);
7459 insn = emit_move_insn (mem, value);
7460 RTX_FRAME_RELATED_P (insn) = 1;
7462 if (frame_bias || value != frame_reg)
7464 if (frame_bias)
7466 addr = plus_constant (stack_pointer_rtx, frame_bias + base_ofs);
7467 mem = gen_rtx_MEM (DImode, addr);
7470 REG_NOTES (insn)
7471 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
7472 gen_rtx_SET (VOIDmode, mem, frame_reg),
7473 REG_NOTES (insn));
7477 static void
7478 emit_frame_store (unsigned int regno, rtx base_reg,
7479 HOST_WIDE_INT frame_bias, HOST_WIDE_INT base_ofs)
7481 rtx reg = gen_rtx_REG (DImode, regno);
7482 emit_frame_store_1 (reg, base_reg, frame_bias, base_ofs, reg);
7485 /* Write function prologue. */
7487 /* On vms we have two kinds of functions:
7489 - stack frame (PROC_STACK)
7490 these are 'normal' functions with local vars and which are
7491 calling other functions
7492 - register frame (PROC_REGISTER)
7493 keeps all data in registers, needs no stack
7495 We must pass this to the assembler so it can generate the
7496 proper pdsc (procedure descriptor)
7497 This is done with the '.pdesc' command.
7499 On not-vms, we don't really differentiate between the two, as we can
7500 simply allocate stack without saving registers. */
7502 void
7503 alpha_expand_prologue (void)
7505 /* Registers to save. */
7506 unsigned long imask = 0;
7507 unsigned long fmask = 0;
7508 /* Stack space needed for pushing registers clobbered by us. */
7509 HOST_WIDE_INT sa_size;
7510 /* Complete stack size needed. */
7511 HOST_WIDE_INT frame_size;
7512 /* Offset from base reg to register save area. */
7513 HOST_WIDE_INT reg_offset;
7514 rtx sa_reg;
7515 int i;
7517 sa_size = alpha_sa_size ();
7519 frame_size = get_frame_size ();
7520 if (TARGET_ABI_OPEN_VMS)
7521 frame_size = ALPHA_ROUND (sa_size
7522 + (alpha_procedure_type == PT_STACK ? 8 : 0)
7523 + frame_size
7524 + crtl->args.pretend_args_size);
7525 else if (TARGET_ABI_UNICOSMK)
7526 /* We have to allocate space for the DSIB if we generate a frame. */
7527 frame_size = ALPHA_ROUND (sa_size
7528 + (alpha_procedure_type == PT_STACK ? 48 : 0))
7529 + ALPHA_ROUND (frame_size
7530 + crtl->outgoing_args_size);
7531 else
7532 frame_size = (ALPHA_ROUND (crtl->outgoing_args_size)
7533 + sa_size
7534 + ALPHA_ROUND (frame_size
7535 + crtl->args.pretend_args_size));
7537 if (TARGET_ABI_OPEN_VMS)
7538 reg_offset = 8;
7539 else
7540 reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
7542 alpha_sa_mask (&imask, &fmask);
7544 /* Emit an insn to reload GP, if needed. */
7545 if (TARGET_ABI_OSF)
7547 alpha_function_needs_gp = alpha_does_function_need_gp ();
7548 if (alpha_function_needs_gp)
7549 emit_insn (gen_prologue_ldgp ());
7552 /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert
7553 the call to mcount ourselves, rather than having the linker do it
7554 magically in response to -pg. Since _mcount has special linkage,
7555 don't represent the call as a call. */
7556 if (TARGET_PROFILING_NEEDS_GP && crtl->profile)
7557 emit_insn (gen_prologue_mcount ());
7559 if (TARGET_ABI_UNICOSMK)
7560 unicosmk_gen_dsib (&imask);
7562 /* Adjust the stack by the frame size. If the frame size is > 4096
7563 bytes, we need to be sure we probe somewhere in the first and last
7564 4096 bytes (we can probably get away without the latter test) and
7565 every 8192 bytes in between. If the frame size is > 32768, we
7566 do this in a loop. Otherwise, we generate the explicit probe
7567 instructions.
7569 Note that we are only allowed to adjust sp once in the prologue. */
7571 if (frame_size <= 32768)
7573 if (frame_size > 4096)
7575 int probed;
7577 for (probed = 4096; probed < frame_size; probed += 8192)
7578 emit_insn (gen_probe_stack (GEN_INT (TARGET_ABI_UNICOSMK
7579 ? -probed + 64
7580 : -probed)));
7582 /* We only have to do this probe if we aren't saving registers. */
7583 if (sa_size == 0 && frame_size > probed - 4096)
7584 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
7587 if (frame_size != 0)
7588 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
7589 GEN_INT (TARGET_ABI_UNICOSMK
7590 ? -frame_size + 64
7591 : -frame_size))));
7593 else
7595 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
7596 number of 8192 byte blocks to probe. We then probe each block
7597 in the loop and then set SP to the proper location. If the
7598 amount remaining is > 4096, we have to do one more probe if we
7599 are not saving any registers. */
7601 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
7602 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
7603 rtx ptr = gen_rtx_REG (DImode, 22);
7604 rtx count = gen_rtx_REG (DImode, 23);
7605 rtx seq;
7607 emit_move_insn (count, GEN_INT (blocks));
7608 emit_insn (gen_adddi3 (ptr, stack_pointer_rtx,
7609 GEN_INT (TARGET_ABI_UNICOSMK ? 4096 - 64 : 4096)));
7611 /* Because of the difficulty in emitting a new basic block this
7612 late in the compilation, generate the loop as a single insn. */
7613 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
7615 if (leftover > 4096 && sa_size == 0)
7617 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
7618 MEM_VOLATILE_P (last) = 1;
7619 emit_move_insn (last, const0_rtx);
7622 if (TARGET_ABI_WINDOWS_NT)
7624 /* For NT stack unwind (done by 'reverse execution'), it's
7625 not OK to take the result of a loop, even though the value
7626 is already in ptr, so we reload it via a single operation
7627 and subtract it to sp.
7629 Yes, that's correct -- we have to reload the whole constant
7630 into a temporary via ldah+lda then subtract from sp. */
7632 HOST_WIDE_INT lo, hi;
7633 lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
7634 hi = frame_size - lo;
7636 emit_move_insn (ptr, GEN_INT (hi));
7637 emit_insn (gen_adddi3 (ptr, ptr, GEN_INT (lo)));
7638 seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
7639 ptr));
7641 else
7643 seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
7644 GEN_INT (-leftover)));
7647 /* This alternative is special, because the DWARF code cannot
7648 possibly intuit through the loop above. So we invent this
7649 note it looks at instead. */
7650 RTX_FRAME_RELATED_P (seq) = 1;
7651 REG_NOTES (seq)
7652 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
7653 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
7654 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
7655 GEN_INT (TARGET_ABI_UNICOSMK
7656 ? -frame_size + 64
7657 : -frame_size))),
7658 REG_NOTES (seq));
7661 if (!TARGET_ABI_UNICOSMK)
7663 HOST_WIDE_INT sa_bias = 0;
7665 /* Cope with very large offsets to the register save area. */
7666 sa_reg = stack_pointer_rtx;
7667 if (reg_offset + sa_size > 0x8000)
7669 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
7670 rtx sa_bias_rtx;
7672 if (low + sa_size <= 0x8000)
7673 sa_bias = reg_offset - low, reg_offset = low;
7674 else
7675 sa_bias = reg_offset, reg_offset = 0;
7677 sa_reg = gen_rtx_REG (DImode, 24);
7678 sa_bias_rtx = GEN_INT (sa_bias);
7680 if (add_operand (sa_bias_rtx, DImode))
7681 emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_bias_rtx));
7682 else
7684 emit_move_insn (sa_reg, sa_bias_rtx);
7685 emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_reg));
7689 /* Save regs in stack order. Beginning with VMS PV. */
7690 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
7691 emit_frame_store (REG_PV, stack_pointer_rtx, 0, 0);
7693 /* Save register RA next. */
7694 if (imask & (1UL << REG_RA))
7696 emit_frame_store (REG_RA, sa_reg, sa_bias, reg_offset);
7697 imask &= ~(1UL << REG_RA);
7698 reg_offset += 8;
7701 /* Now save any other registers required to be saved. */
7702 for (i = 0; i < 31; i++)
7703 if (imask & (1UL << i))
7705 emit_frame_store (i, sa_reg, sa_bias, reg_offset);
7706 reg_offset += 8;
7709 for (i = 0; i < 31; i++)
7710 if (fmask & (1UL << i))
7712 emit_frame_store (i+32, sa_reg, sa_bias, reg_offset);
7713 reg_offset += 8;
7716 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
7718 /* The standard frame on the T3E includes space for saving registers.
7719 We just have to use it. We don't have to save the return address and
7720 the old frame pointer here - they are saved in the DSIB. */
7722 reg_offset = -56;
7723 for (i = 9; i < 15; i++)
7724 if (imask & (1UL << i))
7726 emit_frame_store (i, hard_frame_pointer_rtx, 0, reg_offset);
7727 reg_offset -= 8;
7729 for (i = 2; i < 10; i++)
7730 if (fmask & (1UL << i))
7732 emit_frame_store (i+32, hard_frame_pointer_rtx, 0, reg_offset);
7733 reg_offset -= 8;
7737 if (TARGET_ABI_OPEN_VMS)
7739 if (alpha_procedure_type == PT_REGISTER)
7740 /* Register frame procedures save the fp.
7741 ?? Ought to have a dwarf2 save for this. */
7742 emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
7743 hard_frame_pointer_rtx);
7745 if (alpha_procedure_type != PT_NULL && vms_base_regno != REG_PV)
7746 emit_insn (gen_force_movdi (gen_rtx_REG (DImode, vms_base_regno),
7747 gen_rtx_REG (DImode, REG_PV)));
7749 if (alpha_procedure_type != PT_NULL
7750 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
7751 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
7753 /* If we have to allocate space for outgoing args, do it now. */
7754 if (crtl->outgoing_args_size != 0)
7756 rtx seq
7757 = emit_move_insn (stack_pointer_rtx,
7758 plus_constant
7759 (hard_frame_pointer_rtx,
7760 - (ALPHA_ROUND
7761 (crtl->outgoing_args_size))));
7763 /* Only set FRAME_RELATED_P on the stack adjustment we just emitted
7764 if ! frame_pointer_needed. Setting the bit will change the CFA
7765 computation rule to use sp again, which would be wrong if we had
7766 frame_pointer_needed, as this means sp might move unpredictably
7767 later on.
7769 Also, note that
7770 frame_pointer_needed
7771 => vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
7773 crtl->outgoing_args_size != 0
7774 => alpha_procedure_type != PT_NULL,
7776 so when we are not setting the bit here, we are guaranteed to
7777 have emitted an FRP frame pointer update just before. */
7778 RTX_FRAME_RELATED_P (seq) = ! frame_pointer_needed;
7781 else if (!TARGET_ABI_UNICOSMK)
7783 /* If we need a frame pointer, set it from the stack pointer. */
7784 if (frame_pointer_needed)
7786 if (TARGET_CAN_FAULT_IN_PROLOGUE)
7787 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
7788 else
7789 /* This must always be the last instruction in the
7790 prologue, thus we emit a special move + clobber. */
7791 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
7792 stack_pointer_rtx, sa_reg)));
7796 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
7797 the prologue, for exception handling reasons, we cannot do this for
7798 any insn that might fault. We could prevent this for mems with a
7799 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
7800 have to prevent all such scheduling with a blockage.
7802 Linux, on the other hand, never bothered to implement OSF/1's
7803 exception handling, and so doesn't care about such things. Anyone
7804 planning to use dwarf2 frame-unwind info can also omit the blockage. */
7806 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
7807 emit_insn (gen_blockage ());
7810 /* Count the number of .file directives, so that .loc is up to date. */
7811 int num_source_filenames = 0;
7813 /* Output the textual info surrounding the prologue. */
7815 void
7816 alpha_start_function (FILE *file, const char *fnname,
7817 tree decl ATTRIBUTE_UNUSED)
7819 unsigned long imask = 0;
7820 unsigned long fmask = 0;
7821 /* Stack space needed for pushing registers clobbered by us. */
7822 HOST_WIDE_INT sa_size;
7823 /* Complete stack size needed. */
7824 unsigned HOST_WIDE_INT frame_size;
7825 /* The maximum debuggable frame size (512 Kbytes using Tru64 as). */
7826 unsigned HOST_WIDE_INT max_frame_size = TARGET_ABI_OSF && !TARGET_GAS
7827 ? 524288
7828 : 1UL << 31;
7829 /* Offset from base reg to register save area. */
7830 HOST_WIDE_INT reg_offset;
7831 char *entry_label = (char *) alloca (strlen (fnname) + 6);
7832 int i;
7834 /* Don't emit an extern directive for functions defined in the same file. */
7835 if (TARGET_ABI_UNICOSMK)
7837 tree name_tree;
7838 name_tree = get_identifier (fnname);
7839 TREE_ASM_WRITTEN (name_tree) = 1;
7842 alpha_fnname = fnname;
7843 sa_size = alpha_sa_size ();
7845 frame_size = get_frame_size ();
7846 if (TARGET_ABI_OPEN_VMS)
7847 frame_size = ALPHA_ROUND (sa_size
7848 + (alpha_procedure_type == PT_STACK ? 8 : 0)
7849 + frame_size
7850 + crtl->args.pretend_args_size);
7851 else if (TARGET_ABI_UNICOSMK)
7852 frame_size = ALPHA_ROUND (sa_size
7853 + (alpha_procedure_type == PT_STACK ? 48 : 0))
7854 + ALPHA_ROUND (frame_size
7855 + crtl->outgoing_args_size);
7856 else
7857 frame_size = (ALPHA_ROUND (crtl->outgoing_args_size)
7858 + sa_size
7859 + ALPHA_ROUND (frame_size
7860 + crtl->args.pretend_args_size));
7862 if (TARGET_ABI_OPEN_VMS)
7863 reg_offset = 8;
7864 else
7865 reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
7867 alpha_sa_mask (&imask, &fmask);
7869 /* Ecoff can handle multiple .file directives, so put out file and lineno.
7870 We have to do that before the .ent directive as we cannot switch
7871 files within procedures with native ecoff because line numbers are
7872 linked to procedure descriptors.
7873 Outputting the lineno helps debugging of one line functions as they
7874 would otherwise get no line number at all. Please note that we would
7875 like to put out last_linenum from final.c, but it is not accessible. */
7877 if (write_symbols == SDB_DEBUG)
7879 #ifdef ASM_OUTPUT_SOURCE_FILENAME
7880 ASM_OUTPUT_SOURCE_FILENAME (file,
7881 DECL_SOURCE_FILE (current_function_decl));
7882 #endif
7883 #ifdef SDB_OUTPUT_SOURCE_LINE
7884 if (debug_info_level != DINFO_LEVEL_TERSE)
7885 SDB_OUTPUT_SOURCE_LINE (file,
7886 DECL_SOURCE_LINE (current_function_decl));
7887 #endif
7890 /* Issue function start and label. */
7891 if (TARGET_ABI_OPEN_VMS
7892 || (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive))
7894 fputs ("\t.ent ", file);
7895 assemble_name (file, fnname);
7896 putc ('\n', file);
7898 /* If the function needs GP, we'll write the "..ng" label there.
7899 Otherwise, do it here. */
7900 if (TARGET_ABI_OSF
7901 && ! alpha_function_needs_gp
7902 && ! cfun->is_thunk)
7904 putc ('$', file);
7905 assemble_name (file, fnname);
7906 fputs ("..ng:\n", file);
7910 strcpy (entry_label, fnname);
7911 if (TARGET_ABI_OPEN_VMS)
7912 strcat (entry_label, "..en");
7914 /* For public functions, the label must be globalized by appending an
7915 additional colon. */
7916 if (TARGET_ABI_UNICOSMK && TREE_PUBLIC (decl))
7917 strcat (entry_label, ":");
7919 ASM_OUTPUT_LABEL (file, entry_label);
7920 inside_function = TRUE;
7922 if (TARGET_ABI_OPEN_VMS)
7923 fprintf (file, "\t.base $%d\n", vms_base_regno);
7925 if (!TARGET_ABI_OPEN_VMS && !TARGET_ABI_UNICOSMK && TARGET_IEEE_CONFORMANT
7926 && !flag_inhibit_size_directive)
7928 /* Set flags in procedure descriptor to request IEEE-conformant
7929 math-library routines. The value we set it to is PDSC_EXC_IEEE
7930 (/usr/include/pdsc.h). */
7931 fputs ("\t.eflag 48\n", file);
7934 /* Set up offsets to alpha virtual arg/local debugging pointer. */
7935 alpha_auto_offset = -frame_size + crtl->args.pretend_args_size;
7936 alpha_arg_offset = -frame_size + 48;
7938 /* Describe our frame. If the frame size is larger than an integer,
7939 print it as zero to avoid an assembler error. We won't be
7940 properly describing such a frame, but that's the best we can do. */
7941 if (TARGET_ABI_UNICOSMK)
7943 else if (TARGET_ABI_OPEN_VMS)
7944 fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,"
7945 HOST_WIDE_INT_PRINT_DEC "\n",
7946 vms_unwind_regno,
7947 frame_size >= (1UL << 31) ? 0 : frame_size,
7948 reg_offset);
7949 else if (!flag_inhibit_size_directive)
7950 fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,%d\n",
7951 (frame_pointer_needed
7952 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
7953 frame_size >= max_frame_size ? 0 : frame_size,
7954 crtl->args.pretend_args_size);
7956 /* Describe which registers were spilled. */
7957 if (TARGET_ABI_UNICOSMK)
7959 else if (TARGET_ABI_OPEN_VMS)
7961 if (imask)
7962 /* ??? Does VMS care if mask contains ra? The old code didn't
7963 set it, so I don't here. */
7964 fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1UL << REG_RA));
7965 if (fmask)
7966 fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
7967 if (alpha_procedure_type == PT_REGISTER)
7968 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
7970 else if (!flag_inhibit_size_directive)
7972 if (imask)
7974 fprintf (file, "\t.mask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", imask,
7975 frame_size >= max_frame_size ? 0 : reg_offset - frame_size);
7977 for (i = 0; i < 32; ++i)
7978 if (imask & (1UL << i))
7979 reg_offset += 8;
7982 if (fmask)
7983 fprintf (file, "\t.fmask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", fmask,
7984 frame_size >= max_frame_size ? 0 : reg_offset - frame_size);
7987 #if TARGET_ABI_OPEN_VMS
7988 /* Ifdef'ed cause link_section are only available then. */
7989 switch_to_section (readonly_data_section);
7990 fprintf (file, "\t.align 3\n");
7991 assemble_name (file, fnname); fputs ("..na:\n", file);
7992 fputs ("\t.ascii \"", file);
7993 assemble_name (file, fnname);
7994 fputs ("\\0\"\n", file);
7995 alpha_need_linkage (fnname, 1);
7996 switch_to_section (text_section);
7997 #endif
8000 /* Emit the .prologue note at the scheduled end of the prologue. */
8002 static void
8003 alpha_output_function_end_prologue (FILE *file)
8005 if (TARGET_ABI_UNICOSMK)
8007 else if (TARGET_ABI_OPEN_VMS)
8008 fputs ("\t.prologue\n", file);
8009 else if (TARGET_ABI_WINDOWS_NT)
8010 fputs ("\t.prologue 0\n", file);
8011 else if (!flag_inhibit_size_directive)
8012 fprintf (file, "\t.prologue %d\n",
8013 alpha_function_needs_gp || cfun->is_thunk);
8016 /* Write function epilogue. */
8018 /* ??? At some point we will want to support full unwind, and so will
8019 need to mark the epilogue as well. At the moment, we just confuse
8020 dwarf2out. */
8021 #undef FRP
8022 #define FRP(exp) exp
8024 void
8025 alpha_expand_epilogue (void)
8027 /* Registers to save. */
8028 unsigned long imask = 0;
8029 unsigned long fmask = 0;
8030 /* Stack space needed for pushing registers clobbered by us. */
8031 HOST_WIDE_INT sa_size;
8032 /* Complete stack size needed. */
8033 HOST_WIDE_INT frame_size;
8034 /* Offset from base reg to register save area. */
8035 HOST_WIDE_INT reg_offset;
8036 int fp_is_frame_pointer, fp_offset;
8037 rtx sa_reg, sa_reg_exp = NULL;
8038 rtx sp_adj1, sp_adj2, mem;
8039 rtx eh_ofs;
8040 int i;
8042 sa_size = alpha_sa_size ();
8044 frame_size = get_frame_size ();
8045 if (TARGET_ABI_OPEN_VMS)
8046 frame_size = ALPHA_ROUND (sa_size
8047 + (alpha_procedure_type == PT_STACK ? 8 : 0)
8048 + frame_size
8049 + crtl->args.pretend_args_size);
8050 else if (TARGET_ABI_UNICOSMK)
8051 frame_size = ALPHA_ROUND (sa_size
8052 + (alpha_procedure_type == PT_STACK ? 48 : 0))
8053 + ALPHA_ROUND (frame_size
8054 + crtl->outgoing_args_size);
8055 else
8056 frame_size = (ALPHA_ROUND (crtl->outgoing_args_size)
8057 + sa_size
8058 + ALPHA_ROUND (frame_size
8059 + crtl->args.pretend_args_size));
8061 if (TARGET_ABI_OPEN_VMS)
8063 if (alpha_procedure_type == PT_STACK)
8064 reg_offset = 8;
8065 else
8066 reg_offset = 0;
8068 else
8069 reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
8071 alpha_sa_mask (&imask, &fmask);
8073 fp_is_frame_pointer
8074 = ((TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
8075 || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed));
8076 fp_offset = 0;
8077 sa_reg = stack_pointer_rtx;
8079 if (crtl->calls_eh_return)
8080 eh_ofs = EH_RETURN_STACKADJ_RTX;
8081 else
8082 eh_ofs = NULL_RTX;
8084 if (!TARGET_ABI_UNICOSMK && sa_size)
8086 /* If we have a frame pointer, restore SP from it. */
8087 if ((TARGET_ABI_OPEN_VMS
8088 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
8089 || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed))
8090 FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
8092 /* Cope with very large offsets to the register save area. */
8093 if (reg_offset + sa_size > 0x8000)
8095 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
8096 HOST_WIDE_INT bias;
8098 if (low + sa_size <= 0x8000)
8099 bias = reg_offset - low, reg_offset = low;
8100 else
8101 bias = reg_offset, reg_offset = 0;
8103 sa_reg = gen_rtx_REG (DImode, 22);
8104 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
8106 FRP (emit_move_insn (sa_reg, sa_reg_exp));
8109 /* Restore registers in order, excepting a true frame pointer. */
8111 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
8112 if (! eh_ofs)
8113 set_mem_alias_set (mem, alpha_sr_alias_set);
8114 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
8116 reg_offset += 8;
8117 imask &= ~(1UL << REG_RA);
8119 for (i = 0; i < 31; ++i)
8120 if (imask & (1UL << i))
8122 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
8123 fp_offset = reg_offset;
8124 else
8126 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
8127 set_mem_alias_set (mem, alpha_sr_alias_set);
8128 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
8130 reg_offset += 8;
8133 for (i = 0; i < 31; ++i)
8134 if (fmask & (1UL << i))
8136 mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
8137 set_mem_alias_set (mem, alpha_sr_alias_set);
8138 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
8139 reg_offset += 8;
8142 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
8144 /* Restore callee-saved general-purpose registers. */
8146 reg_offset = -56;
8148 for (i = 9; i < 15; i++)
8149 if (imask & (1UL << i))
8151 mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx,
8152 reg_offset));
8153 set_mem_alias_set (mem, alpha_sr_alias_set);
8154 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
8155 reg_offset -= 8;
8158 for (i = 2; i < 10; i++)
8159 if (fmask & (1UL << i))
8161 mem = gen_rtx_MEM (DFmode, plus_constant(hard_frame_pointer_rtx,
8162 reg_offset));
8163 set_mem_alias_set (mem, alpha_sr_alias_set);
8164 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
8165 reg_offset -= 8;
8168 /* Restore the return address from the DSIB. */
8170 mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx, -8));
8171 set_mem_alias_set (mem, alpha_sr_alias_set);
8172 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
8175 if (frame_size || eh_ofs)
8177 sp_adj1 = stack_pointer_rtx;
8179 if (eh_ofs)
8181 sp_adj1 = gen_rtx_REG (DImode, 23);
8182 emit_move_insn (sp_adj1,
8183 gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
8186 /* If the stack size is large, begin computation into a temporary
8187 register so as not to interfere with a potential fp restore,
8188 which must be consecutive with an SP restore. */
8189 if (frame_size < 32768
8190 && ! (TARGET_ABI_UNICOSMK && cfun->calls_alloca))
8191 sp_adj2 = GEN_INT (frame_size);
8192 else if (TARGET_ABI_UNICOSMK)
8194 sp_adj1 = gen_rtx_REG (DImode, 23);
8195 FRP (emit_move_insn (sp_adj1, hard_frame_pointer_rtx));
8196 sp_adj2 = const0_rtx;
8198 else if (frame_size < 0x40007fffL)
8200 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
8202 sp_adj2 = plus_constant (sp_adj1, frame_size - low);
8203 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
8204 sp_adj1 = sa_reg;
8205 else
8207 sp_adj1 = gen_rtx_REG (DImode, 23);
8208 FRP (emit_move_insn (sp_adj1, sp_adj2));
8210 sp_adj2 = GEN_INT (low);
8212 else
8214 rtx tmp = gen_rtx_REG (DImode, 23);
8215 FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size,
8216 3, false));
8217 if (!sp_adj2)
8219 /* We can't drop new things to memory this late, afaik,
8220 so build it up by pieces. */
8221 FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
8222 -(frame_size < 0)));
8223 gcc_assert (sp_adj2);
8227 /* From now on, things must be in order. So emit blockages. */
8229 /* Restore the frame pointer. */
8230 if (TARGET_ABI_UNICOSMK)
8232 emit_insn (gen_blockage ());
8233 mem = gen_rtx_MEM (DImode,
8234 plus_constant (hard_frame_pointer_rtx, -16));
8235 set_mem_alias_set (mem, alpha_sr_alias_set);
8236 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
8238 else if (fp_is_frame_pointer)
8240 emit_insn (gen_blockage ());
8241 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, fp_offset));
8242 set_mem_alias_set (mem, alpha_sr_alias_set);
8243 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
8245 else if (TARGET_ABI_OPEN_VMS)
8247 emit_insn (gen_blockage ());
8248 FRP (emit_move_insn (hard_frame_pointer_rtx,
8249 gen_rtx_REG (DImode, vms_save_fp_regno)));
8252 /* Restore the stack pointer. */
8253 emit_insn (gen_blockage ());
8254 if (sp_adj2 == const0_rtx)
8255 FRP (emit_move_insn (stack_pointer_rtx, sp_adj1));
8256 else
8257 FRP (emit_move_insn (stack_pointer_rtx,
8258 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
8260 else
8262 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_REGISTER)
8264 emit_insn (gen_blockage ());
8265 FRP (emit_move_insn (hard_frame_pointer_rtx,
8266 gen_rtx_REG (DImode, vms_save_fp_regno)));
8268 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type != PT_STACK)
8270 /* Decrement the frame pointer if the function does not have a
8271 frame. */
8273 emit_insn (gen_blockage ());
8274 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
8275 hard_frame_pointer_rtx, constm1_rtx)));
8280 /* Output the rest of the textual info surrounding the epilogue. */
8282 void
8283 alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED)
8285 rtx insn;
8287 /* We output a nop after noreturn calls at the very end of the function to
8288 ensure that the return address always remains in the caller's code range,
8289 as not doing so might confuse unwinding engines. */
8290 insn = get_last_insn ();
8291 if (!INSN_P (insn))
8292 insn = prev_active_insn (insn);
8293 if (insn && GET_CODE (insn) == CALL_INSN)
8294 output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL);
8296 #if TARGET_ABI_OSF
8297 if (cfun->is_thunk)
8298 free_after_compilation (cfun);
8299 #endif
8301 #if TARGET_ABI_OPEN_VMS
8302 alpha_write_linkage (file, fnname, decl);
8303 #endif
8305 /* End the function. */
8306 if (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive)
8308 fputs ("\t.end ", file);
8309 assemble_name (file, fnname);
8310 putc ('\n', file);
8312 inside_function = FALSE;
8314 /* Output jump tables and the static subroutine information block. */
8315 if (TARGET_ABI_UNICOSMK)
8317 unicosmk_output_ssib (file, fnname);
8318 unicosmk_output_deferred_case_vectors (file);
8322 #if TARGET_ABI_OSF
8323 /* Emit a tail call to FUNCTION after adjusting THIS by DELTA.
8325 In order to avoid the hordes of differences between generated code
8326 with and without TARGET_EXPLICIT_RELOCS, and to avoid duplicating
8327 lots of code loading up large constants, generate rtl and emit it
8328 instead of going straight to text.
8330 Not sure why this idea hasn't been explored before... */
8332 static void
8333 alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
8334 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
8335 tree function)
8337 HOST_WIDE_INT hi, lo;
8338 rtx this_rtx, insn, funexp;
8340 gcc_assert (cfun->is_thunk);
8342 /* We always require a valid GP. */
8343 emit_insn (gen_prologue_ldgp ());
8344 emit_note (NOTE_INSN_PROLOGUE_END);
8346 /* Find the "this" pointer. If the function returns a structure,
8347 the structure return pointer is in $16. */
8348 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
8349 this_rtx = gen_rtx_REG (Pmode, 17);
8350 else
8351 this_rtx = gen_rtx_REG (Pmode, 16);
8353 /* Add DELTA. When possible we use ldah+lda. Otherwise load the
8354 entire constant for the add. */
8355 lo = ((delta & 0xffff) ^ 0x8000) - 0x8000;
8356 hi = (((delta - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
8357 if (hi + lo == delta)
8359 if (hi)
8360 emit_insn (gen_adddi3 (this_rtx, this_rtx, GEN_INT (hi)));
8361 if (lo)
8362 emit_insn (gen_adddi3 (this_rtx, this_rtx, GEN_INT (lo)));
8364 else
8366 rtx tmp = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 0),
8367 delta, -(delta < 0));
8368 emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp));
8371 /* Add a delta stored in the vtable at VCALL_OFFSET. */
8372 if (vcall_offset)
8374 rtx tmp, tmp2;
8376 tmp = gen_rtx_REG (Pmode, 0);
8377 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
8379 lo = ((vcall_offset & 0xffff) ^ 0x8000) - 0x8000;
8380 hi = (((vcall_offset - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
8381 if (hi + lo == vcall_offset)
8383 if (hi)
8384 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (hi)));
8386 else
8388 tmp2 = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 1),
8389 vcall_offset, -(vcall_offset < 0));
8390 emit_insn (gen_adddi3 (tmp, tmp, tmp2));
8391 lo = 0;
8393 if (lo)
8394 tmp2 = gen_rtx_PLUS (Pmode, tmp, GEN_INT (lo));
8395 else
8396 tmp2 = tmp;
8397 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp2));
8399 emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp));
8402 /* Generate a tail call to the target function. */
8403 if (! TREE_USED (function))
8405 assemble_external (function);
8406 TREE_USED (function) = 1;
8408 funexp = XEXP (DECL_RTL (function), 0);
8409 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
8410 insn = emit_call_insn (gen_sibcall (funexp, const0_rtx));
8411 SIBLING_CALL_P (insn) = 1;
8413 /* Run just enough of rest_of_compilation to get the insns emitted.
8414 There's not really enough bulk here to make other passes such as
8415 instruction scheduling worth while. Note that use_thunk calls
8416 assemble_start_function and assemble_end_function. */
8417 insn = get_insns ();
8418 insn_locators_alloc ();
8419 shorten_branches (insn);
8420 final_start_function (insn, file, 1);
8421 final (insn, file, 1);
8422 final_end_function ();
8424 #endif /* TARGET_ABI_OSF */
8426 /* Debugging support. */
8428 #include "gstab.h"
8430 /* Count the number of sdb related labels are generated (to find block
8431 start and end boundaries). */
8433 int sdb_label_count = 0;
8435 /* Name of the file containing the current function. */
8437 static const char *current_function_file = "";
8439 /* Offsets to alpha virtual arg/local debugging pointers. */
8441 long alpha_arg_offset;
8442 long alpha_auto_offset;
8444 /* Emit a new filename to a stream. */
8446 void
8447 alpha_output_filename (FILE *stream, const char *name)
8449 static int first_time = TRUE;
8451 if (first_time)
8453 first_time = FALSE;
8454 ++num_source_filenames;
8455 current_function_file = name;
8456 fprintf (stream, "\t.file\t%d ", num_source_filenames);
8457 output_quoted_string (stream, name);
8458 fprintf (stream, "\n");
8459 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
8460 fprintf (stream, "\t#@stabs\n");
8463 else if (write_symbols == DBX_DEBUG)
8464 /* dbxout.c will emit an appropriate .stabs directive. */
8465 return;
8467 else if (name != current_function_file
8468 && strcmp (name, current_function_file) != 0)
8470 if (inside_function && ! TARGET_GAS)
8471 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
8472 else
8474 ++num_source_filenames;
8475 current_function_file = name;
8476 fprintf (stream, "\t.file\t%d ", num_source_filenames);
8479 output_quoted_string (stream, name);
8480 fprintf (stream, "\n");
8484 /* Structure to show the current status of registers and memory. */
8486 struct shadow_summary
8488 struct {
8489 unsigned int i : 31; /* Mask of int regs */
8490 unsigned int fp : 31; /* Mask of fp regs */
8491 unsigned int mem : 1; /* mem == imem | fpmem */
8492 } used, defd;
8495 /* Summary the effects of expression X on the machine. Update SUM, a pointer
8496 to the summary structure. SET is nonzero if the insn is setting the
8497 object, otherwise zero. */
8499 static void
8500 summarize_insn (rtx x, struct shadow_summary *sum, int set)
8502 const char *format_ptr;
8503 int i, j;
8505 if (x == 0)
8506 return;
8508 switch (GET_CODE (x))
8510 /* ??? Note that this case would be incorrect if the Alpha had a
8511 ZERO_EXTRACT in SET_DEST. */
8512 case SET:
8513 summarize_insn (SET_SRC (x), sum, 0);
8514 summarize_insn (SET_DEST (x), sum, 1);
8515 break;
8517 case CLOBBER:
8518 summarize_insn (XEXP (x, 0), sum, 1);
8519 break;
8521 case USE:
8522 summarize_insn (XEXP (x, 0), sum, 0);
8523 break;
8525 case ASM_OPERANDS:
8526 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
8527 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
8528 break;
8530 case PARALLEL:
8531 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
8532 summarize_insn (XVECEXP (x, 0, i), sum, 0);
8533 break;
8535 case SUBREG:
8536 summarize_insn (SUBREG_REG (x), sum, 0);
8537 break;
8539 case REG:
8541 int regno = REGNO (x);
8542 unsigned long mask = ((unsigned long) 1) << (regno % 32);
8544 if (regno == 31 || regno == 63)
8545 break;
8547 if (set)
8549 if (regno < 32)
8550 sum->defd.i |= mask;
8551 else
8552 sum->defd.fp |= mask;
8554 else
8556 if (regno < 32)
8557 sum->used.i |= mask;
8558 else
8559 sum->used.fp |= mask;
8562 break;
8564 case MEM:
8565 if (set)
8566 sum->defd.mem = 1;
8567 else
8568 sum->used.mem = 1;
8570 /* Find the regs used in memory address computation: */
8571 summarize_insn (XEXP (x, 0), sum, 0);
8572 break;
8574 case CONST_INT: case CONST_DOUBLE:
8575 case SYMBOL_REF: case LABEL_REF: case CONST:
8576 case SCRATCH: case ASM_INPUT:
8577 break;
8579 /* Handle common unary and binary ops for efficiency. */
8580 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
8581 case MOD: case UDIV: case UMOD: case AND: case IOR:
8582 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
8583 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
8584 case NE: case EQ: case GE: case GT: case LE:
8585 case LT: case GEU: case GTU: case LEU: case LTU:
8586 summarize_insn (XEXP (x, 0), sum, 0);
8587 summarize_insn (XEXP (x, 1), sum, 0);
8588 break;
8590 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
8591 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
8592 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
8593 case SQRT: case FFS:
8594 summarize_insn (XEXP (x, 0), sum, 0);
8595 break;
8597 default:
8598 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
8599 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
8600 switch (format_ptr[i])
8602 case 'e':
8603 summarize_insn (XEXP (x, i), sum, 0);
8604 break;
8606 case 'E':
8607 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
8608 summarize_insn (XVECEXP (x, i, j), sum, 0);
8609 break;
8611 case 'i':
8612 break;
8614 default:
8615 gcc_unreachable ();
8620 /* Ensure a sufficient number of `trapb' insns are in the code when
8621 the user requests code with a trap precision of functions or
8622 instructions.
8624 In naive mode, when the user requests a trap-precision of
8625 "instruction", a trapb is needed after every instruction that may
8626 generate a trap. This ensures that the code is resumption safe but
8627 it is also slow.
8629 When optimizations are turned on, we delay issuing a trapb as long
8630 as possible. In this context, a trap shadow is the sequence of
8631 instructions that starts with a (potentially) trap generating
8632 instruction and extends to the next trapb or call_pal instruction
8633 (but GCC never generates call_pal by itself). We can delay (and
8634 therefore sometimes omit) a trapb subject to the following
8635 conditions:
8637 (a) On entry to the trap shadow, if any Alpha register or memory
8638 location contains a value that is used as an operand value by some
8639 instruction in the trap shadow (live on entry), then no instruction
8640 in the trap shadow may modify the register or memory location.
8642 (b) Within the trap shadow, the computation of the base register
8643 for a memory load or store instruction may not involve using the
8644 result of an instruction that might generate an UNPREDICTABLE
8645 result.
8647 (c) Within the trap shadow, no register may be used more than once
8648 as a destination register. (This is to make life easier for the
8649 trap-handler.)
8651 (d) The trap shadow may not include any branch instructions. */
8653 static void
8654 alpha_handle_trap_shadows (void)
8656 struct shadow_summary shadow;
8657 int trap_pending, exception_nesting;
8658 rtx i, n;
8660 trap_pending = 0;
8661 exception_nesting = 0;
8662 shadow.used.i = 0;
8663 shadow.used.fp = 0;
8664 shadow.used.mem = 0;
8665 shadow.defd = shadow.used;
8667 for (i = get_insns (); i ; i = NEXT_INSN (i))
8669 if (GET_CODE (i) == NOTE)
8671 switch (NOTE_KIND (i))
8673 case NOTE_INSN_EH_REGION_BEG:
8674 exception_nesting++;
8675 if (trap_pending)
8676 goto close_shadow;
8677 break;
8679 case NOTE_INSN_EH_REGION_END:
8680 exception_nesting--;
8681 if (trap_pending)
8682 goto close_shadow;
8683 break;
8685 case NOTE_INSN_EPILOGUE_BEG:
8686 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
8687 goto close_shadow;
8688 break;
8691 else if (trap_pending)
8693 if (alpha_tp == ALPHA_TP_FUNC)
8695 if (GET_CODE (i) == JUMP_INSN
8696 && GET_CODE (PATTERN (i)) == RETURN)
8697 goto close_shadow;
8699 else if (alpha_tp == ALPHA_TP_INSN)
8701 if (optimize > 0)
8703 struct shadow_summary sum;
8705 sum.used.i = 0;
8706 sum.used.fp = 0;
8707 sum.used.mem = 0;
8708 sum.defd = sum.used;
8710 switch (GET_CODE (i))
8712 case INSN:
8713 /* Annoyingly, get_attr_trap will die on these. */
8714 if (GET_CODE (PATTERN (i)) == USE
8715 || GET_CODE (PATTERN (i)) == CLOBBER)
8716 break;
8718 summarize_insn (PATTERN (i), &sum, 0);
8720 if ((sum.defd.i & shadow.defd.i)
8721 || (sum.defd.fp & shadow.defd.fp))
8723 /* (c) would be violated */
8724 goto close_shadow;
8727 /* Combine shadow with summary of current insn: */
8728 shadow.used.i |= sum.used.i;
8729 shadow.used.fp |= sum.used.fp;
8730 shadow.used.mem |= sum.used.mem;
8731 shadow.defd.i |= sum.defd.i;
8732 shadow.defd.fp |= sum.defd.fp;
8733 shadow.defd.mem |= sum.defd.mem;
8735 if ((sum.defd.i & shadow.used.i)
8736 || (sum.defd.fp & shadow.used.fp)
8737 || (sum.defd.mem & shadow.used.mem))
8739 /* (a) would be violated (also takes care of (b)) */
8740 gcc_assert (get_attr_trap (i) != TRAP_YES
8741 || (!(sum.defd.i & sum.used.i)
8742 && !(sum.defd.fp & sum.used.fp)));
8744 goto close_shadow;
8746 break;
8748 case JUMP_INSN:
8749 case CALL_INSN:
8750 case CODE_LABEL:
8751 goto close_shadow;
8753 default:
8754 gcc_unreachable ();
8757 else
8759 close_shadow:
8760 n = emit_insn_before (gen_trapb (), i);
8761 PUT_MODE (n, TImode);
8762 PUT_MODE (i, TImode);
8763 trap_pending = 0;
8764 shadow.used.i = 0;
8765 shadow.used.fp = 0;
8766 shadow.used.mem = 0;
8767 shadow.defd = shadow.used;
8772 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
8773 && GET_CODE (i) == INSN
8774 && GET_CODE (PATTERN (i)) != USE
8775 && GET_CODE (PATTERN (i)) != CLOBBER
8776 && get_attr_trap (i) == TRAP_YES)
8778 if (optimize && !trap_pending)
8779 summarize_insn (PATTERN (i), &shadow, 0);
8780 trap_pending = 1;
8785 /* Alpha can only issue instruction groups simultaneously if they are
8786 suitably aligned. This is very processor-specific. */
8787 /* There are a number of entries in alphaev4_insn_pipe and alphaev5_insn_pipe
8788 that are marked "fake". These instructions do not exist on that target,
8789 but it is possible to see these insns with deranged combinations of
8790 command-line options, such as "-mtune=ev4 -mmax". Instead of aborting,
8791 choose a result at random. */
8793 enum alphaev4_pipe {
8794 EV4_STOP = 0,
8795 EV4_IB0 = 1,
8796 EV4_IB1 = 2,
8797 EV4_IBX = 4
8800 enum alphaev5_pipe {
8801 EV5_STOP = 0,
8802 EV5_NONE = 1,
8803 EV5_E01 = 2,
8804 EV5_E0 = 4,
8805 EV5_E1 = 8,
8806 EV5_FAM = 16,
8807 EV5_FA = 32,
8808 EV5_FM = 64
8811 static enum alphaev4_pipe
8812 alphaev4_insn_pipe (rtx insn)
8814 if (recog_memoized (insn) < 0)
8815 return EV4_STOP;
8816 if (get_attr_length (insn) != 4)
8817 return EV4_STOP;
8819 switch (get_attr_type (insn))
8821 case TYPE_ILD:
8822 case TYPE_LDSYM:
8823 case TYPE_FLD:
8824 case TYPE_LD_L:
8825 return EV4_IBX;
8827 case TYPE_IADD:
8828 case TYPE_ILOG:
8829 case TYPE_ICMOV:
8830 case TYPE_ICMP:
8831 case TYPE_FST:
8832 case TYPE_SHIFT:
8833 case TYPE_IMUL:
8834 case TYPE_FBR:
8835 case TYPE_MVI: /* fake */
8836 return EV4_IB0;
8838 case TYPE_IST:
8839 case TYPE_MISC:
8840 case TYPE_IBR:
8841 case TYPE_JSR:
8842 case TYPE_CALLPAL:
8843 case TYPE_FCPYS:
8844 case TYPE_FCMOV:
8845 case TYPE_FADD:
8846 case TYPE_FDIV:
8847 case TYPE_FMUL:
8848 case TYPE_ST_C:
8849 case TYPE_MB:
8850 case TYPE_FSQRT: /* fake */
8851 case TYPE_FTOI: /* fake */
8852 case TYPE_ITOF: /* fake */
8853 return EV4_IB1;
8855 default:
8856 gcc_unreachable ();
8860 static enum alphaev5_pipe
8861 alphaev5_insn_pipe (rtx insn)
8863 if (recog_memoized (insn) < 0)
8864 return EV5_STOP;
8865 if (get_attr_length (insn) != 4)
8866 return EV5_STOP;
8868 switch (get_attr_type (insn))
8870 case TYPE_ILD:
8871 case TYPE_FLD:
8872 case TYPE_LDSYM:
8873 case TYPE_IADD:
8874 case TYPE_ILOG:
8875 case TYPE_ICMOV:
8876 case TYPE_ICMP:
8877 return EV5_E01;
8879 case TYPE_IST:
8880 case TYPE_FST:
8881 case TYPE_SHIFT:
8882 case TYPE_IMUL:
8883 case TYPE_MISC:
8884 case TYPE_MVI:
8885 case TYPE_LD_L:
8886 case TYPE_ST_C:
8887 case TYPE_MB:
8888 case TYPE_FTOI: /* fake */
8889 case TYPE_ITOF: /* fake */
8890 return EV5_E0;
8892 case TYPE_IBR:
8893 case TYPE_JSR:
8894 case TYPE_CALLPAL:
8895 return EV5_E1;
8897 case TYPE_FCPYS:
8898 return EV5_FAM;
8900 case TYPE_FBR:
8901 case TYPE_FCMOV:
8902 case TYPE_FADD:
8903 case TYPE_FDIV:
8904 case TYPE_FSQRT: /* fake */
8905 return EV5_FA;
8907 case TYPE_FMUL:
8908 return EV5_FM;
8910 default:
8911 gcc_unreachable ();
8915 /* IN_USE is a mask of the slots currently filled within the insn group.
8916 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
8917 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
8919 LEN is, of course, the length of the group in bytes. */
8921 static rtx
8922 alphaev4_next_group (rtx insn, int *pin_use, int *plen)
8924 int len, in_use;
8926 len = in_use = 0;
8928 if (! INSN_P (insn)
8929 || GET_CODE (PATTERN (insn)) == CLOBBER
8930 || GET_CODE (PATTERN (insn)) == USE)
8931 goto next_and_done;
8933 while (1)
8935 enum alphaev4_pipe pipe;
8937 pipe = alphaev4_insn_pipe (insn);
8938 switch (pipe)
8940 case EV4_STOP:
8941 /* Force complex instructions to start new groups. */
8942 if (in_use)
8943 goto done;
8945 /* If this is a completely unrecognized insn, it's an asm.
8946 We don't know how long it is, so record length as -1 to
8947 signal a needed realignment. */
8948 if (recog_memoized (insn) < 0)
8949 len = -1;
8950 else
8951 len = get_attr_length (insn);
8952 goto next_and_done;
8954 case EV4_IBX:
8955 if (in_use & EV4_IB0)
8957 if (in_use & EV4_IB1)
8958 goto done;
8959 in_use |= EV4_IB1;
8961 else
8962 in_use |= EV4_IB0 | EV4_IBX;
8963 break;
8965 case EV4_IB0:
8966 if (in_use & EV4_IB0)
8968 if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
8969 goto done;
8970 in_use |= EV4_IB1;
8972 in_use |= EV4_IB0;
8973 break;
8975 case EV4_IB1:
8976 if (in_use & EV4_IB1)
8977 goto done;
8978 in_use |= EV4_IB1;
8979 break;
8981 default:
8982 gcc_unreachable ();
8984 len += 4;
8986 /* Haifa doesn't do well scheduling branches. */
8987 if (GET_CODE (insn) == JUMP_INSN)
8988 goto next_and_done;
8990 next:
8991 insn = next_nonnote_insn (insn);
8993 if (!insn || ! INSN_P (insn))
8994 goto done;
8996 /* Let Haifa tell us where it thinks insn group boundaries are. */
8997 if (GET_MODE (insn) == TImode)
8998 goto done;
9000 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
9001 goto next;
9004 next_and_done:
9005 insn = next_nonnote_insn (insn);
9007 done:
9008 *plen = len;
9009 *pin_use = in_use;
9010 return insn;
9013 /* IN_USE is a mask of the slots currently filled within the insn group.
9014 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
9015 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
9017 LEN is, of course, the length of the group in bytes. */
9019 static rtx
9020 alphaev5_next_group (rtx insn, int *pin_use, int *plen)
9022 int len, in_use;
9024 len = in_use = 0;
9026 if (! INSN_P (insn)
9027 || GET_CODE (PATTERN (insn)) == CLOBBER
9028 || GET_CODE (PATTERN (insn)) == USE)
9029 goto next_and_done;
9031 while (1)
9033 enum alphaev5_pipe pipe;
9035 pipe = alphaev5_insn_pipe (insn);
9036 switch (pipe)
9038 case EV5_STOP:
9039 /* Force complex instructions to start new groups. */
9040 if (in_use)
9041 goto done;
9043 /* If this is a completely unrecognized insn, it's an asm.
9044 We don't know how long it is, so record length as -1 to
9045 signal a needed realignment. */
9046 if (recog_memoized (insn) < 0)
9047 len = -1;
9048 else
9049 len = get_attr_length (insn);
9050 goto next_and_done;
9052 /* ??? Most of the places below, we would like to assert never
9053 happen, as it would indicate an error either in Haifa, or
9054 in the scheduling description. Unfortunately, Haifa never
9055 schedules the last instruction of the BB, so we don't have
9056 an accurate TI bit to go off. */
9057 case EV5_E01:
9058 if (in_use & EV5_E0)
9060 if (in_use & EV5_E1)
9061 goto done;
9062 in_use |= EV5_E1;
9064 else
9065 in_use |= EV5_E0 | EV5_E01;
9066 break;
9068 case EV5_E0:
9069 if (in_use & EV5_E0)
9071 if (!(in_use & EV5_E01) || (in_use & EV5_E1))
9072 goto done;
9073 in_use |= EV5_E1;
9075 in_use |= EV5_E0;
9076 break;
9078 case EV5_E1:
9079 if (in_use & EV5_E1)
9080 goto done;
9081 in_use |= EV5_E1;
9082 break;
9084 case EV5_FAM:
9085 if (in_use & EV5_FA)
9087 if (in_use & EV5_FM)
9088 goto done;
9089 in_use |= EV5_FM;
9091 else
9092 in_use |= EV5_FA | EV5_FAM;
9093 break;
9095 case EV5_FA:
9096 if (in_use & EV5_FA)
9097 goto done;
9098 in_use |= EV5_FA;
9099 break;
9101 case EV5_FM:
9102 if (in_use & EV5_FM)
9103 goto done;
9104 in_use |= EV5_FM;
9105 break;
9107 case EV5_NONE:
9108 break;
9110 default:
9111 gcc_unreachable ();
9113 len += 4;
9115 /* Haifa doesn't do well scheduling branches. */
9116 /* ??? If this is predicted not-taken, slotting continues, except
9117 that no more IBR, FBR, or JSR insns may be slotted. */
9118 if (GET_CODE (insn) == JUMP_INSN)
9119 goto next_and_done;
9121 next:
9122 insn = next_nonnote_insn (insn);
9124 if (!insn || ! INSN_P (insn))
9125 goto done;
9127 /* Let Haifa tell us where it thinks insn group boundaries are. */
9128 if (GET_MODE (insn) == TImode)
9129 goto done;
9131 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
9132 goto next;
9135 next_and_done:
9136 insn = next_nonnote_insn (insn);
9138 done:
9139 *plen = len;
9140 *pin_use = in_use;
9141 return insn;
9144 static rtx
9145 alphaev4_next_nop (int *pin_use)
9147 int in_use = *pin_use;
9148 rtx nop;
9150 if (!(in_use & EV4_IB0))
9152 in_use |= EV4_IB0;
9153 nop = gen_nop ();
9155 else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
9157 in_use |= EV4_IB1;
9158 nop = gen_nop ();
9160 else if (TARGET_FP && !(in_use & EV4_IB1))
9162 in_use |= EV4_IB1;
9163 nop = gen_fnop ();
9165 else
9166 nop = gen_unop ();
9168 *pin_use = in_use;
9169 return nop;
9172 static rtx
9173 alphaev5_next_nop (int *pin_use)
9175 int in_use = *pin_use;
9176 rtx nop;
9178 if (!(in_use & EV5_E1))
9180 in_use |= EV5_E1;
9181 nop = gen_nop ();
9183 else if (TARGET_FP && !(in_use & EV5_FA))
9185 in_use |= EV5_FA;
9186 nop = gen_fnop ();
9188 else if (TARGET_FP && !(in_use & EV5_FM))
9190 in_use |= EV5_FM;
9191 nop = gen_fnop ();
9193 else
9194 nop = gen_unop ();
9196 *pin_use = in_use;
9197 return nop;
9200 /* The instruction group alignment main loop. */
9202 static void
9203 alpha_align_insns (unsigned int max_align,
9204 rtx (*next_group) (rtx, int *, int *),
9205 rtx (*next_nop) (int *))
9207 /* ALIGN is the known alignment for the insn group. */
9208 unsigned int align;
9209 /* OFS is the offset of the current insn in the insn group. */
9210 int ofs;
9211 int prev_in_use, in_use, len, ldgp;
9212 rtx i, next;
9214 /* Let shorten branches care for assigning alignments to code labels. */
9215 shorten_branches (get_insns ());
9217 if (align_functions < 4)
9218 align = 4;
9219 else if ((unsigned int) align_functions < max_align)
9220 align = align_functions;
9221 else
9222 align = max_align;
9224 ofs = prev_in_use = 0;
9225 i = get_insns ();
9226 if (GET_CODE (i) == NOTE)
9227 i = next_nonnote_insn (i);
9229 ldgp = alpha_function_needs_gp ? 8 : 0;
9231 while (i)
9233 next = (*next_group) (i, &in_use, &len);
9235 /* When we see a label, resync alignment etc. */
9236 if (GET_CODE (i) == CODE_LABEL)
9238 unsigned int new_align = 1 << label_to_alignment (i);
9240 if (new_align >= align)
9242 align = new_align < max_align ? new_align : max_align;
9243 ofs = 0;
9246 else if (ofs & (new_align-1))
9247 ofs = (ofs | (new_align-1)) + 1;
9248 gcc_assert (!len);
9251 /* Handle complex instructions special. */
9252 else if (in_use == 0)
9254 /* Asms will have length < 0. This is a signal that we have
9255 lost alignment knowledge. Assume, however, that the asm
9256 will not mis-align instructions. */
9257 if (len < 0)
9259 ofs = 0;
9260 align = 4;
9261 len = 0;
9265 /* If the known alignment is smaller than the recognized insn group,
9266 realign the output. */
9267 else if ((int) align < len)
9269 unsigned int new_log_align = len > 8 ? 4 : 3;
9270 rtx prev, where;
9272 where = prev = prev_nonnote_insn (i);
9273 if (!where || GET_CODE (where) != CODE_LABEL)
9274 where = i;
9276 /* Can't realign between a call and its gp reload. */
9277 if (! (TARGET_EXPLICIT_RELOCS
9278 && prev && GET_CODE (prev) == CALL_INSN))
9280 emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
9281 align = 1 << new_log_align;
9282 ofs = 0;
9286 /* We may not insert padding inside the initial ldgp sequence. */
9287 else if (ldgp > 0)
9288 ldgp -= len;
9290 /* If the group won't fit in the same INT16 as the previous,
9291 we need to add padding to keep the group together. Rather
9292 than simply leaving the insn filling to the assembler, we
9293 can make use of the knowledge of what sorts of instructions
9294 were issued in the previous group to make sure that all of
9295 the added nops are really free. */
9296 else if (ofs + len > (int) align)
9298 int nop_count = (align - ofs) / 4;
9299 rtx where;
9301 /* Insert nops before labels, branches, and calls to truly merge
9302 the execution of the nops with the previous instruction group. */
9303 where = prev_nonnote_insn (i);
9304 if (where)
9306 if (GET_CODE (where) == CODE_LABEL)
9308 rtx where2 = prev_nonnote_insn (where);
9309 if (where2 && GET_CODE (where2) == JUMP_INSN)
9310 where = where2;
9312 else if (GET_CODE (where) == INSN)
9313 where = i;
9315 else
9316 where = i;
9319 emit_insn_before ((*next_nop)(&prev_in_use), where);
9320 while (--nop_count);
9321 ofs = 0;
9324 ofs = (ofs + len) & (align - 1);
9325 prev_in_use = in_use;
9326 i = next;
9330 /* Insert an unop between a noreturn function call and GP load. */
9332 static void
9333 alpha_pad_noreturn (void)
9335 rtx insn, next;
9337 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
9339 if (!CALL_P (insn)
9340 || !find_reg_note (insn, REG_NORETURN, NULL_RTX))
9341 continue;
9343 next = next_active_insn (insn);
9345 if (next)
9347 rtx pat = PATTERN (next);
9349 if (GET_CODE (pat) == SET
9350 && GET_CODE (SET_SRC (pat)) == UNSPEC_VOLATILE
9351 && XINT (SET_SRC (pat), 1) == UNSPECV_LDGP1)
9352 emit_insn_after (gen_unop (), insn);
9357 /* Machine dependent reorg pass. */
9359 static void
9360 alpha_reorg (void)
9362 /* Workaround for a linker error that triggers when an
9363 exception handler immediatelly follows a noreturn function.
9365 The instruction stream from an object file:
9367 54: 00 40 5b 6b jsr ra,(t12),58 <__func+0x58>
9368 58: 00 00 ba 27 ldah gp,0(ra)
9369 5c: 00 00 bd 23 lda gp,0(gp)
9370 60: 00 00 7d a7 ldq t12,0(gp)
9371 64: 00 40 5b 6b jsr ra,(t12),68 <__func+0x68>
9373 was converted in the final link pass to:
9375 fdb24: a0 03 40 d3 bsr ra,fe9a8 <_called_func+0x8>
9376 fdb28: 00 00 fe 2f unop
9377 fdb2c: 00 00 fe 2f unop
9378 fdb30: 30 82 7d a7 ldq t12,-32208(gp)
9379 fdb34: 00 40 5b 6b jsr ra,(t12),fdb38 <__func+0x68>
9381 GP load instructions were wrongly cleared by the linker relaxation
9382 pass. This workaround prevents removal of GP loads by inserting
9383 an unop instruction between a noreturn function call and
9384 exception handler prologue. */
9386 if (current_function_has_exception_handlers ())
9387 alpha_pad_noreturn ();
9389 if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
9390 alpha_handle_trap_shadows ();
9392 /* Due to the number of extra trapb insns, don't bother fixing up
9393 alignment when trap precision is instruction. Moreover, we can
9394 only do our job when sched2 is run. */
9395 if (optimize && !optimize_size
9396 && alpha_tp != ALPHA_TP_INSN
9397 && flag_schedule_insns_after_reload)
9399 if (alpha_tune == PROCESSOR_EV4)
9400 alpha_align_insns (8, alphaev4_next_group, alphaev4_next_nop);
9401 else if (alpha_tune == PROCESSOR_EV5)
9402 alpha_align_insns (16, alphaev5_next_group, alphaev5_next_nop);
9406 #if !TARGET_ABI_UNICOSMK
9408 #ifdef HAVE_STAMP_H
9409 #include <stamp.h>
9410 #endif
9412 static void
9413 alpha_file_start (void)
9415 #ifdef OBJECT_FORMAT_ELF
9416 /* If emitting dwarf2 debug information, we cannot generate a .file
9417 directive to start the file, as it will conflict with dwarf2out
9418 file numbers. So it's only useful when emitting mdebug output. */
9419 targetm.file_start_file_directive = (write_symbols == DBX_DEBUG);
9420 #endif
9422 default_file_start ();
9423 #ifdef MS_STAMP
9424 fprintf (asm_out_file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
9425 #endif
9427 fputs ("\t.set noreorder\n", asm_out_file);
9428 fputs ("\t.set volatile\n", asm_out_file);
9429 if (!TARGET_ABI_OPEN_VMS)
9430 fputs ("\t.set noat\n", asm_out_file);
9431 if (TARGET_EXPLICIT_RELOCS)
9432 fputs ("\t.set nomacro\n", asm_out_file);
9433 if (TARGET_SUPPORT_ARCH | TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX)
9435 const char *arch;
9437 if (alpha_cpu == PROCESSOR_EV6 || TARGET_FIX || TARGET_CIX)
9438 arch = "ev6";
9439 else if (TARGET_MAX)
9440 arch = "pca56";
9441 else if (TARGET_BWX)
9442 arch = "ev56";
9443 else if (alpha_cpu == PROCESSOR_EV5)
9444 arch = "ev5";
9445 else
9446 arch = "ev4";
9448 fprintf (asm_out_file, "\t.arch %s\n", arch);
9451 #endif
9453 #ifdef OBJECT_FORMAT_ELF
9454 /* Since we don't have a .dynbss section, we should not allow global
9455 relocations in the .rodata section. */
9457 static int
9458 alpha_elf_reloc_rw_mask (void)
9460 return flag_pic ? 3 : 2;
9463 /* Return a section for X. The only special thing we do here is to
9464 honor small data. */
9466 static section *
9467 alpha_elf_select_rtx_section (enum machine_mode mode, rtx x,
9468 unsigned HOST_WIDE_INT align)
9470 if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value)
9471 /* ??? Consider using mergeable sdata sections. */
9472 return sdata_section;
9473 else
9474 return default_elf_select_rtx_section (mode, x, align);
9477 static unsigned int
9478 alpha_elf_section_type_flags (tree decl, const char *name, int reloc)
9480 unsigned int flags = 0;
9482 if (strcmp (name, ".sdata") == 0
9483 || strncmp (name, ".sdata.", 7) == 0
9484 || strncmp (name, ".gnu.linkonce.s.", 16) == 0
9485 || strcmp (name, ".sbss") == 0
9486 || strncmp (name, ".sbss.", 6) == 0
9487 || strncmp (name, ".gnu.linkonce.sb.", 17) == 0)
9488 flags = SECTION_SMALL;
9490 flags |= default_section_type_flags (decl, name, reloc);
9491 return flags;
9493 #endif /* OBJECT_FORMAT_ELF */
9495 /* Structure to collect function names for final output in link section. */
9496 /* Note that items marked with GTY can't be ifdef'ed out. */
9498 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
9499 enum reloc_kind {KIND_LINKAGE, KIND_CODEADDR};
9501 struct alpha_links GTY(())
9503 int num;
9504 rtx linkage;
9505 enum links_kind lkind;
9506 enum reloc_kind rkind;
9509 struct alpha_funcs GTY(())
9511 int num;
9512 splay_tree GTY ((param1_is (char *), param2_is (struct alpha_links *)))
9513 links;
9516 static GTY ((param1_is (char *), param2_is (struct alpha_links *)))
9517 splay_tree alpha_links_tree;
9518 static GTY ((param1_is (tree), param2_is (struct alpha_funcs *)))
9519 splay_tree alpha_funcs_tree;
9521 static GTY(()) int alpha_funcs_num;
9523 #if TARGET_ABI_OPEN_VMS
9525 /* Return the VMS argument type corresponding to MODE. */
9527 enum avms_arg_type
9528 alpha_arg_type (enum machine_mode mode)
9530 switch (mode)
9532 case SFmode:
9533 return TARGET_FLOAT_VAX ? FF : FS;
9534 case DFmode:
9535 return TARGET_FLOAT_VAX ? FD : FT;
9536 default:
9537 return I64;
9541 /* Return an rtx for an integer representing the VMS Argument Information
9542 register value. */
9545 alpha_arg_info_reg_val (CUMULATIVE_ARGS cum)
9547 unsigned HOST_WIDE_INT regval = cum.num_args;
9548 int i;
9550 for (i = 0; i < 6; i++)
9551 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
9553 return GEN_INT (regval);
9556 /* Make (or fake) .linkage entry for function call.
9558 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.
9560 Return an SYMBOL_REF rtx for the linkage. */
9563 alpha_need_linkage (const char *name, int is_local)
9565 splay_tree_node node;
9566 struct alpha_links *al;
9568 if (name[0] == '*')
9569 name++;
9571 if (is_local)
9573 struct alpha_funcs *cfaf;
9575 if (!alpha_funcs_tree)
9576 alpha_funcs_tree = splay_tree_new_ggc ((splay_tree_compare_fn)
9577 splay_tree_compare_pointers);
9579 cfaf = (struct alpha_funcs *) ggc_alloc (sizeof (struct alpha_funcs));
9581 cfaf->links = 0;
9582 cfaf->num = ++alpha_funcs_num;
9584 splay_tree_insert (alpha_funcs_tree,
9585 (splay_tree_key) current_function_decl,
9586 (splay_tree_value) cfaf);
9589 if (alpha_links_tree)
9591 /* Is this name already defined? */
9593 node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
9594 if (node)
9596 al = (struct alpha_links *) node->value;
9597 if (is_local)
9599 /* Defined here but external assumed. */
9600 if (al->lkind == KIND_EXTERN)
9601 al->lkind = KIND_LOCAL;
9603 else
9605 /* Used here but unused assumed. */
9606 if (al->lkind == KIND_UNUSED)
9607 al->lkind = KIND_LOCAL;
9609 return al->linkage;
9612 else
9613 alpha_links_tree = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
9615 al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
9616 name = ggc_strdup (name);
9618 /* Assume external if no definition. */
9619 al->lkind = (is_local ? KIND_UNUSED : KIND_EXTERN);
9621 /* Ensure we have an IDENTIFIER so assemble_name can mark it used. */
9622 get_identifier (name);
9624 /* Construct a SYMBOL_REF for us to call. */
9626 size_t name_len = strlen (name);
9627 char *linksym = XALLOCAVEC (char, name_len + 6);
9628 linksym[0] = '$';
9629 memcpy (linksym + 1, name, name_len);
9630 memcpy (linksym + 1 + name_len, "..lk", 5);
9631 al->linkage = gen_rtx_SYMBOL_REF (Pmode,
9632 ggc_alloc_string (linksym, name_len + 5));
9635 splay_tree_insert (alpha_links_tree, (splay_tree_key) name,
9636 (splay_tree_value) al);
9638 return al->linkage;
9642 alpha_use_linkage (rtx linkage, tree cfundecl, int lflag, int rflag)
9644 splay_tree_node cfunnode;
9645 struct alpha_funcs *cfaf;
9646 struct alpha_links *al;
9647 const char *name = XSTR (linkage, 0);
9649 cfaf = (struct alpha_funcs *) 0;
9650 al = (struct alpha_links *) 0;
9652 cfunnode = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) cfundecl);
9653 cfaf = (struct alpha_funcs *) cfunnode->value;
9655 if (cfaf->links)
9657 splay_tree_node lnode;
9659 /* Is this name already defined? */
9661 lnode = splay_tree_lookup (cfaf->links, (splay_tree_key) name);
9662 if (lnode)
9663 al = (struct alpha_links *) lnode->value;
9665 else
9666 cfaf->links = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
9668 if (!al)
9670 size_t name_len;
9671 size_t buflen;
9672 char buf [512];
9673 char *linksym;
9674 splay_tree_node node = 0;
9675 struct alpha_links *anl;
9677 if (name[0] == '*')
9678 name++;
9680 name_len = strlen (name);
9682 al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
9683 al->num = cfaf->num;
9685 node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
9686 if (node)
9688 anl = (struct alpha_links *) node->value;
9689 al->lkind = anl->lkind;
9692 sprintf (buf, "$%d..%s..lk", cfaf->num, name);
9693 buflen = strlen (buf);
9694 linksym = XALLOCAVEC (char, buflen + 1);
9695 memcpy (linksym, buf, buflen + 1);
9697 al->linkage = gen_rtx_SYMBOL_REF
9698 (Pmode, ggc_alloc_string (linksym, buflen + 1));
9700 splay_tree_insert (cfaf->links, (splay_tree_key) name,
9701 (splay_tree_value) al);
9704 if (rflag)
9705 al->rkind = KIND_CODEADDR;
9706 else
9707 al->rkind = KIND_LINKAGE;
9709 if (lflag)
9710 return gen_rtx_MEM (Pmode, plus_constant (al->linkage, 8));
9711 else
9712 return al->linkage;
9715 static int
9716 alpha_write_one_linkage (splay_tree_node node, void *data)
9718 const char *const name = (const char *) node->key;
9719 struct alpha_links *link = (struct alpha_links *) node->value;
9720 FILE *stream = (FILE *) data;
9722 fprintf (stream, "$%d..%s..lk:\n", link->num, name);
9723 if (link->rkind == KIND_CODEADDR)
9725 if (link->lkind == KIND_LOCAL)
9727 /* Local and used */
9728 fprintf (stream, "\t.quad %s..en\n", name);
9730 else
9732 /* External and used, request code address. */
9733 fprintf (stream, "\t.code_address %s\n", name);
9736 else
9738 if (link->lkind == KIND_LOCAL)
9740 /* Local and used, build linkage pair. */
9741 fprintf (stream, "\t.quad %s..en\n", name);
9742 fprintf (stream, "\t.quad %s\n", name);
9744 else
9746 /* External and used, request linkage pair. */
9747 fprintf (stream, "\t.linkage %s\n", name);
9751 return 0;
9754 static void
9755 alpha_write_linkage (FILE *stream, const char *funname, tree fundecl)
9757 splay_tree_node node;
9758 struct alpha_funcs *func;
9760 fprintf (stream, "\t.link\n");
9761 fprintf (stream, "\t.align 3\n");
9762 in_section = NULL;
9764 node = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) fundecl);
9765 func = (struct alpha_funcs *) node->value;
9767 fputs ("\t.name ", stream);
9768 assemble_name (stream, funname);
9769 fputs ("..na\n", stream);
9770 ASM_OUTPUT_LABEL (stream, funname);
9771 fprintf (stream, "\t.pdesc ");
9772 assemble_name (stream, funname);
9773 fprintf (stream, "..en,%s\n",
9774 alpha_procedure_type == PT_STACK ? "stack"
9775 : alpha_procedure_type == PT_REGISTER ? "reg" : "null");
9777 if (func->links)
9779 splay_tree_foreach (func->links, alpha_write_one_linkage, stream);
9780 /* splay_tree_delete (func->links); */
9784 /* Given a decl, a section name, and whether the decl initializer
9785 has relocs, choose attributes for the section. */
9787 #define SECTION_VMS_OVERLAY SECTION_FORGET
9788 #define SECTION_VMS_GLOBAL SECTION_MACH_DEP
9789 #define SECTION_VMS_INITIALIZE (SECTION_VMS_GLOBAL << 1)
9791 static unsigned int
9792 vms_section_type_flags (tree decl, const char *name, int reloc)
9794 unsigned int flags = default_section_type_flags (decl, name, reloc);
9796 if (decl && DECL_ATTRIBUTES (decl)
9797 && lookup_attribute ("overlaid", DECL_ATTRIBUTES (decl)))
9798 flags |= SECTION_VMS_OVERLAY;
9799 if (decl && DECL_ATTRIBUTES (decl)
9800 && lookup_attribute ("global", DECL_ATTRIBUTES (decl)))
9801 flags |= SECTION_VMS_GLOBAL;
9802 if (decl && DECL_ATTRIBUTES (decl)
9803 && lookup_attribute ("initialize", DECL_ATTRIBUTES (decl)))
9804 flags |= SECTION_VMS_INITIALIZE;
9806 return flags;
9809 /* Switch to an arbitrary section NAME with attributes as specified
9810 by FLAGS. ALIGN specifies any known alignment requirements for
9811 the section; 0 if the default should be used. */
9813 static void
9814 vms_asm_named_section (const char *name, unsigned int flags,
9815 tree decl ATTRIBUTE_UNUSED)
9817 fputc ('\n', asm_out_file);
9818 fprintf (asm_out_file, ".section\t%s", name);
9820 if (flags & SECTION_VMS_OVERLAY)
9821 fprintf (asm_out_file, ",OVR");
9822 if (flags & SECTION_VMS_GLOBAL)
9823 fprintf (asm_out_file, ",GBL");
9824 if (flags & SECTION_VMS_INITIALIZE)
9825 fprintf (asm_out_file, ",NOMOD");
9826 if (flags & SECTION_DEBUG)
9827 fprintf (asm_out_file, ",NOWRT");
9829 fputc ('\n', asm_out_file);
9832 /* Record an element in the table of global constructors. SYMBOL is
9833 a SYMBOL_REF of the function to be called; PRIORITY is a number
9834 between 0 and MAX_INIT_PRIORITY.
9836 Differs from default_ctors_section_asm_out_constructor in that the
9837 width of the .ctors entry is always 64 bits, rather than the 32 bits
9838 used by a normal pointer. */
9840 static void
9841 vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
9843 switch_to_section (ctors_section);
9844 assemble_align (BITS_PER_WORD);
9845 assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
9848 static void
9849 vms_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
9851 switch_to_section (dtors_section);
9852 assemble_align (BITS_PER_WORD);
9853 assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
9855 #else
9858 alpha_need_linkage (const char *name ATTRIBUTE_UNUSED,
9859 int is_local ATTRIBUTE_UNUSED)
9861 return NULL_RTX;
9865 alpha_use_linkage (rtx linkage ATTRIBUTE_UNUSED,
9866 tree cfundecl ATTRIBUTE_UNUSED,
9867 int lflag ATTRIBUTE_UNUSED,
9868 int rflag ATTRIBUTE_UNUSED)
9870 return NULL_RTX;
9873 #endif /* TARGET_ABI_OPEN_VMS */
9875 #if TARGET_ABI_UNICOSMK
9877 /* This evaluates to true if we do not know how to pass TYPE solely in
9878 registers. This is the case for all arguments that do not fit in two
9879 registers. */
9881 static bool
9882 unicosmk_must_pass_in_stack (enum machine_mode mode, const_tree type)
9884 if (type == NULL)
9885 return false;
9887 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
9888 return true;
9889 if (TREE_ADDRESSABLE (type))
9890 return true;
9892 return ALPHA_ARG_SIZE (mode, type, 0) > 2;
9895 /* Define the offset between two registers, one to be eliminated, and the
9896 other its replacement, at the start of a routine. */
9899 unicosmk_initial_elimination_offset (int from, int to)
9901 int fixed_size;
9903 fixed_size = alpha_sa_size();
9904 if (fixed_size != 0)
9905 fixed_size += 48;
9907 if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
9908 return -fixed_size;
9909 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
9910 return 0;
9911 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
9912 return (ALPHA_ROUND (crtl->outgoing_args_size)
9913 + ALPHA_ROUND (get_frame_size()));
9914 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
9915 return (ALPHA_ROUND (fixed_size)
9916 + ALPHA_ROUND (get_frame_size()
9917 + crtl->outgoing_args_size));
9918 else
9919 gcc_unreachable ();
9922 /* Output the module name for .ident and .end directives. We have to strip
9923 directories and add make sure that the module name starts with a letter
9924 or '$'. */
9926 static void
9927 unicosmk_output_module_name (FILE *file)
9929 const char *name = lbasename (main_input_filename);
9930 unsigned len = strlen (name);
9931 char *clean_name = alloca (len + 2);
9932 char *ptr = clean_name;
9934 /* CAM only accepts module names that start with a letter or '$'. We
9935 prefix the module name with a '$' if necessary. */
9937 if (!ISALPHA (*name))
9938 *ptr++ = '$';
9939 memcpy (ptr, name, len + 1);
9940 clean_symbol_name (clean_name);
9941 fputs (clean_name, file);
9944 /* Output the definition of a common variable. */
9946 void
9947 unicosmk_output_common (FILE *file, const char *name, int size, int align)
9949 tree name_tree;
9950 printf ("T3E__: common %s\n", name);
9952 in_section = NULL;
9953 fputs("\t.endp\n\n\t.psect ", file);
9954 assemble_name(file, name);
9955 fprintf(file, ",%d,common\n", floor_log2 (align / BITS_PER_UNIT));
9956 fprintf(file, "\t.byte\t0:%d\n", size);
9958 /* Mark the symbol as defined in this module. */
9959 name_tree = get_identifier (name);
9960 TREE_ASM_WRITTEN (name_tree) = 1;
9963 #define SECTION_PUBLIC SECTION_MACH_DEP
9964 #define SECTION_MAIN (SECTION_PUBLIC << 1)
9965 static int current_section_align;
9967 /* A get_unnamed_section callback for switching to the text section. */
9969 static void
9970 unicosmk_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
9972 static int count = 0;
9973 fprintf (asm_out_file, "\t.endp\n\n\t.psect\tgcc@text___%d,code\n", count++);
9976 /* A get_unnamed_section callback for switching to the data section. */
9978 static void
9979 unicosmk_output_data_section_asm_op (const void *data ATTRIBUTE_UNUSED)
9981 static int count = 1;
9982 fprintf (asm_out_file, "\t.endp\n\n\t.psect\tgcc@data___%d,data\n", count++);
9985 /* Implement TARGET_ASM_INIT_SECTIONS.
9987 The Cray assembler is really weird with respect to sections. It has only
9988 named sections and you can't reopen a section once it has been closed.
9989 This means that we have to generate unique names whenever we want to
9990 reenter the text or the data section. */
9992 static void
9993 unicosmk_init_sections (void)
9995 text_section = get_unnamed_section (SECTION_CODE,
9996 unicosmk_output_text_section_asm_op,
9997 NULL);
9998 data_section = get_unnamed_section (SECTION_WRITE,
9999 unicosmk_output_data_section_asm_op,
10000 NULL);
10001 readonly_data_section = data_section;
10004 static unsigned int
10005 unicosmk_section_type_flags (tree decl, const char *name,
10006 int reloc ATTRIBUTE_UNUSED)
10008 unsigned int flags = default_section_type_flags (decl, name, reloc);
10010 if (!decl)
10011 return flags;
10013 if (TREE_CODE (decl) == FUNCTION_DECL)
10015 current_section_align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
10016 if (align_functions_log > current_section_align)
10017 current_section_align = align_functions_log;
10019 if (! strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), "main"))
10020 flags |= SECTION_MAIN;
10022 else
10023 current_section_align = floor_log2 (DECL_ALIGN (decl) / BITS_PER_UNIT);
10025 if (TREE_PUBLIC (decl))
10026 flags |= SECTION_PUBLIC;
10028 return flags;
10031 /* Generate a section name for decl and associate it with the
10032 declaration. */
10034 static void
10035 unicosmk_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
10037 const char *name;
10038 int len;
10040 gcc_assert (decl);
10042 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
10043 name = default_strip_name_encoding (name);
10044 len = strlen (name);
10046 if (TREE_CODE (decl) == FUNCTION_DECL)
10048 char *string;
10050 /* It is essential that we prefix the section name here because
10051 otherwise the section names generated for constructors and
10052 destructors confuse collect2. */
10054 string = alloca (len + 6);
10055 sprintf (string, "code@%s", name);
10056 DECL_SECTION_NAME (decl) = build_string (len + 5, string);
10058 else if (TREE_PUBLIC (decl))
10059 DECL_SECTION_NAME (decl) = build_string (len, name);
10060 else
10062 char *string;
10064 string = alloca (len + 6);
10065 sprintf (string, "data@%s", name);
10066 DECL_SECTION_NAME (decl) = build_string (len + 5, string);
10070 /* Switch to an arbitrary section NAME with attributes as specified
10071 by FLAGS. ALIGN specifies any known alignment requirements for
10072 the section; 0 if the default should be used. */
10074 static void
10075 unicosmk_asm_named_section (const char *name, unsigned int flags,
10076 tree decl ATTRIBUTE_UNUSED)
10078 const char *kind;
10080 /* Close the previous section. */
10082 fputs ("\t.endp\n\n", asm_out_file);
10084 /* Find out what kind of section we are opening. */
10086 if (flags & SECTION_MAIN)
10087 fputs ("\t.start\tmain\n", asm_out_file);
10089 if (flags & SECTION_CODE)
10090 kind = "code";
10091 else if (flags & SECTION_PUBLIC)
10092 kind = "common";
10093 else
10094 kind = "data";
10096 if (current_section_align != 0)
10097 fprintf (asm_out_file, "\t.psect\t%s,%d,%s\n", name,
10098 current_section_align, kind);
10099 else
10100 fprintf (asm_out_file, "\t.psect\t%s,%s\n", name, kind);
10103 static void
10104 unicosmk_insert_attributes (tree decl, tree *attr_ptr ATTRIBUTE_UNUSED)
10106 if (DECL_P (decl)
10107 && (TREE_PUBLIC (decl) || TREE_CODE (decl) == FUNCTION_DECL))
10108 unicosmk_unique_section (decl, 0);
10111 /* Output an alignment directive. We have to use the macro 'gcc@code@align'
10112 in code sections because .align fill unused space with zeroes. */
10114 void
10115 unicosmk_output_align (FILE *file, int align)
10117 if (inside_function)
10118 fprintf (file, "\tgcc@code@align\t%d\n", align);
10119 else
10120 fprintf (file, "\t.align\t%d\n", align);
10123 /* Add a case vector to the current function's list of deferred case
10124 vectors. Case vectors have to be put into a separate section because CAM
10125 does not allow data definitions in code sections. */
10127 void
10128 unicosmk_defer_case_vector (rtx lab, rtx vec)
10130 struct machine_function *machine = cfun->machine;
10132 vec = gen_rtx_EXPR_LIST (VOIDmode, lab, vec);
10133 machine->addr_list = gen_rtx_EXPR_LIST (VOIDmode, vec,
10134 machine->addr_list);
10137 /* Output a case vector. */
10139 static void
10140 unicosmk_output_addr_vec (FILE *file, rtx vec)
10142 rtx lab = XEXP (vec, 0);
10143 rtx body = XEXP (vec, 1);
10144 int vlen = XVECLEN (body, 0);
10145 int idx;
10147 (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (lab));
10149 for (idx = 0; idx < vlen; idx++)
10151 ASM_OUTPUT_ADDR_VEC_ELT
10152 (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
10156 /* Output current function's deferred case vectors. */
10158 static void
10159 unicosmk_output_deferred_case_vectors (FILE *file)
10161 struct machine_function *machine = cfun->machine;
10162 rtx t;
10164 if (machine->addr_list == NULL_RTX)
10165 return;
10167 switch_to_section (data_section);
10168 for (t = machine->addr_list; t; t = XEXP (t, 1))
10169 unicosmk_output_addr_vec (file, XEXP (t, 0));
10172 /* Generate the name of the SSIB section for the current function. */
10174 #define SSIB_PREFIX "__SSIB_"
10175 #define SSIB_PREFIX_LEN 7
10177 static const char *
10178 unicosmk_ssib_name (void)
10180 /* This is ok since CAM won't be able to deal with names longer than that
10181 anyway. */
10183 static char name[256];
10185 rtx x;
10186 const char *fnname;
10187 int len;
10189 x = DECL_RTL (cfun->decl);
10190 gcc_assert (GET_CODE (x) == MEM);
10191 x = XEXP (x, 0);
10192 gcc_assert (GET_CODE (x) == SYMBOL_REF);
10193 fnname = XSTR (x, 0);
10195 len = strlen (fnname);
10196 if (len + SSIB_PREFIX_LEN > 255)
10197 len = 255 - SSIB_PREFIX_LEN;
10199 strcpy (name, SSIB_PREFIX);
10200 strncpy (name + SSIB_PREFIX_LEN, fnname, len);
10201 name[len + SSIB_PREFIX_LEN] = 0;
10203 return name;
10206 /* Set up the dynamic subprogram information block (DSIB) and update the
10207 frame pointer register ($15) for subroutines which have a frame. If the
10208 subroutine doesn't have a frame, simply increment $15. */
10210 static void
10211 unicosmk_gen_dsib (unsigned long *imaskP)
10213 if (alpha_procedure_type == PT_STACK)
10215 const char *ssib_name;
10216 rtx mem;
10218 /* Allocate 64 bytes for the DSIB. */
10220 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
10221 GEN_INT (-64))));
10222 emit_insn (gen_blockage ());
10224 /* Save the return address. */
10226 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 56));
10227 set_mem_alias_set (mem, alpha_sr_alias_set);
10228 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
10229 (*imaskP) &= ~(1UL << REG_RA);
10231 /* Save the old frame pointer. */
10233 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 48));
10234 set_mem_alias_set (mem, alpha_sr_alias_set);
10235 FRP (emit_move_insn (mem, hard_frame_pointer_rtx));
10236 (*imaskP) &= ~(1UL << HARD_FRAME_POINTER_REGNUM);
10238 emit_insn (gen_blockage ());
10240 /* Store the SSIB pointer. */
10242 ssib_name = ggc_strdup (unicosmk_ssib_name ());
10243 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 32));
10244 set_mem_alias_set (mem, alpha_sr_alias_set);
10246 FRP (emit_move_insn (gen_rtx_REG (DImode, 5),
10247 gen_rtx_SYMBOL_REF (Pmode, ssib_name)));
10248 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 5)));
10250 /* Save the CIW index. */
10252 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 24));
10253 set_mem_alias_set (mem, alpha_sr_alias_set);
10254 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 25)));
10256 emit_insn (gen_blockage ());
10258 /* Set the new frame pointer. */
10260 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
10261 stack_pointer_rtx, GEN_INT (64))));
10264 else
10266 /* Increment the frame pointer register to indicate that we do not
10267 have a frame. */
10269 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
10270 hard_frame_pointer_rtx, const1_rtx)));
10274 /* Output the static subroutine information block for the current
10275 function. */
10277 static void
10278 unicosmk_output_ssib (FILE *file, const char *fnname)
10280 int len;
10281 int i;
10282 rtx x;
10283 rtx ciw;
10284 struct machine_function *machine = cfun->machine;
10286 in_section = NULL;
10287 fprintf (file, "\t.endp\n\n\t.psect\t%s%s,data\n", user_label_prefix,
10288 unicosmk_ssib_name ());
10290 /* Some required stuff and the function name length. */
10292 len = strlen (fnname);
10293 fprintf (file, "\t.quad\t^X20008%2.2X28\n", len);
10295 /* Saved registers
10296 ??? We don't do that yet. */
10298 fputs ("\t.quad\t0\n", file);
10300 /* Function address. */
10302 fputs ("\t.quad\t", file);
10303 assemble_name (file, fnname);
10304 putc ('\n', file);
10306 fputs ("\t.quad\t0\n", file);
10307 fputs ("\t.quad\t0\n", file);
10309 /* Function name.
10310 ??? We do it the same way Cray CC does it but this could be
10311 simplified. */
10313 for( i = 0; i < len; i++ )
10314 fprintf (file, "\t.byte\t%d\n", (int)(fnname[i]));
10315 if( (len % 8) == 0 )
10316 fputs ("\t.quad\t0\n", file);
10317 else
10318 fprintf (file, "\t.bits\t%d : 0\n", (8 - (len % 8))*8);
10320 /* All call information words used in the function. */
10322 for (x = machine->first_ciw; x; x = XEXP (x, 1))
10324 ciw = XEXP (x, 0);
10325 #if HOST_BITS_PER_WIDE_INT == 32
10326 fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_DOUBLE_HEX "\n",
10327 CONST_DOUBLE_HIGH (ciw), CONST_DOUBLE_LOW (ciw));
10328 #else
10329 fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n", INTVAL (ciw));
10330 #endif
10334 /* Add a call information word (CIW) to the list of the current function's
10335 CIWs and return its index.
10337 X is a CONST_INT or CONST_DOUBLE representing the CIW. */
10340 unicosmk_add_call_info_word (rtx x)
10342 rtx node;
10343 struct machine_function *machine = cfun->machine;
10345 node = gen_rtx_EXPR_LIST (VOIDmode, x, NULL_RTX);
10346 if (machine->first_ciw == NULL_RTX)
10347 machine->first_ciw = node;
10348 else
10349 XEXP (machine->last_ciw, 1) = node;
10351 machine->last_ciw = node;
10352 ++machine->ciw_count;
10354 return GEN_INT (machine->ciw_count
10355 + strlen (current_function_name ())/8 + 5);
10358 /* The Cray assembler doesn't accept extern declarations for symbols which
10359 are defined in the same file. We have to keep track of all global
10360 symbols which are referenced and/or defined in a source file and output
10361 extern declarations for those which are referenced but not defined at
10362 the end of file. */
10364 /* List of identifiers for which an extern declaration might have to be
10365 emitted. */
10366 /* FIXME: needs to use GC, so it can be saved and restored for PCH. */
10368 struct unicosmk_extern_list
10370 struct unicosmk_extern_list *next;
10371 const char *name;
10374 static struct unicosmk_extern_list *unicosmk_extern_head = 0;
10376 /* Output extern declarations which are required for every asm file. */
10378 static void
10379 unicosmk_output_default_externs (FILE *file)
10381 static const char *const externs[] =
10382 { "__T3E_MISMATCH" };
10384 int i;
10385 int n;
10387 n = ARRAY_SIZE (externs);
10389 for (i = 0; i < n; i++)
10390 fprintf (file, "\t.extern\t%s\n", externs[i]);
10393 /* Output extern declarations for global symbols which are have been
10394 referenced but not defined. */
10396 static void
10397 unicosmk_output_externs (FILE *file)
10399 struct unicosmk_extern_list *p;
10400 const char *real_name;
10401 int len;
10402 tree name_tree;
10404 len = strlen (user_label_prefix);
10405 for (p = unicosmk_extern_head; p != 0; p = p->next)
10407 /* We have to strip the encoding and possibly remove user_label_prefix
10408 from the identifier in order to handle -fleading-underscore and
10409 explicit asm names correctly (cf. gcc.dg/asm-names-1.c). */
10410 real_name = default_strip_name_encoding (p->name);
10411 if (len && p->name[0] == '*'
10412 && !memcmp (real_name, user_label_prefix, len))
10413 real_name += len;
10415 name_tree = get_identifier (real_name);
10416 if (! TREE_ASM_WRITTEN (name_tree))
10418 TREE_ASM_WRITTEN (name_tree) = 1;
10419 fputs ("\t.extern\t", file);
10420 assemble_name (file, p->name);
10421 putc ('\n', file);
10426 /* Record an extern. */
10428 void
10429 unicosmk_add_extern (const char *name)
10431 struct unicosmk_extern_list *p;
10433 p = (struct unicosmk_extern_list *)
10434 xmalloc (sizeof (struct unicosmk_extern_list));
10435 p->next = unicosmk_extern_head;
10436 p->name = name;
10437 unicosmk_extern_head = p;
10440 /* The Cray assembler generates incorrect code if identifiers which
10441 conflict with register names are used as instruction operands. We have
10442 to replace such identifiers with DEX expressions. */
10444 /* Structure to collect identifiers which have been replaced by DEX
10445 expressions. */
10446 /* FIXME: needs to use GC, so it can be saved and restored for PCH. */
10448 struct unicosmk_dex {
10449 struct unicosmk_dex *next;
10450 const char *name;
10453 /* List of identifiers which have been replaced by DEX expressions. The DEX
10454 number is determined by the position in the list. */
10456 static struct unicosmk_dex *unicosmk_dex_list = NULL;
10458 /* The number of elements in the DEX list. */
10460 static int unicosmk_dex_count = 0;
10462 /* Check if NAME must be replaced by a DEX expression. */
10464 static int
10465 unicosmk_special_name (const char *name)
10467 if (name[0] == '*')
10468 ++name;
10470 if (name[0] == '$')
10471 ++name;
10473 if (name[0] != 'r' && name[0] != 'f' && name[0] != 'R' && name[0] != 'F')
10474 return 0;
10476 switch (name[1])
10478 case '1': case '2':
10479 return (name[2] == '\0' || (ISDIGIT (name[2]) && name[3] == '\0'));
10481 case '3':
10482 return (name[2] == '\0'
10483 || ((name[2] == '0' || name[2] == '1') && name[3] == '\0'));
10485 default:
10486 return (ISDIGIT (name[1]) && name[2] == '\0');
10490 /* Return the DEX number if X must be replaced by a DEX expression and 0
10491 otherwise. */
10493 static int
10494 unicosmk_need_dex (rtx x)
10496 struct unicosmk_dex *dex;
10497 const char *name;
10498 int i;
10500 if (GET_CODE (x) != SYMBOL_REF)
10501 return 0;
10503 name = XSTR (x,0);
10504 if (! unicosmk_special_name (name))
10505 return 0;
10507 i = unicosmk_dex_count;
10508 for (dex = unicosmk_dex_list; dex; dex = dex->next)
10510 if (! strcmp (name, dex->name))
10511 return i;
10512 --i;
10515 dex = (struct unicosmk_dex *) xmalloc (sizeof (struct unicosmk_dex));
10516 dex->name = name;
10517 dex->next = unicosmk_dex_list;
10518 unicosmk_dex_list = dex;
10520 ++unicosmk_dex_count;
10521 return unicosmk_dex_count;
10524 /* Output the DEX definitions for this file. */
10526 static void
10527 unicosmk_output_dex (FILE *file)
10529 struct unicosmk_dex *dex;
10530 int i;
10532 if (unicosmk_dex_list == NULL)
10533 return;
10535 fprintf (file, "\t.dexstart\n");
10537 i = unicosmk_dex_count;
10538 for (dex = unicosmk_dex_list; dex; dex = dex->next)
10540 fprintf (file, "\tDEX (%d) = ", i);
10541 assemble_name (file, dex->name);
10542 putc ('\n', file);
10543 --i;
10546 fprintf (file, "\t.dexend\n");
10549 /* Output text that to appear at the beginning of an assembler file. */
10551 static void
10552 unicosmk_file_start (void)
10554 int i;
10556 fputs ("\t.ident\t", asm_out_file);
10557 unicosmk_output_module_name (asm_out_file);
10558 fputs ("\n\n", asm_out_file);
10560 /* The Unicos/Mk assembler uses different register names. Instead of trying
10561 to support them, we simply use micro definitions. */
10563 /* CAM has different register names: rN for the integer register N and fN
10564 for the floating-point register N. Instead of trying to use these in
10565 alpha.md, we define the symbols $N and $fN to refer to the appropriate
10566 register. */
10568 for (i = 0; i < 32; ++i)
10569 fprintf (asm_out_file, "$%d <- r%d\n", i, i);
10571 for (i = 0; i < 32; ++i)
10572 fprintf (asm_out_file, "$f%d <- f%d\n", i, i);
10574 putc ('\n', asm_out_file);
10576 /* The .align directive fill unused space with zeroes which does not work
10577 in code sections. We define the macro 'gcc@code@align' which uses nops
10578 instead. Note that it assumes that code sections always have the
10579 biggest possible alignment since . refers to the current offset from
10580 the beginning of the section. */
10582 fputs ("\t.macro gcc@code@align n\n", asm_out_file);
10583 fputs ("gcc@n@bytes = 1 << n\n", asm_out_file);
10584 fputs ("gcc@here = . % gcc@n@bytes\n", asm_out_file);
10585 fputs ("\t.if ne, gcc@here, 0\n", asm_out_file);
10586 fputs ("\t.repeat (gcc@n@bytes - gcc@here) / 4\n", asm_out_file);
10587 fputs ("\tbis r31,r31,r31\n", asm_out_file);
10588 fputs ("\t.endr\n", asm_out_file);
10589 fputs ("\t.endif\n", asm_out_file);
10590 fputs ("\t.endm gcc@code@align\n\n", asm_out_file);
10592 /* Output extern declarations which should always be visible. */
10593 unicosmk_output_default_externs (asm_out_file);
10595 /* Open a dummy section. We always need to be inside a section for the
10596 section-switching code to work correctly.
10597 ??? This should be a module id or something like that. I still have to
10598 figure out what the rules for those are. */
10599 fputs ("\n\t.psect\t$SG00000,data\n", asm_out_file);
10602 /* Output text to appear at the end of an assembler file. This includes all
10603 pending extern declarations and DEX expressions. */
10605 static void
10606 unicosmk_file_end (void)
10608 fputs ("\t.endp\n\n", asm_out_file);
10610 /* Output all pending externs. */
10612 unicosmk_output_externs (asm_out_file);
10614 /* Output dex definitions used for functions whose names conflict with
10615 register names. */
10617 unicosmk_output_dex (asm_out_file);
10619 fputs ("\t.end\t", asm_out_file);
10620 unicosmk_output_module_name (asm_out_file);
10621 putc ('\n', asm_out_file);
10624 #else
10626 static void
10627 unicosmk_output_deferred_case_vectors (FILE *file ATTRIBUTE_UNUSED)
10630 static void
10631 unicosmk_gen_dsib (unsigned long *imaskP ATTRIBUTE_UNUSED)
10634 static void
10635 unicosmk_output_ssib (FILE * file ATTRIBUTE_UNUSED,
10636 const char * fnname ATTRIBUTE_UNUSED)
10640 unicosmk_add_call_info_word (rtx x ATTRIBUTE_UNUSED)
10642 return NULL_RTX;
10645 static int
10646 unicosmk_need_dex (rtx x ATTRIBUTE_UNUSED)
10648 return 0;
10651 #endif /* TARGET_ABI_UNICOSMK */
10653 static void
10654 alpha_init_libfuncs (void)
10656 if (TARGET_ABI_UNICOSMK)
10658 /* Prevent gcc from generating calls to __divsi3. */
10659 set_optab_libfunc (sdiv_optab, SImode, 0);
10660 set_optab_libfunc (udiv_optab, SImode, 0);
10662 /* Use the functions provided by the system library
10663 for DImode integer division. */
10664 set_optab_libfunc (sdiv_optab, DImode, "$sldiv");
10665 set_optab_libfunc (udiv_optab, DImode, "$uldiv");
10667 else if (TARGET_ABI_OPEN_VMS)
10669 /* Use the VMS runtime library functions for division and
10670 remainder. */
10671 set_optab_libfunc (sdiv_optab, SImode, "OTS$DIV_I");
10672 set_optab_libfunc (sdiv_optab, DImode, "OTS$DIV_L");
10673 set_optab_libfunc (udiv_optab, SImode, "OTS$DIV_UI");
10674 set_optab_libfunc (udiv_optab, DImode, "OTS$DIV_UL");
10675 set_optab_libfunc (smod_optab, SImode, "OTS$REM_I");
10676 set_optab_libfunc (smod_optab, DImode, "OTS$REM_L");
10677 set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI");
10678 set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL");
10683 /* Initialize the GCC target structure. */
10684 #if TARGET_ABI_OPEN_VMS
10685 # undef TARGET_ATTRIBUTE_TABLE
10686 # define TARGET_ATTRIBUTE_TABLE vms_attribute_table
10687 # undef TARGET_SECTION_TYPE_FLAGS
10688 # define TARGET_SECTION_TYPE_FLAGS vms_section_type_flags
10689 #endif
10691 #undef TARGET_IN_SMALL_DATA_P
10692 #define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p
10694 #if TARGET_ABI_UNICOSMK
10695 # undef TARGET_INSERT_ATTRIBUTES
10696 # define TARGET_INSERT_ATTRIBUTES unicosmk_insert_attributes
10697 # undef TARGET_SECTION_TYPE_FLAGS
10698 # define TARGET_SECTION_TYPE_FLAGS unicosmk_section_type_flags
10699 # undef TARGET_ASM_UNIQUE_SECTION
10700 # define TARGET_ASM_UNIQUE_SECTION unicosmk_unique_section
10701 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
10702 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
10703 # undef TARGET_ASM_GLOBALIZE_LABEL
10704 # define TARGET_ASM_GLOBALIZE_LABEL hook_void_FILEptr_constcharptr
10705 # undef TARGET_MUST_PASS_IN_STACK
10706 # define TARGET_MUST_PASS_IN_STACK unicosmk_must_pass_in_stack
10707 #endif
10709 #undef TARGET_ASM_ALIGNED_HI_OP
10710 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
10711 #undef TARGET_ASM_ALIGNED_DI_OP
10712 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
10714 /* Default unaligned ops are provided for ELF systems. To get unaligned
10715 data for non-ELF systems, we have to turn off auto alignment. */
10716 #ifndef OBJECT_FORMAT_ELF
10717 #undef TARGET_ASM_UNALIGNED_HI_OP
10718 #define TARGET_ASM_UNALIGNED_HI_OP "\t.align 0\n\t.word\t"
10719 #undef TARGET_ASM_UNALIGNED_SI_OP
10720 #define TARGET_ASM_UNALIGNED_SI_OP "\t.align 0\n\t.long\t"
10721 #undef TARGET_ASM_UNALIGNED_DI_OP
10722 #define TARGET_ASM_UNALIGNED_DI_OP "\t.align 0\n\t.quad\t"
10723 #endif
10725 #ifdef OBJECT_FORMAT_ELF
10726 #undef TARGET_ASM_RELOC_RW_MASK
10727 #define TARGET_ASM_RELOC_RW_MASK alpha_elf_reloc_rw_mask
10728 #undef TARGET_ASM_SELECT_RTX_SECTION
10729 #define TARGET_ASM_SELECT_RTX_SECTION alpha_elf_select_rtx_section
10730 #undef TARGET_SECTION_TYPE_FLAGS
10731 #define TARGET_SECTION_TYPE_FLAGS alpha_elf_section_type_flags
10732 #endif
10734 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
10735 #define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
10737 #undef TARGET_INIT_LIBFUNCS
10738 #define TARGET_INIT_LIBFUNCS alpha_init_libfuncs
10740 #if TARGET_ABI_UNICOSMK
10741 #undef TARGET_ASM_FILE_START
10742 #define TARGET_ASM_FILE_START unicosmk_file_start
10743 #undef TARGET_ASM_FILE_END
10744 #define TARGET_ASM_FILE_END unicosmk_file_end
10745 #else
10746 #undef TARGET_ASM_FILE_START
10747 #define TARGET_ASM_FILE_START alpha_file_start
10748 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
10749 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
10750 #endif
10752 #undef TARGET_SCHED_ADJUST_COST
10753 #define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
10754 #undef TARGET_SCHED_ISSUE_RATE
10755 #define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
10756 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
10757 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
10758 alpha_multipass_dfa_lookahead
10760 #undef TARGET_HAVE_TLS
10761 #define TARGET_HAVE_TLS HAVE_AS_TLS
10763 #undef TARGET_INIT_BUILTINS
10764 #define TARGET_INIT_BUILTINS alpha_init_builtins
10765 #undef TARGET_EXPAND_BUILTIN
10766 #define TARGET_EXPAND_BUILTIN alpha_expand_builtin
10767 #undef TARGET_FOLD_BUILTIN
10768 #define TARGET_FOLD_BUILTIN alpha_fold_builtin
10770 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
10771 #define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall
10772 #undef TARGET_CANNOT_COPY_INSN_P
10773 #define TARGET_CANNOT_COPY_INSN_P alpha_cannot_copy_insn_p
10774 #undef TARGET_CANNOT_FORCE_CONST_MEM
10775 #define TARGET_CANNOT_FORCE_CONST_MEM alpha_cannot_force_const_mem
10777 #if TARGET_ABI_OSF
10778 #undef TARGET_ASM_OUTPUT_MI_THUNK
10779 #define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
10780 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
10781 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
10782 #undef TARGET_STDARG_OPTIMIZE_HOOK
10783 #define TARGET_STDARG_OPTIMIZE_HOOK alpha_stdarg_optimize_hook
10784 #endif
10786 #undef TARGET_RTX_COSTS
10787 #define TARGET_RTX_COSTS alpha_rtx_costs
10788 #undef TARGET_ADDRESS_COST
10789 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
10791 #undef TARGET_MACHINE_DEPENDENT_REORG
10792 #define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg
10794 #undef TARGET_PROMOTE_FUNCTION_ARGS
10795 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
10796 #undef TARGET_PROMOTE_FUNCTION_RETURN
10797 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
10798 #undef TARGET_PROMOTE_PROTOTYPES
10799 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_false
10800 #undef TARGET_RETURN_IN_MEMORY
10801 #define TARGET_RETURN_IN_MEMORY alpha_return_in_memory
10802 #undef TARGET_PASS_BY_REFERENCE
10803 #define TARGET_PASS_BY_REFERENCE alpha_pass_by_reference
10804 #undef TARGET_SETUP_INCOMING_VARARGS
10805 #define TARGET_SETUP_INCOMING_VARARGS alpha_setup_incoming_varargs
10806 #undef TARGET_STRICT_ARGUMENT_NAMING
10807 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
10808 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
10809 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
10810 #undef TARGET_SPLIT_COMPLEX_ARG
10811 #define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg
10812 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
10813 #define TARGET_GIMPLIFY_VA_ARG_EXPR alpha_gimplify_va_arg
10814 #undef TARGET_ARG_PARTIAL_BYTES
10815 #define TARGET_ARG_PARTIAL_BYTES alpha_arg_partial_bytes
10817 #undef TARGET_SECONDARY_RELOAD
10818 #define TARGET_SECONDARY_RELOAD alpha_secondary_reload
10820 #undef TARGET_SCALAR_MODE_SUPPORTED_P
10821 #define TARGET_SCALAR_MODE_SUPPORTED_P alpha_scalar_mode_supported_p
10822 #undef TARGET_VECTOR_MODE_SUPPORTED_P
10823 #define TARGET_VECTOR_MODE_SUPPORTED_P alpha_vector_mode_supported_p
10825 #undef TARGET_BUILD_BUILTIN_VA_LIST
10826 #define TARGET_BUILD_BUILTIN_VA_LIST alpha_build_builtin_va_list
10828 #undef TARGET_EXPAND_BUILTIN_VA_START
10829 #define TARGET_EXPAND_BUILTIN_VA_START alpha_va_start
10831 /* The Alpha architecture does not require sequential consistency. See
10832 http://www.cs.umd.edu/~pugh/java/memoryModel/AlphaReordering.html
10833 for an example of how it can be violated in practice. */
10834 #undef TARGET_RELAXED_ORDERING
10835 #define TARGET_RELAXED_ORDERING true
10837 #undef TARGET_DEFAULT_TARGET_FLAGS
10838 #define TARGET_DEFAULT_TARGET_FLAGS \
10839 (TARGET_DEFAULT | TARGET_CPU_DEFAULT | TARGET_DEFAULT_EXPLICIT_RELOCS)
10840 #undef TARGET_HANDLE_OPTION
10841 #define TARGET_HANDLE_OPTION alpha_handle_option
10843 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
10844 #undef TARGET_MANGLE_TYPE
10845 #define TARGET_MANGLE_TYPE alpha_mangle_type
10846 #endif
10848 struct gcc_target targetm = TARGET_INITIALIZER;
10851 #include "gt-alpha.h"