1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
26 #include "coretypes.h"
31 #include "hard-reg-set.h"
33 #include "insn-config.h"
34 #include "conditions.h"
36 #include "insn-attr.h"
47 #include "integrate.h"
50 #include "target-def.h"
52 #include "langhooks.h"
53 #include <splay-tree.h>
54 #include "cfglayout.h"
55 #include "tree-gimple.h"
57 /* Specify which cpu to schedule for. */
58 enum processor_type alpha_tune;
60 /* Which cpu we're generating code for. */
61 enum processor_type alpha_cpu;
63 static const char * const alpha_cpu_name[] =
68 /* Specify how accurate floating-point traps need to be. */
70 enum alpha_trap_precision alpha_tp;
72 /* Specify the floating-point rounding mode. */
74 enum alpha_fp_rounding_mode alpha_fprm;
76 /* Specify which things cause traps. */
78 enum alpha_fp_trap_mode alpha_fptm;
80 /* Specify bit size of immediate TLS offsets. */
82 int alpha_tls_size = 32;
84 /* Strings decoded into the above options. */
86 static const char *alpha_cpu_string; /* -mcpu= */
87 static const char *alpha_tune_string; /* -mtune= */
88 static const char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
89 static const char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
90 static const char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
91 static const char *alpha_mlat_string; /* -mmemory-latency= */
93 /* Save information from a "cmpxx" operation until the branch or scc is
96 struct alpha_compare alpha_compare;
98 /* Nonzero if inside of a function, because the Alpha asm can't
99 handle .files inside of functions. */
101 static int inside_function = FALSE;
103 /* The number of cycles of latency we should assume on memory reads. */
105 int alpha_memory_latency = 3;
107 /* Whether the function needs the GP. */
109 static int alpha_function_needs_gp;
111 /* The alias set for prologue/epilogue register save/restore. */
113 static GTY(()) int alpha_sr_alias_set;
115 /* The assembler name of the current function. */
117 static const char *alpha_fnname;
119 /* The next explicit relocation sequence number. */
120 extern GTY(()) int alpha_next_sequence_number;
121 int alpha_next_sequence_number = 1;
123 /* The literal and gpdisp sequence numbers for this insn, as printed
124 by %# and %* respectively. */
125 extern GTY(()) int alpha_this_literal_sequence_number;
126 extern GTY(()) int alpha_this_gpdisp_sequence_number;
127 int alpha_this_literal_sequence_number;
128 int alpha_this_gpdisp_sequence_number;
130 /* Costs of various operations on the different architectures. */
132 struct alpha_rtx_cost_data
134 unsigned char fp_add;
135 unsigned char fp_mult;
136 unsigned char fp_div_sf;
137 unsigned char fp_div_df;
138 unsigned char int_mult_si;
139 unsigned char int_mult_di;
140 unsigned char int_shift;
141 unsigned char int_cmov;
142 unsigned short int_div;
145 static struct alpha_rtx_cost_data const alpha_rtx_cost_data[PROCESSOR_MAX] =
148 COSTS_N_INSNS (6), /* fp_add */
149 COSTS_N_INSNS (6), /* fp_mult */
150 COSTS_N_INSNS (34), /* fp_div_sf */
151 COSTS_N_INSNS (63), /* fp_div_df */
152 COSTS_N_INSNS (23), /* int_mult_si */
153 COSTS_N_INSNS (23), /* int_mult_di */
154 COSTS_N_INSNS (2), /* int_shift */
155 COSTS_N_INSNS (2), /* int_cmov */
156 COSTS_N_INSNS (97), /* int_div */
159 COSTS_N_INSNS (4), /* fp_add */
160 COSTS_N_INSNS (4), /* fp_mult */
161 COSTS_N_INSNS (15), /* fp_div_sf */
162 COSTS_N_INSNS (22), /* fp_div_df */
163 COSTS_N_INSNS (8), /* int_mult_si */
164 COSTS_N_INSNS (12), /* int_mult_di */
165 COSTS_N_INSNS (1) + 1, /* int_shift */
166 COSTS_N_INSNS (1), /* int_cmov */
167 COSTS_N_INSNS (83), /* int_div */
170 COSTS_N_INSNS (4), /* fp_add */
171 COSTS_N_INSNS (4), /* fp_mult */
172 COSTS_N_INSNS (12), /* fp_div_sf */
173 COSTS_N_INSNS (15), /* fp_div_df */
174 COSTS_N_INSNS (7), /* int_mult_si */
175 COSTS_N_INSNS (7), /* int_mult_di */
176 COSTS_N_INSNS (1), /* int_shift */
177 COSTS_N_INSNS (2), /* int_cmov */
178 COSTS_N_INSNS (86), /* int_div */
182 /* Similar but tuned for code size instead of execution latency. The
183 extra +N is fractional cost tuning based on latency. It's used to
184 encourage use of cheaper insns like shift, but only if there's just
187 static struct alpha_rtx_cost_data const alpha_rtx_cost_size =
189 COSTS_N_INSNS (1), /* fp_add */
190 COSTS_N_INSNS (1), /* fp_mult */
191 COSTS_N_INSNS (1), /* fp_div_sf */
192 COSTS_N_INSNS (1) + 1, /* fp_div_df */
193 COSTS_N_INSNS (1) + 1, /* int_mult_si */
194 COSTS_N_INSNS (1) + 2, /* int_mult_di */
195 COSTS_N_INSNS (1), /* int_shift */
196 COSTS_N_INSNS (1), /* int_cmov */
197 COSTS_N_INSNS (6), /* int_div */
200 /* Get the number of args of a function in one of two ways. */
201 #if TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK
202 #define NUM_ARGS current_function_args_info.num_args
204 #define NUM_ARGS current_function_args_info
210 /* Declarations of static functions. */
211 static struct machine_function *alpha_init_machine_status (void);
212 static rtx alpha_emit_xfloating_compare (enum rtx_code, rtx, rtx);
214 #if TARGET_ABI_OPEN_VMS
215 static void alpha_write_linkage (FILE *, const char *, tree);
218 static void unicosmk_output_deferred_case_vectors (FILE *);
219 static void unicosmk_gen_dsib (unsigned long *);
220 static void unicosmk_output_ssib (FILE *, const char *);
221 static int unicosmk_need_dex (rtx);
223 /* Implement TARGET_HANDLE_OPTION. */
226 alpha_handle_option (size_t code, const char *arg, int value)
232 target_flags |= MASK_SOFT_FP;
236 case OPT_mieee_with_inexact:
237 target_flags |= MASK_IEEE_CONFORMANT;
241 alpha_cpu_string = arg;
245 alpha_tune_string = arg;
248 case OPT_mfp_rounding_mode_:
249 alpha_fprm_string = arg;
252 case OPT_mfp_trap_mode_:
253 alpha_fptm_string = arg;
256 case OPT_mtrap_precision_:
257 alpha_tp_string = arg;
260 case OPT_mmemory_latency_:
261 alpha_mlat_string = arg;
265 if (strcmp (arg, "16") == 0)
267 else if (strcmp (arg, "32") == 0)
269 else if (strcmp (arg, "64") == 0)
272 error ("bad value %qs for -mtls-size switch", arg);
279 /* Parse target option strings. */
282 override_options (void)
284 static const struct cpu_table {
285 const char *const name;
286 const enum processor_type processor;
289 { "ev4", PROCESSOR_EV4, 0 },
290 { "ev45", PROCESSOR_EV4, 0 },
291 { "21064", PROCESSOR_EV4, 0 },
292 { "ev5", PROCESSOR_EV5, 0 },
293 { "21164", PROCESSOR_EV5, 0 },
294 { "ev56", PROCESSOR_EV5, MASK_BWX },
295 { "21164a", PROCESSOR_EV5, MASK_BWX },
296 { "pca56", PROCESSOR_EV5, MASK_BWX|MASK_MAX },
297 { "21164PC",PROCESSOR_EV5, MASK_BWX|MASK_MAX },
298 { "21164pc",PROCESSOR_EV5, MASK_BWX|MASK_MAX },
299 { "ev6", PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX },
300 { "21264", PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX },
301 { "ev67", PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX|MASK_CIX },
302 { "21264a", PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX|MASK_CIX },
308 /* Unicos/Mk doesn't have shared libraries. */
309 if (TARGET_ABI_UNICOSMK && flag_pic)
311 warning ("-f%s ignored for Unicos/Mk (not supported)",
312 (flag_pic > 1) ? "PIC" : "pic");
316 /* On Unicos/Mk, the native compiler consistently generates /d suffices for
317 floating-point instructions. Make that the default for this target. */
318 if (TARGET_ABI_UNICOSMK)
319 alpha_fprm = ALPHA_FPRM_DYN;
321 alpha_fprm = ALPHA_FPRM_NORM;
323 alpha_tp = ALPHA_TP_PROG;
324 alpha_fptm = ALPHA_FPTM_N;
326 /* We cannot use su and sui qualifiers for conversion instructions on
327 Unicos/Mk. I'm not sure if this is due to assembler or hardware
328 limitations. Right now, we issue a warning if -mieee is specified
329 and then ignore it; eventually, we should either get it right or
330 disable the option altogether. */
334 if (TARGET_ABI_UNICOSMK)
335 warning ("-mieee not supported on Unicos/Mk");
338 alpha_tp = ALPHA_TP_INSN;
339 alpha_fptm = ALPHA_FPTM_SU;
343 if (TARGET_IEEE_WITH_INEXACT)
345 if (TARGET_ABI_UNICOSMK)
346 warning ("-mieee-with-inexact not supported on Unicos/Mk");
349 alpha_tp = ALPHA_TP_INSN;
350 alpha_fptm = ALPHA_FPTM_SUI;
356 if (! strcmp (alpha_tp_string, "p"))
357 alpha_tp = ALPHA_TP_PROG;
358 else if (! strcmp (alpha_tp_string, "f"))
359 alpha_tp = ALPHA_TP_FUNC;
360 else if (! strcmp (alpha_tp_string, "i"))
361 alpha_tp = ALPHA_TP_INSN;
363 error ("bad value %qs for -mtrap-precision switch", alpha_tp_string);
366 if (alpha_fprm_string)
368 if (! strcmp (alpha_fprm_string, "n"))
369 alpha_fprm = ALPHA_FPRM_NORM;
370 else if (! strcmp (alpha_fprm_string, "m"))
371 alpha_fprm = ALPHA_FPRM_MINF;
372 else if (! strcmp (alpha_fprm_string, "c"))
373 alpha_fprm = ALPHA_FPRM_CHOP;
374 else if (! strcmp (alpha_fprm_string,"d"))
375 alpha_fprm = ALPHA_FPRM_DYN;
377 error ("bad value %qs for -mfp-rounding-mode switch",
381 if (alpha_fptm_string)
383 if (strcmp (alpha_fptm_string, "n") == 0)
384 alpha_fptm = ALPHA_FPTM_N;
385 else if (strcmp (alpha_fptm_string, "u") == 0)
386 alpha_fptm = ALPHA_FPTM_U;
387 else if (strcmp (alpha_fptm_string, "su") == 0)
388 alpha_fptm = ALPHA_FPTM_SU;
389 else if (strcmp (alpha_fptm_string, "sui") == 0)
390 alpha_fptm = ALPHA_FPTM_SUI;
392 error ("bad value %qs for -mfp-trap-mode switch", alpha_fptm_string);
395 if (alpha_cpu_string)
397 for (i = 0; cpu_table [i].name; i++)
398 if (! strcmp (alpha_cpu_string, cpu_table [i].name))
400 alpha_tune = alpha_cpu = cpu_table [i].processor;
401 target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX);
402 target_flags |= cpu_table [i].flags;
405 if (! cpu_table [i].name)
406 error ("bad value %qs for -mcpu switch", alpha_cpu_string);
409 if (alpha_tune_string)
411 for (i = 0; cpu_table [i].name; i++)
412 if (! strcmp (alpha_tune_string, cpu_table [i].name))
414 alpha_tune = cpu_table [i].processor;
417 if (! cpu_table [i].name)
418 error ("bad value %qs for -mcpu switch", alpha_tune_string);
421 /* Do some sanity checks on the above options. */
423 if (TARGET_ABI_UNICOSMK && alpha_fptm != ALPHA_FPTM_N)
425 warning ("trap mode not supported on Unicos/Mk");
426 alpha_fptm = ALPHA_FPTM_N;
429 if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
430 && alpha_tp != ALPHA_TP_INSN && alpha_cpu != PROCESSOR_EV6)
432 warning ("fp software completion requires -mtrap-precision=i");
433 alpha_tp = ALPHA_TP_INSN;
436 if (alpha_cpu == PROCESSOR_EV6)
438 /* Except for EV6 pass 1 (not released), we always have precise
439 arithmetic traps. Which means we can do software completion
440 without minding trap shadows. */
441 alpha_tp = ALPHA_TP_PROG;
444 if (TARGET_FLOAT_VAX)
446 if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
448 warning ("rounding mode not supported for VAX floats");
449 alpha_fprm = ALPHA_FPRM_NORM;
451 if (alpha_fptm == ALPHA_FPTM_SUI)
453 warning ("trap mode not supported for VAX floats");
454 alpha_fptm = ALPHA_FPTM_SU;
456 if (target_flags_explicit & MASK_LONG_DOUBLE_128)
457 warning ("128-bit long double not supported for VAX floats");
458 target_flags &= ~MASK_LONG_DOUBLE_128;
465 if (!alpha_mlat_string)
466 alpha_mlat_string = "L1";
468 if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
469 && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
471 else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
472 && ISDIGIT ((unsigned char)alpha_mlat_string[1])
473 && alpha_mlat_string[2] == '\0')
475 static int const cache_latency[][4] =
477 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
478 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
479 { 3, 12, 30 }, /* ev6 -- Bcache from DS20 LMbench. */
482 lat = alpha_mlat_string[1] - '0';
483 if (lat <= 0 || lat > 3 || cache_latency[alpha_tune][lat-1] == -1)
485 warning ("L%d cache latency unknown for %s",
486 lat, alpha_cpu_name[alpha_tune]);
490 lat = cache_latency[alpha_tune][lat-1];
492 else if (! strcmp (alpha_mlat_string, "main"))
494 /* Most current memories have about 370ns latency. This is
495 a reasonable guess for a fast cpu. */
500 warning ("bad value %qs for -mmemory-latency", alpha_mlat_string);
504 alpha_memory_latency = lat;
507 /* Default the definition of "small data" to 8 bytes. */
511 /* Infer TARGET_SMALL_DATA from -fpic/-fPIC. */
513 target_flags |= MASK_SMALL_DATA;
514 else if (flag_pic == 2)
515 target_flags &= ~MASK_SMALL_DATA;
517 /* Align labels and loops for optimal branching. */
518 /* ??? Kludge these by not doing anything if we don't optimize and also if
519 we are writing ECOFF symbols to work around a bug in DEC's assembler. */
520 if (optimize > 0 && write_symbols != SDB_DEBUG)
522 if (align_loops <= 0)
524 if (align_jumps <= 0)
527 if (align_functions <= 0)
528 align_functions = 16;
530 /* Acquire a unique set number for our register saves and restores. */
531 alpha_sr_alias_set = new_alias_set ();
533 /* Register variables and functions with the garbage collector. */
535 /* Set up function hooks. */
536 init_machine_status = alpha_init_machine_status;
538 /* Tell the compiler when we're using VAX floating point. */
539 if (TARGET_FLOAT_VAX)
541 REAL_MODE_FORMAT (SFmode) = &vax_f_format;
542 REAL_MODE_FORMAT (DFmode) = &vax_g_format;
543 REAL_MODE_FORMAT (TFmode) = NULL;
547 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
550 zap_mask (HOST_WIDE_INT value)
554 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
556 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
562 /* Return true if OP is valid for a particular TLS relocation.
563 We are already guaranteed that OP is a CONST. */
566 tls_symbolic_operand_1 (rtx op, int size, int unspec)
570 if (GET_CODE (op) != UNSPEC || XINT (op, 1) != unspec)
572 op = XVECEXP (op, 0, 0);
574 if (GET_CODE (op) != SYMBOL_REF)
577 if (SYMBOL_REF_LOCAL_P (op))
579 if (alpha_tls_size > size)
588 switch (SYMBOL_REF_TLS_MODEL (op))
590 case TLS_MODEL_LOCAL_DYNAMIC:
591 return unspec == UNSPEC_DTPREL;
592 case TLS_MODEL_INITIAL_EXEC:
593 return unspec == UNSPEC_TPREL && size == 64;
594 case TLS_MODEL_LOCAL_EXEC:
595 return unspec == UNSPEC_TPREL;
601 /* Used by aligned_memory_operand and unaligned_memory_operand to
602 resolve what reload is going to do with OP if it's a register. */
605 resolve_reload_operand (rtx op)
607 if (reload_in_progress)
610 if (GET_CODE (tmp) == SUBREG)
611 tmp = SUBREG_REG (tmp);
612 if (GET_CODE (tmp) == REG
613 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
615 op = reg_equiv_memory_loc[REGNO (tmp)];
623 /* Implements CONST_OK_FOR_LETTER_P. Return true if the value matches
624 the range defined for C in [I-P]. */
627 alpha_const_ok_for_letter_p (HOST_WIDE_INT value, int c)
632 /* An unsigned 8 bit constant. */
633 return (unsigned HOST_WIDE_INT) value < 0x100;
635 /* The constant zero. */
638 /* A signed 16 bit constant. */
639 return (unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000;
641 /* A shifted signed 16 bit constant appropriate for LDAH. */
642 return ((value & 0xffff) == 0
643 && ((value) >> 31 == -1 || value >> 31 == 0));
645 /* A constant that can be AND'ed with using a ZAP insn. */
646 return zap_mask (value);
648 /* A complemented unsigned 8 bit constant. */
649 return (unsigned HOST_WIDE_INT) (~ value) < 0x100;
651 /* A negated unsigned 8 bit constant. */
652 return (unsigned HOST_WIDE_INT) (- value) < 0x100;
654 /* The constant 1, 2 or 3. */
655 return value == 1 || value == 2 || value == 3;
662 /* Implements CONST_DOUBLE_OK_FOR_LETTER_P. Return true if VALUE
663 matches for C in [GH]. */
666 alpha_const_double_ok_for_letter_p (rtx value, int c)
671 /* The floating point zero constant. */
672 return (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT
673 && value == CONST0_RTX (GET_MODE (value)));
676 /* A valid operand of a ZAP insn. */
677 return (GET_MODE (value) == VOIDmode
678 && zap_mask (CONST_DOUBLE_LOW (value))
679 && zap_mask (CONST_DOUBLE_HIGH (value)));
686 /* Implements CONST_DOUBLE_OK_FOR_LETTER_P. Return true if VALUE
690 alpha_extra_constraint (rtx value, int c)
695 return normal_memory_operand (value, VOIDmode);
697 return direct_call_operand (value, Pmode);
699 return (GET_CODE (value) == CONST_INT
700 && (unsigned HOST_WIDE_INT) INTVAL (value) < 64);
702 return GET_CODE (value) == HIGH;
704 return TARGET_ABI_UNICOSMK && symbolic_operand (value, VOIDmode);
706 return (GET_CODE (value) == CONST_VECTOR
707 && value == CONST0_RTX (GET_MODE (value)));
713 /* The scalar modes supported differs from the default check-what-c-supports
714 version in that sometimes TFmode is available even when long double
715 indicates only DFmode. On unicosmk, we have the situation that HImode
716 doesn't map to any C type, but of course we still support that. */
719 alpha_scalar_mode_supported_p (enum machine_mode mode)
727 case TImode: /* via optabs.c */
735 return TARGET_HAS_XFLOATING_LIBS;
742 /* Alpha implements a couple of integer vector mode operations when
743 TARGET_MAX is enabled. We do not check TARGET_MAX here, however,
744 which allows the vectorizer to operate on e.g. move instructions,
745 or when expand_vector_operations can do something useful. */
748 alpha_vector_mode_supported_p (enum machine_mode mode)
750 return mode == V8QImode || mode == V4HImode || mode == V2SImode;
753 /* Return 1 if this function can directly return via $26. */
758 return (! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK
760 && alpha_sa_size () == 0
761 && get_frame_size () == 0
762 && current_function_outgoing_args_size == 0
763 && current_function_pretend_args_size == 0);
766 /* Return the ADDR_VEC associated with a tablejump insn. */
769 alpha_tablejump_addr_vec (rtx insn)
773 tmp = JUMP_LABEL (insn);
776 tmp = NEXT_INSN (tmp);
779 if (GET_CODE (tmp) == JUMP_INSN
780 && GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC)
781 return PATTERN (tmp);
785 /* Return the label of the predicted edge, or CONST0_RTX if we don't know. */
788 alpha_tablejump_best_label (rtx insn)
790 rtx jump_table = alpha_tablejump_addr_vec (insn);
791 rtx best_label = NULL_RTX;
793 /* ??? Once the CFG doesn't keep getting completely rebuilt, look
794 there for edge frequency counts from profile data. */
798 int n_labels = XVECLEN (jump_table, 1);
802 for (i = 0; i < n_labels; i++)
806 for (j = i + 1; j < n_labels; j++)
807 if (XEXP (XVECEXP (jump_table, 1, i), 0)
808 == XEXP (XVECEXP (jump_table, 1, j), 0))
811 if (count > best_count)
812 best_count = count, best_label = XVECEXP (jump_table, 1, i);
816 return best_label ? best_label : const0_rtx;
819 /* Return the TLS model to use for SYMBOL. */
821 static enum tls_model
822 tls_symbolic_operand_type (rtx symbol)
824 enum tls_model model;
826 if (GET_CODE (symbol) != SYMBOL_REF)
828 model = SYMBOL_REF_TLS_MODEL (symbol);
830 /* Local-exec with a 64-bit size is the same code as initial-exec. */
831 if (model == TLS_MODEL_LOCAL_EXEC && alpha_tls_size == 64)
832 model = TLS_MODEL_INITIAL_EXEC;
837 /* Return true if the function DECL will share the same GP as any
838 function in the current unit of translation. */
841 decl_has_samegp (tree decl)
843 /* Functions that are not local can be overridden, and thus may
844 not share the same gp. */
845 if (!(*targetm.binds_local_p) (decl))
848 /* If -msmall-data is in effect, assume that there is only one GP
849 for the module, and so any local symbol has this property. We
850 need explicit relocations to be able to enforce this for symbols
851 not defined in this unit of translation, however. */
852 if (TARGET_EXPLICIT_RELOCS && TARGET_SMALL_DATA)
855 /* Functions that are not external are defined in this UoT. */
856 /* ??? Irritatingly, static functions not yet emitted are still
857 marked "external". Apply this to non-static functions only. */
858 return !TREE_PUBLIC (decl) || !DECL_EXTERNAL (decl);
861 /* Return true if EXP should be placed in the small data section. */
864 alpha_in_small_data_p (tree exp)
866 /* We want to merge strings, so we never consider them small data. */
867 if (TREE_CODE (exp) == STRING_CST)
870 /* Functions are never in the small data area. Duh. */
871 if (TREE_CODE (exp) == FUNCTION_DECL)
874 if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
876 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
877 if (strcmp (section, ".sdata") == 0
878 || strcmp (section, ".sbss") == 0)
883 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
885 /* If this is an incomplete type with size 0, then we can't put it
886 in sdata because it might be too big when completed. */
887 if (size > 0 && (unsigned HOST_WIDE_INT) size <= g_switch_value)
894 #if TARGET_ABI_OPEN_VMS
896 alpha_linkage_symbol_p (const char *symname)
898 int symlen = strlen (symname);
901 return strcmp (&symname [symlen - 4], "..lk") == 0;
906 #define LINKAGE_SYMBOL_REF_P(X) \
907 ((GET_CODE (X) == SYMBOL_REF \
908 && alpha_linkage_symbol_p (XSTR (X, 0))) \
909 || (GET_CODE (X) == CONST \
910 && GET_CODE (XEXP (X, 0)) == PLUS \
911 && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \
912 && alpha_linkage_symbol_p (XSTR (XEXP (XEXP (X, 0), 0), 0))))
915 /* legitimate_address_p recognizes an RTL expression that is a valid
916 memory address for an instruction. The MODE argument is the
917 machine mode for the MEM expression that wants to use this address.
919 For Alpha, we have either a constant address or the sum of a
920 register and a constant address, or just a register. For DImode,
921 any of those forms can be surrounded with an AND that clear the
922 low-order three bits; this is an "unaligned" access. */
925 alpha_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
927 /* If this is an ldq_u type address, discard the outer AND. */
929 && GET_CODE (x) == AND
930 && GET_CODE (XEXP (x, 1)) == CONST_INT
931 && INTVAL (XEXP (x, 1)) == -8)
934 /* Discard non-paradoxical subregs. */
935 if (GET_CODE (x) == SUBREG
936 && (GET_MODE_SIZE (GET_MODE (x))
937 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
940 /* Unadorned general registers are valid. */
943 ? STRICT_REG_OK_FOR_BASE_P (x)
944 : NONSTRICT_REG_OK_FOR_BASE_P (x)))
947 /* Constant addresses (i.e. +/- 32k) are valid. */
948 if (CONSTANT_ADDRESS_P (x))
951 #if TARGET_ABI_OPEN_VMS
952 if (LINKAGE_SYMBOL_REF_P (x))
956 /* Register plus a small constant offset is valid. */
957 if (GET_CODE (x) == PLUS)
959 rtx ofs = XEXP (x, 1);
962 /* Discard non-paradoxical subregs. */
963 if (GET_CODE (x) == SUBREG
964 && (GET_MODE_SIZE (GET_MODE (x))
965 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
971 && NONSTRICT_REG_OK_FP_BASE_P (x)
972 && GET_CODE (ofs) == CONST_INT)
975 ? STRICT_REG_OK_FOR_BASE_P (x)
976 : NONSTRICT_REG_OK_FOR_BASE_P (x))
977 && CONSTANT_ADDRESS_P (ofs))
982 /* If we're managing explicit relocations, LO_SUM is valid, as
983 are small data symbols. */
984 else if (TARGET_EXPLICIT_RELOCS)
986 if (small_symbolic_operand (x, Pmode))
989 if (GET_CODE (x) == LO_SUM)
991 rtx ofs = XEXP (x, 1);
994 /* Discard non-paradoxical subregs. */
995 if (GET_CODE (x) == SUBREG
996 && (GET_MODE_SIZE (GET_MODE (x))
997 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
1000 /* Must have a valid base register. */
1003 ? STRICT_REG_OK_FOR_BASE_P (x)
1004 : NONSTRICT_REG_OK_FOR_BASE_P (x))))
1007 /* The symbol must be local. */
1008 if (local_symbolic_operand (ofs, Pmode)
1009 || dtp32_symbolic_operand (ofs, Pmode)
1010 || tp32_symbolic_operand (ofs, Pmode))
1018 /* Build the SYMBOL_REF for __tls_get_addr. */
1020 static GTY(()) rtx tls_get_addr_libfunc;
1023 get_tls_get_addr (void)
1025 if (!tls_get_addr_libfunc)
1026 tls_get_addr_libfunc = init_one_libfunc ("__tls_get_addr");
1027 return tls_get_addr_libfunc;
1030 /* Try machine-dependent ways of modifying an illegitimate address
1031 to be legitimate. If we find one, return the new, valid address. */
1034 alpha_legitimize_address (rtx x, rtx scratch,
1035 enum machine_mode mode ATTRIBUTE_UNUSED)
1037 HOST_WIDE_INT addend;
1039 /* If the address is (plus reg const_int) and the CONST_INT is not a
1040 valid offset, compute the high part of the constant and add it to
1041 the register. Then our address is (plus temp low-part-const). */
1042 if (GET_CODE (x) == PLUS
1043 && GET_CODE (XEXP (x, 0)) == REG
1044 && GET_CODE (XEXP (x, 1)) == CONST_INT
1045 && ! CONSTANT_ADDRESS_P (XEXP (x, 1)))
1047 addend = INTVAL (XEXP (x, 1));
1052 /* If the address is (const (plus FOO const_int)), find the low-order
1053 part of the CONST_INT. Then load FOO plus any high-order part of the
1054 CONST_INT into a register. Our address is (plus reg low-part-const).
1055 This is done to reduce the number of GOT entries. */
1057 && GET_CODE (x) == CONST
1058 && GET_CODE (XEXP (x, 0)) == PLUS
1059 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
1061 addend = INTVAL (XEXP (XEXP (x, 0), 1));
1062 x = force_reg (Pmode, XEXP (XEXP (x, 0), 0));
1066 /* If we have a (plus reg const), emit the load as in (2), then add
1067 the two registers, and finally generate (plus reg low-part-const) as
1070 && GET_CODE (x) == PLUS
1071 && GET_CODE (XEXP (x, 0)) == REG
1072 && GET_CODE (XEXP (x, 1)) == CONST
1073 && GET_CODE (XEXP (XEXP (x, 1), 0)) == PLUS
1074 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == CONST_INT)
1076 addend = INTVAL (XEXP (XEXP (XEXP (x, 1), 0), 1));
1077 x = expand_simple_binop (Pmode, PLUS, XEXP (x, 0),
1078 XEXP (XEXP (XEXP (x, 1), 0), 0),
1079 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1083 /* If this is a local symbol, split the address into HIGH/LO_SUM parts. */
1084 if (TARGET_EXPLICIT_RELOCS && symbolic_operand (x, Pmode))
1086 rtx r0, r16, eqv, tga, tp, insn, dest, seq;
1088 switch (tls_symbolic_operand_type (x))
1090 case TLS_MODEL_GLOBAL_DYNAMIC:
1093 r0 = gen_rtx_REG (Pmode, 0);
1094 r16 = gen_rtx_REG (Pmode, 16);
1095 tga = get_tls_get_addr ();
1096 dest = gen_reg_rtx (Pmode);
1097 seq = GEN_INT (alpha_next_sequence_number++);
1099 emit_insn (gen_movdi_er_tlsgd (r16, pic_offset_table_rtx, x, seq));
1100 insn = gen_call_value_osf_tlsgd (r0, tga, seq);
1101 insn = emit_call_insn (insn);
1102 CONST_OR_PURE_CALL_P (insn) = 1;
1103 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
1105 insn = get_insns ();
1108 emit_libcall_block (insn, dest, r0, x);
1111 case TLS_MODEL_LOCAL_DYNAMIC:
1114 r0 = gen_rtx_REG (Pmode, 0);
1115 r16 = gen_rtx_REG (Pmode, 16);
1116 tga = get_tls_get_addr ();
1117 scratch = gen_reg_rtx (Pmode);
1118 seq = GEN_INT (alpha_next_sequence_number++);
1120 emit_insn (gen_movdi_er_tlsldm (r16, pic_offset_table_rtx, seq));
1121 insn = gen_call_value_osf_tlsldm (r0, tga, seq);
1122 insn = emit_call_insn (insn);
1123 CONST_OR_PURE_CALL_P (insn) = 1;
1124 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
1126 insn = get_insns ();
1129 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
1130 UNSPEC_TLSLDM_CALL);
1131 emit_libcall_block (insn, scratch, r0, eqv);
1133 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPREL);
1134 eqv = gen_rtx_CONST (Pmode, eqv);
1136 if (alpha_tls_size == 64)
1138 dest = gen_reg_rtx (Pmode);
1139 emit_insn (gen_rtx_SET (VOIDmode, dest, eqv));
1140 emit_insn (gen_adddi3 (dest, dest, scratch));
1143 if (alpha_tls_size == 32)
1145 insn = gen_rtx_HIGH (Pmode, eqv);
1146 insn = gen_rtx_PLUS (Pmode, scratch, insn);
1147 scratch = gen_reg_rtx (Pmode);
1148 emit_insn (gen_rtx_SET (VOIDmode, scratch, insn));
1150 return gen_rtx_LO_SUM (Pmode, scratch, eqv);
1152 case TLS_MODEL_INITIAL_EXEC:
1153 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
1154 eqv = gen_rtx_CONST (Pmode, eqv);
1155 tp = gen_reg_rtx (Pmode);
1156 scratch = gen_reg_rtx (Pmode);
1157 dest = gen_reg_rtx (Pmode);
1159 emit_insn (gen_load_tp (tp));
1160 emit_insn (gen_rtx_SET (VOIDmode, scratch, eqv));
1161 emit_insn (gen_adddi3 (dest, tp, scratch));
1164 case TLS_MODEL_LOCAL_EXEC:
1165 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
1166 eqv = gen_rtx_CONST (Pmode, eqv);
1167 tp = gen_reg_rtx (Pmode);
1169 emit_insn (gen_load_tp (tp));
1170 if (alpha_tls_size == 32)
1172 insn = gen_rtx_HIGH (Pmode, eqv);
1173 insn = gen_rtx_PLUS (Pmode, tp, insn);
1174 tp = gen_reg_rtx (Pmode);
1175 emit_insn (gen_rtx_SET (VOIDmode, tp, insn));
1177 return gen_rtx_LO_SUM (Pmode, tp, eqv);
1180 if (local_symbolic_operand (x, Pmode))
1182 if (small_symbolic_operand (x, Pmode))
1186 if (!no_new_pseudos)
1187 scratch = gen_reg_rtx (Pmode);
1188 emit_insn (gen_rtx_SET (VOIDmode, scratch,
1189 gen_rtx_HIGH (Pmode, x)));
1190 return gen_rtx_LO_SUM (Pmode, scratch, x);
1199 HOST_WIDE_INT low, high;
1201 low = ((addend & 0xffff) ^ 0x8000) - 0x8000;
1203 high = ((addend & 0xffffffff) ^ 0x80000000) - 0x80000000;
1207 x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (addend),
1208 (no_new_pseudos ? scratch : NULL_RTX),
1209 1, OPTAB_LIB_WIDEN);
1211 x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (high),
1212 (no_new_pseudos ? scratch : NULL_RTX),
1213 1, OPTAB_LIB_WIDEN);
1215 return plus_constant (x, low);
1219 /* Primarily this is required for TLS symbols, but given that our move
1220 patterns *ought* to be able to handle any symbol at any time, we
1221 should never be spilling symbolic operands to the constant pool, ever. */
1224 alpha_cannot_force_const_mem (rtx x)
1226 enum rtx_code code = GET_CODE (x);
1227 return code == SYMBOL_REF || code == LABEL_REF || code == CONST;
1230 /* We do not allow indirect calls to be optimized into sibling calls, nor
1231 can we allow a call to a function with a different GP to be optimized
1235 alpha_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
1237 /* Can't do indirect tail calls, since we don't know if the target
1238 uses the same GP. */
1242 /* Otherwise, we can make a tail call if the target function shares
1244 return decl_has_samegp (decl);
1248 some_small_symbolic_operand_int (rtx *px, void *data ATTRIBUTE_UNUSED)
1252 /* Don't re-split. */
1253 if (GET_CODE (x) == LO_SUM)
1256 return small_symbolic_operand (x, Pmode) != 0;
1260 split_small_symbolic_operand_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
1264 /* Don't re-split. */
1265 if (GET_CODE (x) == LO_SUM)
1268 if (small_symbolic_operand (x, Pmode))
1270 x = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, x);
1279 split_small_symbolic_operand (rtx x)
1282 for_each_rtx (&x, split_small_symbolic_operand_1, NULL);
1286 /* Indicate that INSN cannot be duplicated. This is true for any insn
1287 that we've marked with gpdisp relocs, since those have to stay in
1288 1-1 correspondence with one another.
1290 Technically we could copy them if we could set up a mapping from one
1291 sequence number to another, across the set of insns to be duplicated.
1292 This seems overly complicated and error-prone since interblock motion
1293 from sched-ebb could move one of the pair of insns to a different block.
1295 Also cannot allow jsr insns to be duplicated. If they throw exceptions,
1296 then they'll be in a different block from their ldgp. Which could lead
1297 the bb reorder code to think that it would be ok to copy just the block
1298 containing the call and branch to the block containing the ldgp. */
1301 alpha_cannot_copy_insn_p (rtx insn)
1303 if (!reload_completed || !TARGET_EXPLICIT_RELOCS)
1305 if (recog_memoized (insn) >= 0)
1306 return get_attr_cannot_copy (insn);
1312 /* Try a machine-dependent way of reloading an illegitimate address
1313 operand. If we find one, push the reload and return the new rtx. */
1316 alpha_legitimize_reload_address (rtx x,
1317 enum machine_mode mode ATTRIBUTE_UNUSED,
1318 int opnum, int type,
1319 int ind_levels ATTRIBUTE_UNUSED)
1321 /* We must recognize output that we have already generated ourselves. */
1322 if (GET_CODE (x) == PLUS
1323 && GET_CODE (XEXP (x, 0)) == PLUS
1324 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
1325 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1326 && GET_CODE (XEXP (x, 1)) == CONST_INT)
1328 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
1329 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
1334 /* We wish to handle large displacements off a base register by
1335 splitting the addend across an ldah and the mem insn. This
1336 cuts number of extra insns needed from 3 to 1. */
1337 if (GET_CODE (x) == PLUS
1338 && GET_CODE (XEXP (x, 0)) == REG
1339 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
1340 && REGNO_OK_FOR_BASE_P (REGNO (XEXP (x, 0)))
1341 && GET_CODE (XEXP (x, 1)) == CONST_INT)
1343 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
1344 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1346 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
1348 /* Check for 32-bit overflow. */
1349 if (high + low != val)
1352 /* Reload the high part into a base reg; leave the low part
1353 in the mem directly. */
1354 x = gen_rtx_PLUS (GET_MODE (x),
1355 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
1359 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
1360 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
1368 /* Compute a (partial) cost for rtx X. Return true if the complete
1369 cost has been computed, and false if subexpressions should be
1370 scanned. In either case, *TOTAL contains the cost result. */
1373 alpha_rtx_costs (rtx x, int code, int outer_code, int *total)
1375 enum machine_mode mode = GET_MODE (x);
1376 bool float_mode_p = FLOAT_MODE_P (mode);
1377 const struct alpha_rtx_cost_data *cost_data;
1380 cost_data = &alpha_rtx_cost_size;
1382 cost_data = &alpha_rtx_cost_data[alpha_tune];
1387 /* If this is an 8-bit constant, return zero since it can be used
1388 nearly anywhere with no cost. If it is a valid operand for an
1389 ADD or AND, likewise return 0 if we know it will be used in that
1390 context. Otherwise, return 2 since it might be used there later.
1391 All other constants take at least two insns. */
1392 if (INTVAL (x) >= 0 && INTVAL (x) < 256)
1400 if (x == CONST0_RTX (mode))
1402 else if ((outer_code == PLUS && add_operand (x, VOIDmode))
1403 || (outer_code == AND && and_operand (x, VOIDmode)))
1405 else if (add_operand (x, VOIDmode) || and_operand (x, VOIDmode))
1408 *total = COSTS_N_INSNS (2);
1414 if (TARGET_EXPLICIT_RELOCS && small_symbolic_operand (x, VOIDmode))
1415 *total = COSTS_N_INSNS (outer_code != MEM);
1416 else if (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (x, VOIDmode))
1417 *total = COSTS_N_INSNS (1 + (outer_code != MEM));
1418 else if (tls_symbolic_operand_type (x))
1419 /* Estimate of cost for call_pal rduniq. */
1420 /* ??? How many insns do we emit here? More than one... */
1421 *total = COSTS_N_INSNS (15);
1423 /* Otherwise we do a load from the GOT. */
1424 *total = COSTS_N_INSNS (optimize_size ? 1 : alpha_memory_latency);
1428 /* This is effectively an add_operand. */
1435 *total = cost_data->fp_add;
1436 else if (GET_CODE (XEXP (x, 0)) == MULT
1437 && const48_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
1439 *total = (rtx_cost (XEXP (XEXP (x, 0), 0), outer_code)
1440 + rtx_cost (XEXP (x, 1), outer_code) + COSTS_N_INSNS (1));
1447 *total = cost_data->fp_mult;
1448 else if (mode == DImode)
1449 *total = cost_data->int_mult_di;
1451 *total = cost_data->int_mult_si;
1455 if (GET_CODE (XEXP (x, 1)) == CONST_INT
1456 && INTVAL (XEXP (x, 1)) <= 3)
1458 *total = COSTS_N_INSNS (1);
1465 *total = cost_data->int_shift;
1470 *total = cost_data->fp_add;
1472 *total = cost_data->int_cmov;
1480 *total = cost_data->int_div;
1481 else if (mode == SFmode)
1482 *total = cost_data->fp_div_sf;
1484 *total = cost_data->fp_div_df;
1488 *total = COSTS_N_INSNS (optimize_size ? 1 : alpha_memory_latency);
1494 *total = COSTS_N_INSNS (1);
1502 *total = COSTS_N_INSNS (1) + cost_data->int_cmov;
1508 case UNSIGNED_FLOAT:
1512 case FLOAT_TRUNCATE:
1513 *total = cost_data->fp_add;
1521 /* REF is an alignable memory location. Place an aligned SImode
1522 reference into *PALIGNED_MEM and the number of bits to shift into
1523 *PBITNUM. SCRATCH is a free register for use in reloading out
1524 of range stack slots. */
1527 get_aligned_mem (rtx ref, rtx *paligned_mem, rtx *pbitnum)
1530 HOST_WIDE_INT offset = 0;
1532 if (GET_CODE (ref) != MEM)
1535 if (reload_in_progress
1536 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1538 base = find_replacement (&XEXP (ref, 0));
1540 if (! memory_address_p (GET_MODE (ref), base))
1545 base = XEXP (ref, 0);
1548 if (GET_CODE (base) == PLUS)
1549 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1552 = widen_memory_access (ref, SImode, (offset & ~3) - offset);
1554 if (WORDS_BIG_ENDIAN)
1555 *pbitnum = GEN_INT (32 - (GET_MODE_BITSIZE (GET_MODE (ref))
1556 + (offset & 3) * 8));
1558 *pbitnum = GEN_INT ((offset & 3) * 8);
1561 /* Similar, but just get the address. Handle the two reload cases.
1562 Add EXTRA_OFFSET to the address we return. */
1565 get_unaligned_address (rtx ref, int extra_offset)
1568 HOST_WIDE_INT offset = 0;
1570 if (GET_CODE (ref) != MEM)
1573 if (reload_in_progress
1574 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1576 base = find_replacement (&XEXP (ref, 0));
1578 if (! memory_address_p (GET_MODE (ref), base))
1583 base = XEXP (ref, 0);
1586 if (GET_CODE (base) == PLUS)
1587 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1589 return plus_constant (base, offset + extra_offset);
1592 /* On the Alpha, all (non-symbolic) constants except zero go into
1593 a floating-point register via memory. Note that we cannot
1594 return anything that is not a subset of CLASS, and that some
1595 symbolic constants cannot be dropped to memory. */
1598 alpha_preferred_reload_class(rtx x, enum reg_class class)
1600 /* Zero is present in any register class. */
1601 if (x == CONST0_RTX (GET_MODE (x)))
1604 /* These sorts of constants we can easily drop to memory. */
1605 if (GET_CODE (x) == CONST_INT
1606 || GET_CODE (x) == CONST_DOUBLE
1607 || GET_CODE (x) == CONST_VECTOR)
1609 if (class == FLOAT_REGS)
1611 if (class == ALL_REGS)
1612 return GENERAL_REGS;
1616 /* All other kinds of constants should not (and in the case of HIGH
1617 cannot) be dropped to memory -- instead we use a GENERAL_REGS
1618 secondary reload. */
1620 return (class == ALL_REGS ? GENERAL_REGS : class);
1625 /* Loading and storing HImode or QImode values to and from memory
1626 usually requires a scratch register. The exceptions are loading
1627 QImode and HImode from an aligned address to a general register
1628 unless byte instructions are permitted.
1630 We also cannot load an unaligned address or a paradoxical SUBREG
1631 into an FP register.
1633 We also cannot do integral arithmetic into FP regs, as might result
1634 from register elimination into a DImode fp register. */
1637 secondary_reload_class (enum reg_class class, enum machine_mode mode,
1640 if ((mode == QImode || mode == HImode) && ! TARGET_BWX)
1642 if (GET_CODE (x) == MEM
1643 || (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
1644 || (GET_CODE (x) == SUBREG
1645 && (GET_CODE (SUBREG_REG (x)) == MEM
1646 || (GET_CODE (SUBREG_REG (x)) == REG
1647 && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER))))
1649 if (!in || !aligned_memory_operand(x, mode))
1650 return GENERAL_REGS;
1654 if (class == FLOAT_REGS)
1656 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
1657 return GENERAL_REGS;
1659 if (GET_CODE (x) == SUBREG
1660 && (GET_MODE_SIZE (GET_MODE (x))
1661 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
1662 return GENERAL_REGS;
1664 if (in && INTEGRAL_MODE_P (mode)
1665 && ! (memory_operand (x, mode) || x == const0_rtx))
1666 return GENERAL_REGS;
1672 /* Subfunction of the following function. Update the flags of any MEM
1673 found in part of X. */
1676 alpha_set_memflags_1 (rtx *xp, void *data)
1678 rtx x = *xp, orig = (rtx) data;
1680 if (GET_CODE (x) != MEM)
1683 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (orig);
1684 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (orig);
1685 MEM_SCALAR_P (x) = MEM_SCALAR_P (orig);
1686 MEM_NOTRAP_P (x) = MEM_NOTRAP_P (orig);
1687 MEM_READONLY_P (x) = MEM_READONLY_P (orig);
1689 /* Sadly, we cannot use alias sets because the extra aliasing
1690 produced by the AND interferes. Given that two-byte quantities
1691 are the only thing we would be able to differentiate anyway,
1692 there does not seem to be any point in convoluting the early
1693 out of the alias check. */
1698 /* Given INSN, which is an INSN list or the PATTERN of a single insn
1699 generated to perform a memory operation, look for any MEMs in either
1700 a SET_DEST or a SET_SRC and copy the in-struct, unchanging, and
1701 volatile flags from REF into each of the MEMs found. If REF is not
1702 a MEM, don't do anything. */
1705 alpha_set_memflags (rtx insn, rtx ref)
1709 if (GET_CODE (ref) != MEM)
1712 /* This is only called from alpha.md, after having had something
1713 generated from one of the insn patterns. So if everything is
1714 zero, the pattern is already up-to-date. */
1715 if (!MEM_VOLATILE_P (ref)
1716 && !MEM_IN_STRUCT_P (ref)
1717 && !MEM_SCALAR_P (ref)
1718 && !MEM_NOTRAP_P (ref)
1719 && !MEM_READONLY_P (ref))
1723 base_ptr = &PATTERN (insn);
1726 for_each_rtx (base_ptr, alpha_set_memflags_1, (void *) ref);
1729 static rtx alpha_emit_set_const (rtx, enum machine_mode, HOST_WIDE_INT,
1732 /* Internal routine for alpha_emit_set_const to check for N or below insns.
1733 If NO_OUTPUT is true, then we only check to see if N insns are possible,
1734 and return pc_rtx if successful. */
1737 alpha_emit_set_const_1 (rtx target, enum machine_mode mode,
1738 HOST_WIDE_INT c, int n, bool no_output)
1742 /* Use a pseudo if highly optimizing and still generating RTL. */
1744 = (flag_expensive_optimizations && !no_new_pseudos ? 0 : target);
1747 /* If this is a sign-extended 32-bit constant, we can do this in at most
1748 three insns, so do it if we have enough insns left. We always have
1749 a sign-extended 32-bit constant when compiling on a narrow machine. */
1751 if (HOST_BITS_PER_WIDE_INT != 64
1752 || c >> 31 == -1 || c >> 31 == 0)
1754 HOST_WIDE_INT low = ((c & 0xffff) ^ 0x8000) - 0x8000;
1755 HOST_WIDE_INT tmp1 = c - low;
1756 HOST_WIDE_INT high = (((tmp1 >> 16) & 0xffff) ^ 0x8000) - 0x8000;
1757 HOST_WIDE_INT extra = 0;
1759 /* If HIGH will be interpreted as negative but the constant is
1760 positive, we must adjust it to do two ldha insns. */
1762 if ((high & 0x8000) != 0 && c >= 0)
1766 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1769 if (c == low || (low == 0 && extra == 0))
1771 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1772 but that meant that we can't handle INT_MIN on 32-bit machines
1773 (like NT/Alpha), because we recurse indefinitely through
1774 emit_move_insn to gen_movdi. So instead, since we know exactly
1775 what we want, create it explicitly. */
1780 target = gen_reg_rtx (mode);
1781 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1784 else if (n >= 2 + (extra != 0))
1790 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (high << 16)));
1794 temp = copy_to_suggested_reg (GEN_INT (high << 16),
1797 /* As of 2002-02-23, addsi3 is only available when not optimizing.
1798 This means that if we go through expand_binop, we'll try to
1799 generate extensions, etc, which will require new pseudos, which
1800 will fail during some split phases. The SImode add patterns
1801 still exist, but are not named. So build the insns by hand. */
1806 subtarget = gen_reg_rtx (mode);
1807 insn = gen_rtx_PLUS (mode, temp, GEN_INT (extra << 16));
1808 insn = gen_rtx_SET (VOIDmode, subtarget, insn);
1814 target = gen_reg_rtx (mode);
1815 insn = gen_rtx_PLUS (mode, temp, GEN_INT (low));
1816 insn = gen_rtx_SET (VOIDmode, target, insn);
1822 /* If we couldn't do it that way, try some other methods. But if we have
1823 no instructions left, don't bother. Likewise, if this is SImode and
1824 we can't make pseudos, we can't do anything since the expand_binop
1825 and expand_unop calls will widen and try to make pseudos. */
1827 if (n == 1 || (mode == SImode && no_new_pseudos))
1830 /* Next, see if we can load a related constant and then shift and possibly
1831 negate it to get the constant we want. Try this once each increasing
1832 numbers of insns. */
1834 for (i = 1; i < n; i++)
1836 /* First, see if minus some low bits, we've an easy load of
1839 new = ((c & 0xffff) ^ 0x8000) - 0x8000;
1842 temp = alpha_emit_set_const (subtarget, mode, c - new, i, no_output);
1847 return expand_binop (mode, add_optab, temp, GEN_INT (new),
1848 target, 0, OPTAB_WIDEN);
1852 /* Next try complementing. */
1853 temp = alpha_emit_set_const (subtarget, mode, ~c, i, no_output);
1858 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1861 /* Next try to form a constant and do a left shift. We can do this
1862 if some low-order bits are zero; the exact_log2 call below tells
1863 us that information. The bits we are shifting out could be any
1864 value, but here we'll just try the 0- and sign-extended forms of
1865 the constant. To try to increase the chance of having the same
1866 constant in more than one insn, start at the highest number of
1867 bits to shift, but try all possibilities in case a ZAPNOT will
1870 bits = exact_log2 (c & -c);
1872 for (; bits > 0; bits--)
1875 temp = alpha_emit_set_const (subtarget, mode, new, i, no_output);
1878 new = (unsigned HOST_WIDE_INT)c >> bits;
1879 temp = alpha_emit_set_const (subtarget, mode, new,
1886 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1887 target, 0, OPTAB_WIDEN);
1891 /* Now try high-order zero bits. Here we try the shifted-in bits as
1892 all zero and all ones. Be careful to avoid shifting outside the
1893 mode and to avoid shifting outside the host wide int size. */
1894 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1895 confuse the recursive call and set all of the high 32 bits. */
1897 bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1898 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64));
1900 for (; bits > 0; bits--)
1903 temp = alpha_emit_set_const (subtarget, mode, new, i, no_output);
1906 new = (c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1);
1907 temp = alpha_emit_set_const (subtarget, mode, new,
1914 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1915 target, 1, OPTAB_WIDEN);
1919 /* Now try high-order 1 bits. We get that with a sign-extension.
1920 But one bit isn't enough here. Be careful to avoid shifting outside
1921 the mode and to avoid shifting outside the host wide int size. */
1923 bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1924 - floor_log2 (~ c) - 2);
1926 for (; bits > 0; bits--)
1929 temp = alpha_emit_set_const (subtarget, mode, new, i, no_output);
1932 new = (c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1);
1933 temp = alpha_emit_set_const (subtarget, mode, new,
1940 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1941 target, 0, OPTAB_WIDEN);
1946 #if HOST_BITS_PER_WIDE_INT == 64
1947 /* Finally, see if can load a value into the target that is the same as the
1948 constant except that all bytes that are 0 are changed to be 0xff. If we
1949 can, then we can do a ZAPNOT to obtain the desired constant. */
1952 for (i = 0; i < 64; i += 8)
1953 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1954 new |= (HOST_WIDE_INT) 0xff << i;
1956 /* We are only called for SImode and DImode. If this is SImode, ensure that
1957 we are sign extended to a full word. */
1960 new = ((new & 0xffffffff) ^ 0x80000000) - 0x80000000;
1964 temp = alpha_emit_set_const (subtarget, mode, new, n - 1, no_output);
1969 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1970 target, 0, OPTAB_WIDEN);
1978 /* Try to output insns to set TARGET equal to the constant C if it can be
1979 done in less than N insns. Do all computations in MODE. Returns the place
1980 where the output has been placed if it can be done and the insns have been
1981 emitted. If it would take more than N insns, zero is returned and no
1982 insns and emitted. */
1985 alpha_emit_set_const (rtx target, enum machine_mode mode,
1986 HOST_WIDE_INT c, int n, bool no_output)
1988 enum machine_mode orig_mode = mode;
1989 rtx orig_target = target;
1993 /* If we can't make any pseudos, TARGET is an SImode hard register, we
1994 can't load this constant in one insn, do this in DImode. */
1995 if (no_new_pseudos && mode == SImode
1996 && GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER)
1998 result = alpha_emit_set_const_1 (target, mode, c, 1, no_output);
2002 target = no_output ? NULL : gen_lowpart (DImode, target);
2005 else if (mode == V8QImode || mode == V4HImode || mode == V2SImode)
2007 target = no_output ? NULL : gen_lowpart (DImode, target);
2011 /* Try 1 insn, then 2, then up to N. */
2012 for (i = 1; i <= n; i++)
2014 result = alpha_emit_set_const_1 (target, mode, c, i, no_output);
2022 insn = get_last_insn ();
2023 set = single_set (insn);
2024 if (! CONSTANT_P (SET_SRC (set)))
2025 set_unique_reg_note (get_last_insn (), REG_EQUAL, GEN_INT (c));
2030 /* Allow for the case where we changed the mode of TARGET. */
2033 if (result == target)
2034 result = orig_target;
2035 else if (mode != orig_mode)
2036 result = gen_lowpart (orig_mode, result);
2042 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
2043 fall back to a straight forward decomposition. We do this to avoid
2044 exponential run times encountered when looking for longer sequences
2045 with alpha_emit_set_const. */
2048 alpha_emit_set_long_const (rtx target, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
2050 HOST_WIDE_INT d1, d2, d3, d4;
2052 /* Decompose the entire word */
2053 #if HOST_BITS_PER_WIDE_INT >= 64
2054 if (c2 != -(c1 < 0))
2056 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
2058 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
2059 c1 = (c1 - d2) >> 32;
2060 d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
2062 d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
2066 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
2068 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
2072 d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
2074 d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
2079 /* Construct the high word */
2082 emit_move_insn (target, GEN_INT (d4));
2084 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
2087 emit_move_insn (target, GEN_INT (d3));
2089 /* Shift it into place */
2090 emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
2092 /* Add in the low bits. */
2094 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
2096 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
2101 /* Given an integral CONST_INT, CONST_DOUBLE, or CONST_VECTOR, return
2105 alpha_extract_integer (rtx x, HOST_WIDE_INT *p0, HOST_WIDE_INT *p1)
2107 HOST_WIDE_INT i0, i1;
2109 if (GET_CODE (x) == CONST_VECTOR)
2110 x = simplify_subreg (DImode, x, GET_MODE (x), 0);
2113 if (GET_CODE (x) == CONST_INT)
2118 else if (HOST_BITS_PER_WIDE_INT >= 64)
2120 i0 = CONST_DOUBLE_LOW (x);
2125 i0 = CONST_DOUBLE_LOW (x);
2126 i1 = CONST_DOUBLE_HIGH (x);
2133 /* Implement LEGITIMATE_CONSTANT_P. This is all constants for which we
2134 are willing to load the value into a register via a move pattern.
2135 Normally this is all symbolic constants, integral constants that
2136 take three or fewer instructions, and floating-point zero. */
2139 alpha_legitimate_constant_p (rtx x)
2141 enum machine_mode mode = GET_MODE (x);
2142 HOST_WIDE_INT i0, i1;
2144 switch (GET_CODE (x))
2153 if (x == CONST0_RTX (mode))
2155 if (FLOAT_MODE_P (mode))
2160 if (x == CONST0_RTX (mode))
2162 if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
2164 if (GET_MODE_SIZE (mode) != 8)
2170 if (TARGET_BUILD_CONSTANTS)
2172 alpha_extract_integer (x, &i0, &i1);
2173 if (HOST_BITS_PER_WIDE_INT >= 64 || i1 == (-i0 < 0))
2174 return alpha_emit_set_const_1 (x, mode, i0, 3, true) != NULL;
2182 /* Operand 1 is known to be a constant, and should require more than one
2183 instruction to load. Emit that multi-part load. */
2186 alpha_split_const_mov (enum machine_mode mode, rtx *operands)
2188 HOST_WIDE_INT i0, i1;
2189 rtx temp = NULL_RTX;
2191 alpha_extract_integer (operands[1], &i0, &i1);
2193 if (HOST_BITS_PER_WIDE_INT >= 64 || i1 == -(i0 < 0))
2194 temp = alpha_emit_set_const (operands[0], mode, i0, 3, false);
2196 if (!temp && TARGET_BUILD_CONSTANTS)
2197 temp = alpha_emit_set_long_const (operands[0], i0, i1);
2201 if (!rtx_equal_p (operands[0], temp))
2202 emit_move_insn (operands[0], temp);
2209 /* Expand a move instruction; return true if all work is done.
2210 We don't handle non-bwx subword loads here. */
2213 alpha_expand_mov (enum machine_mode mode, rtx *operands)
2215 /* If the output is not a register, the input must be. */
2216 if (GET_CODE (operands[0]) == MEM
2217 && ! reg_or_0_operand (operands[1], mode))
2218 operands[1] = force_reg (mode, operands[1]);
2220 /* Allow legitimize_address to perform some simplifications. */
2221 if (mode == Pmode && symbolic_operand (operands[1], mode))
2225 tmp = alpha_legitimize_address (operands[1], operands[0], mode);
2228 if (tmp == operands[0])
2235 /* Early out for non-constants and valid constants. */
2236 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], mode))
2239 /* Split large integers. */
2240 if (GET_CODE (operands[1]) == CONST_INT
2241 || GET_CODE (operands[1]) == CONST_DOUBLE
2242 || GET_CODE (operands[1]) == CONST_VECTOR)
2244 if (alpha_split_const_mov (mode, operands))
2248 /* Otherwise we've nothing left but to drop the thing to memory. */
2249 operands[1] = force_const_mem (mode, operands[1]);
2250 if (reload_in_progress)
2252 emit_move_insn (operands[0], XEXP (operands[1], 0));
2253 operands[1] = copy_rtx (operands[1]);
2254 XEXP (operands[1], 0) = operands[0];
2257 operands[1] = validize_mem (operands[1]);
2261 /* Expand a non-bwx QImode or HImode move instruction;
2262 return true if all work is done. */
2265 alpha_expand_mov_nobwx (enum machine_mode mode, rtx *operands)
2267 /* If the output is not a register, the input must be. */
2268 if (GET_CODE (operands[0]) == MEM)
2269 operands[1] = force_reg (mode, operands[1]);
2271 /* Handle four memory cases, unaligned and aligned for either the input
2272 or the output. The only case where we can be called during reload is
2273 for aligned loads; all other cases require temporaries. */
2275 if (GET_CODE (operands[1]) == MEM
2276 || (GET_CODE (operands[1]) == SUBREG
2277 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
2278 || (reload_in_progress && GET_CODE (operands[1]) == REG
2279 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
2280 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
2281 && GET_CODE (SUBREG_REG (operands[1])) == REG
2282 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
2284 if (aligned_memory_operand (operands[1], mode))
2286 if (reload_in_progress)
2288 emit_insn ((mode == QImode
2289 ? gen_reload_inqi_help
2290 : gen_reload_inhi_help)
2291 (operands[0], operands[1],
2292 gen_rtx_REG (SImode, REGNO (operands[0]))));
2296 rtx aligned_mem, bitnum;
2297 rtx scratch = gen_reg_rtx (SImode);
2301 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
2303 subtarget = operands[0];
2304 if (GET_CODE (subtarget) == REG)
2305 subtarget = gen_lowpart (DImode, subtarget), copyout = false;
2307 subtarget = gen_reg_rtx (DImode), copyout = true;
2309 emit_insn ((mode == QImode
2310 ? gen_aligned_loadqi
2311 : gen_aligned_loadhi)
2312 (subtarget, aligned_mem, bitnum, scratch));
2315 emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
2320 /* Don't pass these as parameters since that makes the generated
2321 code depend on parameter evaluation order which will cause
2322 bootstrap failures. */
2324 rtx temp1, temp2, seq, subtarget;
2327 temp1 = gen_reg_rtx (DImode);
2328 temp2 = gen_reg_rtx (DImode);
2330 subtarget = operands[0];
2331 if (GET_CODE (subtarget) == REG)
2332 subtarget = gen_lowpart (DImode, subtarget), copyout = false;
2334 subtarget = gen_reg_rtx (DImode), copyout = true;
2336 seq = ((mode == QImode
2337 ? gen_unaligned_loadqi
2338 : gen_unaligned_loadhi)
2339 (subtarget, get_unaligned_address (operands[1], 0),
2341 alpha_set_memflags (seq, operands[1]);
2345 emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
2350 if (GET_CODE (operands[0]) == MEM
2351 || (GET_CODE (operands[0]) == SUBREG
2352 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
2353 || (reload_in_progress && GET_CODE (operands[0]) == REG
2354 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
2355 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
2356 && GET_CODE (SUBREG_REG (operands[0])) == REG
2357 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
2359 if (aligned_memory_operand (operands[0], mode))
2361 rtx aligned_mem, bitnum;
2362 rtx temp1 = gen_reg_rtx (SImode);
2363 rtx temp2 = gen_reg_rtx (SImode);
2365 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
2367 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
2372 rtx temp1 = gen_reg_rtx (DImode);
2373 rtx temp2 = gen_reg_rtx (DImode);
2374 rtx temp3 = gen_reg_rtx (DImode);
2375 rtx seq = ((mode == QImode
2376 ? gen_unaligned_storeqi
2377 : gen_unaligned_storehi)
2378 (get_unaligned_address (operands[0], 0),
2379 operands[1], temp1, temp2, temp3));
2381 alpha_set_memflags (seq, operands[0]);
2390 /* Implement the movmisalign patterns. One of the operands is a memory
2391 that is not naturally aligned. Emit instructions to load it. */
2394 alpha_expand_movmisalign (enum machine_mode mode, rtx *operands)
2396 /* Honor misaligned loads, for those we promised to do so. */
2397 if (MEM_P (operands[1]))
2401 if (register_operand (operands[0], mode))
2404 tmp = gen_reg_rtx (mode);
2406 alpha_expand_unaligned_load (tmp, operands[1], 8, 0, 0);
2407 if (tmp != operands[0])
2408 emit_move_insn (operands[0], tmp);
2410 else if (MEM_P (operands[0]))
2412 if (!reg_or_0_operand (operands[1], mode))
2413 operands[1] = force_reg (mode, operands[1]);
2414 alpha_expand_unaligned_store (operands[0], operands[1], 8, 0);
2420 /* Generate an unsigned DImode to FP conversion. This is the same code
2421 optabs would emit if we didn't have TFmode patterns.
2423 For SFmode, this is the only construction I've found that can pass
2424 gcc.c-torture/execute/ieee/rbug.c. No scenario that uses DFmode
2425 intermediates will work, because you'll get intermediate rounding
2426 that ruins the end result. Some of this could be fixed by turning
2427 on round-to-positive-infinity, but that requires diddling the fpsr,
2428 which kills performance. I tried turning this around and converting
2429 to a negative number, so that I could turn on /m, but either I did
2430 it wrong or there's something else cause I wound up with the exact
2431 same single-bit error. There is a branch-less form of this same code:
2442 fcmoveq $f10,$f11,$f0
2444 I'm not using it because it's the same number of instructions as
2445 this branch-full form, and it has more serialized long latency
2446 instructions on the critical path.
2448 For DFmode, we can avoid rounding errors by breaking up the word
2449 into two pieces, converting them separately, and adding them back:
2451 LC0: .long 0,0x5f800000
2456 cpyse $f11,$f31,$f10
2457 cpyse $f31,$f11,$f11
2465 This doesn't seem to be a clear-cut win over the optabs form.
2466 It probably all depends on the distribution of numbers being
2467 converted -- in the optabs form, all but high-bit-set has a
2468 much lower minimum execution time. */
2471 alpha_emit_floatuns (rtx operands[2])
2473 rtx neglab, donelab, i0, i1, f0, in, out;
2474 enum machine_mode mode;
2477 in = force_reg (DImode, operands[1]);
2478 mode = GET_MODE (out);
2479 neglab = gen_label_rtx ();
2480 donelab = gen_label_rtx ();
2481 i0 = gen_reg_rtx (DImode);
2482 i1 = gen_reg_rtx (DImode);
2483 f0 = gen_reg_rtx (mode);
2485 emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0, neglab);
2487 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_FLOAT (mode, in)));
2488 emit_jump_insn (gen_jump (donelab));
2491 emit_label (neglab);
2493 emit_insn (gen_lshrdi3 (i0, in, const1_rtx));
2494 emit_insn (gen_anddi3 (i1, in, const1_rtx));
2495 emit_insn (gen_iordi3 (i0, i0, i1));
2496 emit_insn (gen_rtx_SET (VOIDmode, f0, gen_rtx_FLOAT (mode, i0)));
2497 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0)));
2499 emit_label (donelab);
2502 /* Generate the comparison for a conditional branch. */
2505 alpha_emit_conditional_branch (enum rtx_code code)
2507 enum rtx_code cmp_code, branch_code;
2508 enum machine_mode cmp_mode, branch_mode = VOIDmode;
2509 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
2512 if (alpha_compare.fp_p && GET_MODE (op0) == TFmode)
2514 if (! TARGET_HAS_XFLOATING_LIBS)
2517 /* X_floating library comparison functions return
2521 Convert the compare against the raw return value. */
2543 op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
2545 alpha_compare.fp_p = 0;
2548 /* The general case: fold the comparison code to the types of compares
2549 that we have, choosing the branch as necessary. */
2552 case EQ: case LE: case LT: case LEU: case LTU:
2554 /* We have these compares: */
2555 cmp_code = code, branch_code = NE;
2560 /* These must be reversed. */
2561 cmp_code = reverse_condition (code), branch_code = EQ;
2564 case GE: case GT: case GEU: case GTU:
2565 /* For FP, we swap them, for INT, we reverse them. */
2566 if (alpha_compare.fp_p)
2568 cmp_code = swap_condition (code);
2570 tem = op0, op0 = op1, op1 = tem;
2574 cmp_code = reverse_condition (code);
2583 if (alpha_compare.fp_p)
2586 if (flag_unsafe_math_optimizations)
2588 /* When we are not as concerned about non-finite values, and we
2589 are comparing against zero, we can branch directly. */
2590 if (op1 == CONST0_RTX (DFmode))
2591 cmp_code = UNKNOWN, branch_code = code;
2592 else if (op0 == CONST0_RTX (DFmode))
2594 /* Undo the swap we probably did just above. */
2595 tem = op0, op0 = op1, op1 = tem;
2596 branch_code = swap_condition (cmp_code);
2602 /* ??? We mark the branch mode to be CCmode to prevent the
2603 compare and branch from being combined, since the compare
2604 insn follows IEEE rules that the branch does not. */
2605 branch_mode = CCmode;
2612 /* The following optimizations are only for signed compares. */
2613 if (code != LEU && code != LTU && code != GEU && code != GTU)
2615 /* Whee. Compare and branch against 0 directly. */
2616 if (op1 == const0_rtx)
2617 cmp_code = UNKNOWN, branch_code = code;
2619 /* If the constants doesn't fit into an immediate, but can
2620 be generated by lda/ldah, we adjust the argument and
2621 compare against zero, so we can use beq/bne directly. */
2622 /* ??? Don't do this when comparing against symbols, otherwise
2623 we'll reduce (&x == 0x1234) to (&x-0x1234 == 0), which will
2624 be declared false out of hand (at least for non-weak). */
2625 else if (GET_CODE (op1) == CONST_INT
2626 && (code == EQ || code == NE)
2627 && !(symbolic_operand (op0, VOIDmode)
2628 || (GET_CODE (op0) == REG && REG_POINTER (op0))))
2630 HOST_WIDE_INT v = INTVAL (op1), n = -v;
2632 if (! CONST_OK_FOR_LETTER_P (v, 'I')
2633 && (CONST_OK_FOR_LETTER_P (n, 'K')
2634 || CONST_OK_FOR_LETTER_P (n, 'L')))
2636 cmp_code = PLUS, branch_code = code;
2642 if (!reg_or_0_operand (op0, DImode))
2643 op0 = force_reg (DImode, op0);
2644 if (cmp_code != PLUS && !reg_or_8bit_operand (op1, DImode))
2645 op1 = force_reg (DImode, op1);
2648 /* Emit an initial compare instruction, if necessary. */
2650 if (cmp_code != UNKNOWN)
2652 tem = gen_reg_rtx (cmp_mode);
2653 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
2656 /* Zero the operands. */
2657 memset (&alpha_compare, 0, sizeof (alpha_compare));
2659 /* Return the branch comparison. */
2660 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
2663 /* Certain simplifications can be done to make invalid setcc operations
2664 valid. Return the final comparison, or NULL if we can't work. */
2667 alpha_emit_setcc (enum rtx_code code)
2669 enum rtx_code cmp_code;
2670 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
2671 int fp_p = alpha_compare.fp_p;
2674 /* Zero the operands. */
2675 memset (&alpha_compare, 0, sizeof (alpha_compare));
2677 if (fp_p && GET_MODE (op0) == TFmode)
2679 if (! TARGET_HAS_XFLOATING_LIBS)
2682 /* X_floating library comparison functions return
2686 Convert the compare against the raw return value. */
2688 if (code == UNORDERED || code == ORDERED)
2693 op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
2697 if (code == UNORDERED)
2699 else if (code == ORDERED)
2705 if (fp_p && !TARGET_FIX)
2708 /* The general case: fold the comparison code to the types of compares
2709 that we have, choosing the branch as necessary. */
2714 case EQ: case LE: case LT: case LEU: case LTU:
2716 /* We have these compares. */
2718 cmp_code = code, code = NE;
2722 if (!fp_p && op1 == const0_rtx)
2727 cmp_code = reverse_condition (code);
2731 case GE: case GT: case GEU: case GTU:
2732 /* These normally need swapping, but for integer zero we have
2733 special patterns that recognize swapped operands. */
2734 if (!fp_p && op1 == const0_rtx)
2736 code = swap_condition (code);
2738 cmp_code = code, code = NE;
2739 tmp = op0, op0 = op1, op1 = tmp;
2748 if (!register_operand (op0, DImode))
2749 op0 = force_reg (DImode, op0);
2750 if (!reg_or_8bit_operand (op1, DImode))
2751 op1 = force_reg (DImode, op1);
2754 /* Emit an initial compare instruction, if necessary. */
2755 if (cmp_code != UNKNOWN)
2757 enum machine_mode mode = fp_p ? DFmode : DImode;
2759 tmp = gen_reg_rtx (mode);
2760 emit_insn (gen_rtx_SET (VOIDmode, tmp,
2761 gen_rtx_fmt_ee (cmp_code, mode, op0, op1)));
2763 op0 = fp_p ? gen_lowpart (DImode, tmp) : tmp;
2767 /* Return the setcc comparison. */
2768 return gen_rtx_fmt_ee (code, DImode, op0, op1);
2772 /* Rewrite a comparison against zero CMP of the form
2773 (CODE (cc0) (const_int 0)) so it can be written validly in
2774 a conditional move (if_then_else CMP ...).
2775 If both of the operands that set cc0 are nonzero we must emit
2776 an insn to perform the compare (it can't be done within
2777 the conditional move). */
2780 alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
2782 enum rtx_code code = GET_CODE (cmp);
2783 enum rtx_code cmov_code = NE;
2784 rtx op0 = alpha_compare.op0;
2785 rtx op1 = alpha_compare.op1;
2786 int fp_p = alpha_compare.fp_p;
2787 enum machine_mode cmp_mode
2788 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
2789 enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
2790 enum machine_mode cmov_mode = VOIDmode;
2791 int local_fast_math = flag_unsafe_math_optimizations;
2794 /* Zero the operands. */
2795 memset (&alpha_compare, 0, sizeof (alpha_compare));
2797 if (fp_p != FLOAT_MODE_P (mode))
2799 enum rtx_code cmp_code;
2804 /* If we have fp<->int register move instructions, do a cmov by
2805 performing the comparison in fp registers, and move the
2806 zero/nonzero value to integer registers, where we can then
2807 use a normal cmov, or vice-versa. */
2811 case EQ: case LE: case LT: case LEU: case LTU:
2812 /* We have these compares. */
2813 cmp_code = code, code = NE;
2817 /* This must be reversed. */
2818 cmp_code = EQ, code = EQ;
2821 case GE: case GT: case GEU: case GTU:
2822 /* These normally need swapping, but for integer zero we have
2823 special patterns that recognize swapped operands. */
2824 if (!fp_p && op1 == const0_rtx)
2825 cmp_code = code, code = NE;
2828 cmp_code = swap_condition (code);
2830 tem = op0, op0 = op1, op1 = tem;
2838 tem = gen_reg_rtx (cmp_op_mode);
2839 emit_insn (gen_rtx_SET (VOIDmode, tem,
2840 gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
2843 cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
2844 op0 = gen_lowpart (cmp_op_mode, tem);
2845 op1 = CONST0_RTX (cmp_op_mode);
2847 local_fast_math = 1;
2850 /* We may be able to use a conditional move directly.
2851 This avoids emitting spurious compares. */
2852 if (signed_comparison_operator (cmp, VOIDmode)
2853 && (!fp_p || local_fast_math)
2854 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
2855 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
2857 /* We can't put the comparison inside the conditional move;
2858 emit a compare instruction and put that inside the
2859 conditional move. Make sure we emit only comparisons we have;
2860 swap or reverse as necessary. */
2867 case EQ: case LE: case LT: case LEU: case LTU:
2868 /* We have these compares: */
2872 /* This must be reversed. */
2873 code = reverse_condition (code);
2877 case GE: case GT: case GEU: case GTU:
2878 /* These must be swapped. */
2879 if (op1 != CONST0_RTX (cmp_mode))
2881 code = swap_condition (code);
2882 tem = op0, op0 = op1, op1 = tem;
2892 if (!reg_or_0_operand (op0, DImode))
2893 op0 = force_reg (DImode, op0);
2894 if (!reg_or_8bit_operand (op1, DImode))
2895 op1 = force_reg (DImode, op1);
2898 /* ??? We mark the branch mode to be CCmode to prevent the compare
2899 and cmov from being combined, since the compare insn follows IEEE
2900 rules that the cmov does not. */
2901 if (fp_p && !local_fast_math)
2904 tem = gen_reg_rtx (cmp_op_mode);
2905 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
2906 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
2909 /* Simplify a conditional move of two constants into a setcc with
2910 arithmetic. This is done with a splitter since combine would
2911 just undo the work if done during code generation. It also catches
2912 cases we wouldn't have before cse. */
2915 alpha_split_conditional_move (enum rtx_code code, rtx dest, rtx cond,
2916 rtx t_rtx, rtx f_rtx)
2918 HOST_WIDE_INT t, f, diff;
2919 enum machine_mode mode;
2920 rtx target, subtarget, tmp;
2922 mode = GET_MODE (dest);
2927 if (((code == NE || code == EQ) && diff < 0)
2928 || (code == GE || code == GT))
2930 code = reverse_condition (code);
2931 diff = t, t = f, f = diff;
2935 subtarget = target = dest;
2938 target = gen_lowpart (DImode, dest);
2939 if (! no_new_pseudos)
2940 subtarget = gen_reg_rtx (DImode);
2944 /* Below, we must be careful to use copy_rtx on target and subtarget
2945 in intermediate insns, as they may be a subreg rtx, which may not
2948 if (f == 0 && exact_log2 (diff) > 0
2949 /* On EV6, we've got enough shifters to make non-arithmetic shifts
2950 viable over a longer latency cmove. On EV5, the E0 slot is a
2951 scarce resource, and on EV4 shift has the same latency as a cmove. */
2952 && (diff <= 8 || alpha_tune == PROCESSOR_EV6))
2954 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2955 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2957 tmp = gen_rtx_ASHIFT (DImode, copy_rtx (subtarget),
2958 GEN_INT (exact_log2 (t)));
2959 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
2961 else if (f == 0 && t == -1)
2963 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2964 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2966 emit_insn (gen_negdi2 (target, copy_rtx (subtarget)));
2968 else if (diff == 1 || diff == 4 || diff == 8)
2972 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2973 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2976 emit_insn (gen_adddi3 (target, copy_rtx (subtarget), GEN_INT (f)));
2979 add_op = GEN_INT (f);
2980 if (sext_add_operand (add_op, mode))
2982 tmp = gen_rtx_MULT (DImode, copy_rtx (subtarget),
2984 tmp = gen_rtx_PLUS (DImode, tmp, add_op);
2985 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
2997 /* Look up the function X_floating library function name for the
3000 struct xfloating_op GTY(())
3002 const enum rtx_code code;
3003 const char *const GTY((skip)) osf_func;
3004 const char *const GTY((skip)) vms_func;
3008 static GTY(()) struct xfloating_op xfloating_ops[] =
3010 { PLUS, "_OtsAddX", "OTS$ADD_X", 0 },
3011 { MINUS, "_OtsSubX", "OTS$SUB_X", 0 },
3012 { MULT, "_OtsMulX", "OTS$MUL_X", 0 },
3013 { DIV, "_OtsDivX", "OTS$DIV_X", 0 },
3014 { EQ, "_OtsEqlX", "OTS$EQL_X", 0 },
3015 { NE, "_OtsNeqX", "OTS$NEQ_X", 0 },
3016 { LT, "_OtsLssX", "OTS$LSS_X", 0 },
3017 { LE, "_OtsLeqX", "OTS$LEQ_X", 0 },
3018 { GT, "_OtsGtrX", "OTS$GTR_X", 0 },
3019 { GE, "_OtsGeqX", "OTS$GEQ_X", 0 },
3020 { FIX, "_OtsCvtXQ", "OTS$CVTXQ", 0 },
3021 { FLOAT, "_OtsCvtQX", "OTS$CVTQX", 0 },
3022 { UNSIGNED_FLOAT, "_OtsCvtQUX", "OTS$CVTQUX", 0 },
3023 { FLOAT_EXTEND, "_OtsConvertFloatTX", "OTS$CVT_FLOAT_T_X", 0 },
3024 { FLOAT_TRUNCATE, "_OtsConvertFloatXT", "OTS$CVT_FLOAT_X_T", 0 }
3027 static GTY(()) struct xfloating_op vax_cvt_ops[] =
3029 { FLOAT_EXTEND, "_OtsConvertFloatGX", "OTS$CVT_FLOAT_G_X", 0 },
3030 { FLOAT_TRUNCATE, "_OtsConvertFloatXG", "OTS$CVT_FLOAT_X_G", 0 }
3034 alpha_lookup_xfloating_lib_func (enum rtx_code code)
3036 struct xfloating_op *ops = xfloating_ops;
3037 long n = ARRAY_SIZE (xfloating_ops);
3040 /* How irritating. Nothing to key off for the main table. */
3041 if (TARGET_FLOAT_VAX && (code == FLOAT_EXTEND || code == FLOAT_TRUNCATE))
3044 n = ARRAY_SIZE (vax_cvt_ops);
3047 for (i = 0; i < n; ++i, ++ops)
3048 if (ops->code == code)
3050 rtx func = ops->libcall;
3053 func = init_one_libfunc (TARGET_ABI_OPEN_VMS
3054 ? ops->vms_func : ops->osf_func);
3055 ops->libcall = func;
3063 /* Most X_floating operations take the rounding mode as an argument.
3064 Compute that here. */
3067 alpha_compute_xfloating_mode_arg (enum rtx_code code,
3068 enum alpha_fp_rounding_mode round)
3074 case ALPHA_FPRM_NORM:
3077 case ALPHA_FPRM_MINF:
3080 case ALPHA_FPRM_CHOP:
3083 case ALPHA_FPRM_DYN:
3089 /* XXX For reference, round to +inf is mode = 3. */
3092 if (code == FLOAT_TRUNCATE && alpha_fptm == ALPHA_FPTM_N)
3098 /* Emit an X_floating library function call.
3100 Note that these functions do not follow normal calling conventions:
3101 TFmode arguments are passed in two integer registers (as opposed to
3102 indirect); TFmode return values appear in R16+R17.
3104 FUNC is the function to call.
3105 TARGET is where the output belongs.
3106 OPERANDS are the inputs.
3107 NOPERANDS is the count of inputs.
3108 EQUIV is the expression equivalent for the function.
3112 alpha_emit_xfloating_libcall (rtx func, rtx target, rtx operands[],
3113 int noperands, rtx equiv)
3115 rtx usage = NULL_RTX, tmp, reg;
3120 for (i = 0; i < noperands; ++i)
3122 switch (GET_MODE (operands[i]))
3125 reg = gen_rtx_REG (TFmode, regno);
3130 reg = gen_rtx_REG (DFmode, regno + 32);
3135 if (GET_CODE (operands[i]) != CONST_INT)
3139 reg = gen_rtx_REG (DImode, regno);
3147 emit_move_insn (reg, operands[i]);
3148 usage = alloc_EXPR_LIST (0, gen_rtx_USE (VOIDmode, reg), usage);
3151 switch (GET_MODE (target))
3154 reg = gen_rtx_REG (TFmode, 16);
3157 reg = gen_rtx_REG (DFmode, 32);
3160 reg = gen_rtx_REG (DImode, 0);
3166 tmp = gen_rtx_MEM (QImode, func);
3167 tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
3168 const0_rtx, const0_rtx));
3169 CALL_INSN_FUNCTION_USAGE (tmp) = usage;
3170 CONST_OR_PURE_CALL_P (tmp) = 1;
3175 emit_libcall_block (tmp, target, reg, equiv);
3178 /* Emit an X_floating library function call for arithmetic (+,-,*,/). */
3181 alpha_emit_xfloating_arith (enum rtx_code code, rtx operands[])
3185 rtx out_operands[3];
3187 func = alpha_lookup_xfloating_lib_func (code);
3188 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
3190 out_operands[0] = operands[1];
3191 out_operands[1] = operands[2];
3192 out_operands[2] = GEN_INT (mode);
3193 alpha_emit_xfloating_libcall (func, operands[0], out_operands, 3,
3194 gen_rtx_fmt_ee (code, TFmode, operands[1],
3198 /* Emit an X_floating library function call for a comparison. */
3201 alpha_emit_xfloating_compare (enum rtx_code code, rtx op0, rtx op1)
3204 rtx out, operands[2];
3206 func = alpha_lookup_xfloating_lib_func (code);
3210 out = gen_reg_rtx (DImode);
3212 /* ??? Strange mode for equiv because what's actually returned
3213 is -1,0,1, not a proper boolean value. */
3214 alpha_emit_xfloating_libcall (func, out, operands, 2,
3215 gen_rtx_fmt_ee (code, CCmode, op0, op1));
3220 /* Emit an X_floating library function call for a conversion. */
3223 alpha_emit_xfloating_cvt (enum rtx_code orig_code, rtx operands[])
3225 int noperands = 1, mode;
3226 rtx out_operands[2];
3228 enum rtx_code code = orig_code;
3230 if (code == UNSIGNED_FIX)
3233 func = alpha_lookup_xfloating_lib_func (code);
3235 out_operands[0] = operands[1];
3240 mode = alpha_compute_xfloating_mode_arg (code, ALPHA_FPRM_CHOP);
3241 out_operands[1] = GEN_INT (mode);
3244 case FLOAT_TRUNCATE:
3245 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
3246 out_operands[1] = GEN_INT (mode);
3253 alpha_emit_xfloating_libcall (func, operands[0], out_operands, noperands,
3254 gen_rtx_fmt_e (orig_code,
3255 GET_MODE (operands[0]),
3259 /* Split a TFmode OP[1] into DImode OP[2,3] and likewise for
3260 OP[0] into OP[0,1]. Naturally, output operand ordering is
3264 alpha_split_tfmode_pair (rtx operands[4])
3266 if (GET_CODE (operands[1]) == REG)
3268 operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
3269 operands[2] = gen_rtx_REG (DImode, REGNO (operands[1]));
3271 else if (GET_CODE (operands[1]) == MEM)
3273 operands[3] = adjust_address (operands[1], DImode, 8);
3274 operands[2] = adjust_address (operands[1], DImode, 0);
3276 else if (operands[1] == CONST0_RTX (TFmode))
3277 operands[2] = operands[3] = const0_rtx;
3281 if (GET_CODE (operands[0]) == REG)
3283 operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
3284 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
3286 else if (GET_CODE (operands[0]) == MEM)
3288 operands[1] = adjust_address (operands[0], DImode, 8);
3289 operands[0] = adjust_address (operands[0], DImode, 0);
3295 /* Implement negtf2 or abstf2. Op0 is destination, op1 is source,
3296 op2 is a register containing the sign bit, operation is the
3297 logical operation to be performed. */
3300 alpha_split_tfmode_frobsign (rtx operands[3], rtx (*operation) (rtx, rtx, rtx))
3302 rtx high_bit = operands[2];
3306 alpha_split_tfmode_pair (operands);
3308 /* Detect three flavors of operand overlap. */
3310 if (rtx_equal_p (operands[0], operands[2]))
3312 else if (rtx_equal_p (operands[1], operands[2]))
3314 if (rtx_equal_p (operands[0], high_bit))
3321 emit_move_insn (operands[0], operands[2]);
3323 /* ??? If the destination overlaps both source tf and high_bit, then
3324 assume source tf is dead in its entirety and use the other half
3325 for a scratch register. Otherwise "scratch" is just the proper
3326 destination register. */
3327 scratch = operands[move < 2 ? 1 : 3];
3329 emit_insn ((*operation) (scratch, high_bit, operands[3]));
3333 emit_move_insn (operands[0], operands[2]);
3335 emit_move_insn (operands[1], scratch);
3339 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
3343 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
3344 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
3345 lda r3,X(r11) lda r3,X+2(r11)
3346 extwl r1,r3,r1 extql r1,r3,r1
3347 extwh r2,r3,r2 extqh r2,r3,r2
3348 or r1.r2.r1 or r1,r2,r1
3351 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
3352 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
3353 lda r3,X(r11) lda r3,X(r11)
3354 extll r1,r3,r1 extll r1,r3,r1
3355 extlh r2,r3,r2 extlh r2,r3,r2
3356 or r1.r2.r1 addl r1,r2,r1
3358 quad: ldq_u r1,X(r11)
3367 alpha_expand_unaligned_load (rtx tgt, rtx mem, HOST_WIDE_INT size,
3368 HOST_WIDE_INT ofs, int sign)
3370 rtx meml, memh, addr, extl, exth, tmp, mema;
3371 enum machine_mode mode;
3373 if (TARGET_BWX && size == 2)
3375 meml = adjust_address (mem, QImode, ofs);
3376 memh = adjust_address (mem, QImode, ofs+1);
3377 if (BYTES_BIG_ENDIAN)
3378 tmp = meml, meml = memh, memh = tmp;
3379 extl = gen_reg_rtx (DImode);
3380 exth = gen_reg_rtx (DImode);
3381 emit_insn (gen_zero_extendqidi2 (extl, meml));
3382 emit_insn (gen_zero_extendqidi2 (exth, memh));
3383 exth = expand_simple_binop (DImode, ASHIFT, exth, GEN_INT (8),
3384 NULL, 1, OPTAB_LIB_WIDEN);
3385 addr = expand_simple_binop (DImode, IOR, extl, exth,
3386 NULL, 1, OPTAB_LIB_WIDEN);
3388 if (sign && GET_MODE (tgt) != HImode)
3390 addr = gen_lowpart (HImode, addr);
3391 emit_insn (gen_extend_insn (tgt, addr, GET_MODE (tgt), HImode, 0));
3395 if (GET_MODE (tgt) != DImode)
3396 addr = gen_lowpart (GET_MODE (tgt), addr);
3397 emit_move_insn (tgt, addr);
3402 meml = gen_reg_rtx (DImode);
3403 memh = gen_reg_rtx (DImode);
3404 addr = gen_reg_rtx (DImode);
3405 extl = gen_reg_rtx (DImode);
3406 exth = gen_reg_rtx (DImode);
3408 mema = XEXP (mem, 0);
3409 if (GET_CODE (mema) == LO_SUM)
3410 mema = force_reg (Pmode, mema);
3412 /* AND addresses cannot be in any alias set, since they may implicitly
3413 alias surrounding code. Ideally we'd have some alias set that
3414 covered all types except those with alignment 8 or higher. */
3416 tmp = change_address (mem, DImode,
3417 gen_rtx_AND (DImode,
3418 plus_constant (mema, ofs),
3420 set_mem_alias_set (tmp, 0);
3421 emit_move_insn (meml, tmp);
3423 tmp = change_address (mem, DImode,
3424 gen_rtx_AND (DImode,
3425 plus_constant (mema, ofs + size - 1),
3427 set_mem_alias_set (tmp, 0);
3428 emit_move_insn (memh, tmp);
3430 if (WORDS_BIG_ENDIAN && sign && (size == 2 || size == 4))
3432 emit_move_insn (addr, plus_constant (mema, -1));
3434 emit_insn (gen_extqh_be (extl, meml, addr));
3435 emit_insn (gen_extxl_be (exth, memh, GEN_INT (64), addr));
3437 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
3438 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (64 - size*8),
3439 addr, 1, OPTAB_WIDEN);
3441 else if (sign && size == 2)
3443 emit_move_insn (addr, plus_constant (mema, ofs+2));
3445 emit_insn (gen_extxl_le (extl, meml, GEN_INT (64), addr));
3446 emit_insn (gen_extqh_le (exth, memh, addr));
3448 /* We must use tgt here for the target. Alpha-vms port fails if we use
3449 addr for the target, because addr is marked as a pointer and combine
3450 knows that pointers are always sign-extended 32 bit values. */
3451 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
3452 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
3453 addr, 1, OPTAB_WIDEN);
3457 if (WORDS_BIG_ENDIAN)
3459 emit_move_insn (addr, plus_constant (mema, ofs+size-1));
3463 emit_insn (gen_extwh_be (extl, meml, addr));
3468 emit_insn (gen_extlh_be (extl, meml, addr));
3473 emit_insn (gen_extqh_be (extl, meml, addr));
3480 emit_insn (gen_extxl_be (exth, memh, GEN_INT (size*8), addr));
3484 emit_move_insn (addr, plus_constant (mema, ofs));
3485 emit_insn (gen_extxl_le (extl, meml, GEN_INT (size*8), addr));
3489 emit_insn (gen_extwh_le (exth, memh, addr));
3494 emit_insn (gen_extlh_le (exth, memh, addr));
3499 emit_insn (gen_extqh_le (exth, memh, addr));
3508 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
3509 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
3514 emit_move_insn (tgt, gen_lowpart (GET_MODE (tgt), addr));
3517 /* Similarly, use ins and msk instructions to perform unaligned stores. */
3520 alpha_expand_unaligned_store (rtx dst, rtx src,
3521 HOST_WIDE_INT size, HOST_WIDE_INT ofs)
3523 rtx dstl, dsth, addr, insl, insh, meml, memh, dsta;
3525 if (TARGET_BWX && size == 2)
3527 if (src != const0_rtx)
3529 dstl = gen_lowpart (QImode, src);
3530 dsth = expand_simple_binop (DImode, LSHIFTRT, src, GEN_INT (8),
3531 NULL, 1, OPTAB_LIB_WIDEN);
3532 dsth = gen_lowpart (QImode, dsth);
3535 dstl = dsth = const0_rtx;
3537 meml = adjust_address (dst, QImode, ofs);
3538 memh = adjust_address (dst, QImode, ofs+1);
3539 if (BYTES_BIG_ENDIAN)
3540 addr = meml, meml = memh, memh = addr;
3542 emit_move_insn (meml, dstl);
3543 emit_move_insn (memh, dsth);
3547 dstl = gen_reg_rtx (DImode);
3548 dsth = gen_reg_rtx (DImode);
3549 insl = gen_reg_rtx (DImode);
3550 insh = gen_reg_rtx (DImode);
3552 dsta = XEXP (dst, 0);
3553 if (GET_CODE (dsta) == LO_SUM)
3554 dsta = force_reg (Pmode, dsta);
3556 /* AND addresses cannot be in any alias set, since they may implicitly
3557 alias surrounding code. Ideally we'd have some alias set that
3558 covered all types except those with alignment 8 or higher. */
3560 meml = change_address (dst, DImode,
3561 gen_rtx_AND (DImode,
3562 plus_constant (dsta, ofs),
3564 set_mem_alias_set (meml, 0);
3566 memh = change_address (dst, DImode,
3567 gen_rtx_AND (DImode,
3568 plus_constant (dsta, ofs + size - 1),
3570 set_mem_alias_set (memh, 0);
3572 emit_move_insn (dsth, memh);
3573 emit_move_insn (dstl, meml);
3574 if (WORDS_BIG_ENDIAN)
3576 addr = copy_addr_to_reg (plus_constant (dsta, ofs+size-1));
3578 if (src != const0_rtx)
3583 emit_insn (gen_inswl_be (insh, gen_lowpart (HImode,src), addr));
3586 emit_insn (gen_insll_be (insh, gen_lowpart (SImode,src), addr));
3589 emit_insn (gen_insql_be (insh, gen_lowpart (DImode,src), addr));
3592 emit_insn (gen_insxh (insl, gen_lowpart (DImode, src),
3593 GEN_INT (size*8), addr));
3599 emit_insn (gen_mskxl_be (dsth, dsth, GEN_INT (0xffff), addr));
3603 rtx msk = immed_double_const (0xffffffff, 0, DImode);
3604 emit_insn (gen_mskxl_be (dsth, dsth, msk, addr));
3608 emit_insn (gen_mskxl_be (dsth, dsth, constm1_rtx, addr));
3612 emit_insn (gen_mskxh (dstl, dstl, GEN_INT (size*8), addr));
3616 addr = copy_addr_to_reg (plus_constant (dsta, ofs));
3618 if (src != CONST0_RTX (GET_MODE (src)))
3620 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
3621 GEN_INT (size*8), addr));
3626 emit_insn (gen_inswl_le (insl, gen_lowpart (HImode, src), addr));
3629 emit_insn (gen_insll_le (insl, gen_lowpart (SImode, src), addr));
3632 emit_insn (gen_insql_le (insl, src, addr));
3637 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
3642 emit_insn (gen_mskxl_le (dstl, dstl, GEN_INT (0xffff), addr));
3646 rtx msk = immed_double_const (0xffffffff, 0, DImode);
3647 emit_insn (gen_mskxl_le (dstl, dstl, msk, addr));
3651 emit_insn (gen_mskxl_le (dstl, dstl, constm1_rtx, addr));
3656 if (src != CONST0_RTX (GET_MODE (src)))
3658 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
3659 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
3662 if (WORDS_BIG_ENDIAN)
3664 emit_move_insn (meml, dstl);
3665 emit_move_insn (memh, dsth);
3669 /* Must store high before low for degenerate case of aligned. */
3670 emit_move_insn (memh, dsth);
3671 emit_move_insn (meml, dstl);
3675 /* The block move code tries to maximize speed by separating loads and
3676 stores at the expense of register pressure: we load all of the data
3677 before we store it back out. There are two secondary effects worth
3678 mentioning, that this speeds copying to/from aligned and unaligned
3679 buffers, and that it makes the code significantly easier to write. */
3681 #define MAX_MOVE_WORDS 8
3683 /* Load an integral number of consecutive unaligned quadwords. */
3686 alpha_expand_unaligned_load_words (rtx *out_regs, rtx smem,
3687 HOST_WIDE_INT words, HOST_WIDE_INT ofs)
3689 rtx const im8 = GEN_INT (-8);
3690 rtx const i64 = GEN_INT (64);
3691 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
3692 rtx sreg, areg, tmp, smema;
3695 smema = XEXP (smem, 0);
3696 if (GET_CODE (smema) == LO_SUM)
3697 smema = force_reg (Pmode, smema);
3699 /* Generate all the tmp registers we need. */
3700 for (i = 0; i < words; ++i)
3702 data_regs[i] = out_regs[i];
3703 ext_tmps[i] = gen_reg_rtx (DImode);
3705 data_regs[words] = gen_reg_rtx (DImode);
3708 smem = adjust_address (smem, GET_MODE (smem), ofs);
3710 /* Load up all of the source data. */
3711 for (i = 0; i < words; ++i)
3713 tmp = change_address (smem, DImode,
3714 gen_rtx_AND (DImode,
3715 plus_constant (smema, 8*i),
3717 set_mem_alias_set (tmp, 0);
3718 emit_move_insn (data_regs[i], tmp);
3721 tmp = change_address (smem, DImode,
3722 gen_rtx_AND (DImode,
3723 plus_constant (smema, 8*words - 1),
3725 set_mem_alias_set (tmp, 0);
3726 emit_move_insn (data_regs[words], tmp);
3728 /* Extract the half-word fragments. Unfortunately DEC decided to make
3729 extxh with offset zero a noop instead of zeroing the register, so
3730 we must take care of that edge condition ourselves with cmov. */
3732 sreg = copy_addr_to_reg (smema);
3733 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
3735 if (WORDS_BIG_ENDIAN)
3736 emit_move_insn (sreg, plus_constant (sreg, 7));
3737 for (i = 0; i < words; ++i)
3739 if (WORDS_BIG_ENDIAN)
3741 emit_insn (gen_extqh_be (data_regs[i], data_regs[i], sreg));
3742 emit_insn (gen_extxl_be (ext_tmps[i], data_regs[i+1], i64, sreg));
3746 emit_insn (gen_extxl_le (data_regs[i], data_regs[i], i64, sreg));
3747 emit_insn (gen_extqh_le (ext_tmps[i], data_regs[i+1], sreg));
3749 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
3750 gen_rtx_IF_THEN_ELSE (DImode,
3751 gen_rtx_EQ (DImode, areg,
3753 const0_rtx, ext_tmps[i])));
3756 /* Merge the half-words into whole words. */
3757 for (i = 0; i < words; ++i)
3759 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
3760 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
3764 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
3765 may be NULL to store zeros. */
3768 alpha_expand_unaligned_store_words (rtx *data_regs, rtx dmem,
3769 HOST_WIDE_INT words, HOST_WIDE_INT ofs)
3771 rtx const im8 = GEN_INT (-8);
3772 rtx const i64 = GEN_INT (64);
3773 rtx ins_tmps[MAX_MOVE_WORDS];
3774 rtx st_tmp_1, st_tmp_2, dreg;
3775 rtx st_addr_1, st_addr_2, dmema;
3778 dmema = XEXP (dmem, 0);
3779 if (GET_CODE (dmema) == LO_SUM)
3780 dmema = force_reg (Pmode, dmema);
3782 /* Generate all the tmp registers we need. */
3783 if (data_regs != NULL)
3784 for (i = 0; i < words; ++i)
3785 ins_tmps[i] = gen_reg_rtx(DImode);
3786 st_tmp_1 = gen_reg_rtx(DImode);
3787 st_tmp_2 = gen_reg_rtx(DImode);
3790 dmem = adjust_address (dmem, GET_MODE (dmem), ofs);
3792 st_addr_2 = change_address (dmem, DImode,
3793 gen_rtx_AND (DImode,
3794 plus_constant (dmema, words*8 - 1),
3796 set_mem_alias_set (st_addr_2, 0);
3798 st_addr_1 = change_address (dmem, DImode,
3799 gen_rtx_AND (DImode, dmema, im8));
3800 set_mem_alias_set (st_addr_1, 0);
3802 /* Load up the destination end bits. */
3803 emit_move_insn (st_tmp_2, st_addr_2);
3804 emit_move_insn (st_tmp_1, st_addr_1);
3806 /* Shift the input data into place. */
3807 dreg = copy_addr_to_reg (dmema);
3808 if (WORDS_BIG_ENDIAN)
3809 emit_move_insn (dreg, plus_constant (dreg, 7));
3810 if (data_regs != NULL)
3812 for (i = words-1; i >= 0; --i)
3814 if (WORDS_BIG_ENDIAN)
3816 emit_insn (gen_insql_be (ins_tmps[i], data_regs[i], dreg));
3817 emit_insn (gen_insxh (data_regs[i], data_regs[i], i64, dreg));
3821 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
3822 emit_insn (gen_insql_le (data_regs[i], data_regs[i], dreg));
3825 for (i = words-1; i > 0; --i)
3827 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
3828 ins_tmps[i-1], ins_tmps[i-1], 1,
3833 /* Split and merge the ends with the destination data. */
3834 if (WORDS_BIG_ENDIAN)
3836 emit_insn (gen_mskxl_be (st_tmp_2, st_tmp_2, constm1_rtx, dreg));
3837 emit_insn (gen_mskxh (st_tmp_1, st_tmp_1, i64, dreg));
3841 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
3842 emit_insn (gen_mskxl_le (st_tmp_1, st_tmp_1, constm1_rtx, dreg));
3845 if (data_regs != NULL)
3847 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
3848 st_tmp_2, 1, OPTAB_WIDEN);
3849 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
3850 st_tmp_1, 1, OPTAB_WIDEN);
3854 if (WORDS_BIG_ENDIAN)
3855 emit_move_insn (st_addr_1, st_tmp_1);
3857 emit_move_insn (st_addr_2, st_tmp_2);
3858 for (i = words-1; i > 0; --i)
3860 rtx tmp = change_address (dmem, DImode,
3861 gen_rtx_AND (DImode,
3862 plus_constant(dmema,
3863 WORDS_BIG_ENDIAN ? i*8-1 : i*8),
3865 set_mem_alias_set (tmp, 0);
3866 emit_move_insn (tmp, data_regs ? ins_tmps[i-1] : const0_rtx);
3868 if (WORDS_BIG_ENDIAN)
3869 emit_move_insn (st_addr_2, st_tmp_2);
3871 emit_move_insn (st_addr_1, st_tmp_1);
3875 /* Expand string/block move operations.
3877 operands[0] is the pointer to the destination.
3878 operands[1] is the pointer to the source.
3879 operands[2] is the number of bytes to move.
3880 operands[3] is the alignment. */
3883 alpha_expand_block_move (rtx operands[])
3885 rtx bytes_rtx = operands[2];
3886 rtx align_rtx = operands[3];
3887 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
3888 HOST_WIDE_INT bytes = orig_bytes;
3889 HOST_WIDE_INT src_align = INTVAL (align_rtx) * BITS_PER_UNIT;
3890 HOST_WIDE_INT dst_align = src_align;
3891 rtx orig_src = operands[1];
3892 rtx orig_dst = operands[0];
3893 rtx data_regs[2 * MAX_MOVE_WORDS + 16];
3895 unsigned int i, words, ofs, nregs = 0;
3897 if (orig_bytes <= 0)
3899 else if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
3902 /* Look for additional alignment information from recorded register info. */
3904 tmp = XEXP (orig_src, 0);
3905 if (GET_CODE (tmp) == REG)
3906 src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3907 else if (GET_CODE (tmp) == PLUS
3908 && GET_CODE (XEXP (tmp, 0)) == REG
3909 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3911 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3912 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3916 if (a >= 64 && c % 8 == 0)
3918 else if (a >= 32 && c % 4 == 0)
3920 else if (a >= 16 && c % 2 == 0)
3925 tmp = XEXP (orig_dst, 0);
3926 if (GET_CODE (tmp) == REG)
3927 dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3928 else if (GET_CODE (tmp) == PLUS
3929 && GET_CODE (XEXP (tmp, 0)) == REG
3930 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3932 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3933 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3937 if (a >= 64 && c % 8 == 0)
3939 else if (a >= 32 && c % 4 == 0)
3941 else if (a >= 16 && c % 2 == 0)
3947 if (src_align >= 64 && bytes >= 8)
3951 for (i = 0; i < words; ++i)
3952 data_regs[nregs + i] = gen_reg_rtx (DImode);
3954 for (i = 0; i < words; ++i)
3955 emit_move_insn (data_regs[nregs + i],
3956 adjust_address (orig_src, DImode, ofs + i * 8));
3963 if (src_align >= 32 && bytes >= 4)
3967 for (i = 0; i < words; ++i)
3968 data_regs[nregs + i] = gen_reg_rtx (SImode);
3970 for (i = 0; i < words; ++i)
3971 emit_move_insn (data_regs[nregs + i],
3972 adjust_address (orig_src, SImode, ofs + i * 4));
3983 for (i = 0; i < words+1; ++i)
3984 data_regs[nregs + i] = gen_reg_rtx (DImode);
3986 alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,
3994 if (! TARGET_BWX && bytes >= 4)
3996 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
3997 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
4004 if (src_align >= 16)
4007 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
4008 emit_move_insn (tmp, adjust_address (orig_src, HImode, ofs));
4011 } while (bytes >= 2);
4013 else if (! TARGET_BWX)
4015 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
4016 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
4024 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
4025 emit_move_insn (tmp, adjust_address (orig_src, QImode, ofs));
4030 if (nregs > ARRAY_SIZE (data_regs))
4033 /* Now save it back out again. */
4037 /* Write out the data in whatever chunks reading the source allowed. */
4038 if (dst_align >= 64)
4040 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
4042 emit_move_insn (adjust_address (orig_dst, DImode, ofs),
4049 if (dst_align >= 32)
4051 /* If the source has remaining DImode regs, write them out in
4053 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
4055 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
4056 NULL_RTX, 1, OPTAB_WIDEN);
4058 emit_move_insn (adjust_address (orig_dst, SImode, ofs),
4059 gen_lowpart (SImode, data_regs[i]));
4060 emit_move_insn (adjust_address (orig_dst, SImode, ofs + 4),
4061 gen_lowpart (SImode, tmp));
4066 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
4068 emit_move_insn (adjust_address (orig_dst, SImode, ofs),
4075 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
4077 /* Write out a remaining block of words using unaligned methods. */
4079 for (words = 1; i + words < nregs; words++)
4080 if (GET_MODE (data_regs[i + words]) != DImode)
4084 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
4086 alpha_expand_unaligned_store_words (data_regs + i, orig_dst,
4093 /* Due to the above, this won't be aligned. */
4094 /* ??? If we have more than one of these, consider constructing full
4095 words in registers and using alpha_expand_unaligned_store_words. */
4096 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
4098 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
4103 if (dst_align >= 16)
4104 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
4106 emit_move_insn (adjust_address (orig_dst, HImode, ofs), data_regs[i]);
4111 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
4113 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
4118 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
4120 emit_move_insn (adjust_address (orig_dst, QImode, ofs), data_regs[i]);
4132 alpha_expand_block_clear (rtx operands[])
4134 rtx bytes_rtx = operands[1];
4135 rtx align_rtx = operands[2];
4136 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
4137 HOST_WIDE_INT bytes = orig_bytes;
4138 HOST_WIDE_INT align = INTVAL (align_rtx) * BITS_PER_UNIT;
4139 HOST_WIDE_INT alignofs = 0;
4140 rtx orig_dst = operands[0];
4142 int i, words, ofs = 0;
4144 if (orig_bytes <= 0)
4146 if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
4149 /* Look for stricter alignment. */
4150 tmp = XEXP (orig_dst, 0);
4151 if (GET_CODE (tmp) == REG)
4152 align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp)));
4153 else if (GET_CODE (tmp) == PLUS
4154 && GET_CODE (XEXP (tmp, 0)) == REG
4155 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
4157 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
4158 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
4163 align = a, alignofs = 8 - c % 8;
4165 align = a, alignofs = 4 - c % 4;
4167 align = a, alignofs = 2 - c % 2;
4171 /* Handle an unaligned prefix first. */
4175 #if HOST_BITS_PER_WIDE_INT >= 64
4176 /* Given that alignofs is bounded by align, the only time BWX could
4177 generate three stores is for a 7 byte fill. Prefer two individual
4178 stores over a load/mask/store sequence. */
4179 if ((!TARGET_BWX || alignofs == 7)
4181 && !(alignofs == 4 && bytes >= 4))
4183 enum machine_mode mode = (align >= 64 ? DImode : SImode);
4184 int inv_alignofs = (align >= 64 ? 8 : 4) - alignofs;
4188 mem = adjust_address (orig_dst, mode, ofs - inv_alignofs);
4189 set_mem_alias_set (mem, 0);
4191 mask = ~(~(HOST_WIDE_INT)0 << (inv_alignofs * 8));
4192 if (bytes < alignofs)
4194 mask |= ~(HOST_WIDE_INT)0 << ((inv_alignofs + bytes) * 8);
4205 tmp = expand_binop (mode, and_optab, mem, GEN_INT (mask),
4206 NULL_RTX, 1, OPTAB_WIDEN);
4208 emit_move_insn (mem, tmp);
4212 if (TARGET_BWX && (alignofs & 1) && bytes >= 1)
4214 emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
4219 if (TARGET_BWX && align >= 16 && (alignofs & 3) == 2 && bytes >= 2)
4221 emit_move_insn (adjust_address (orig_dst, HImode, ofs), const0_rtx);
4226 if (alignofs == 4 && bytes >= 4)
4228 emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
4234 /* If we've not used the extra lead alignment information by now,
4235 we won't be able to. Downgrade align to match what's left over. */
4238 alignofs = alignofs & -alignofs;
4239 align = MIN (align, alignofs * BITS_PER_UNIT);
4243 /* Handle a block of contiguous long-words. */
4245 if (align >= 64 && bytes >= 8)
4249 for (i = 0; i < words; ++i)
4250 emit_move_insn (adjust_address (orig_dst, DImode, ofs + i * 8),
4257 /* If the block is large and appropriately aligned, emit a single
4258 store followed by a sequence of stq_u insns. */
4260 if (align >= 32 && bytes > 16)
4264 emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
4268 orig_dsta = XEXP (orig_dst, 0);
4269 if (GET_CODE (orig_dsta) == LO_SUM)
4270 orig_dsta = force_reg (Pmode, orig_dsta);
4273 for (i = 0; i < words; ++i)
4276 = change_address (orig_dst, DImode,
4277 gen_rtx_AND (DImode,
4278 plus_constant (orig_dsta, ofs + i*8),
4280 set_mem_alias_set (mem, 0);
4281 emit_move_insn (mem, const0_rtx);
4284 /* Depending on the alignment, the first stq_u may have overlapped
4285 with the initial stl, which means that the last stq_u didn't
4286 write as much as it would appear. Leave those questionable bytes
4288 bytes -= words * 8 - 4;
4289 ofs += words * 8 - 4;
4292 /* Handle a smaller block of aligned words. */
4294 if ((align >= 64 && bytes == 4)
4295 || (align == 32 && bytes >= 4))
4299 for (i = 0; i < words; ++i)
4300 emit_move_insn (adjust_address (orig_dst, SImode, ofs + i * 4),
4307 /* An unaligned block uses stq_u stores for as many as possible. */
4313 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
4319 /* Next clean up any trailing pieces. */
4321 #if HOST_BITS_PER_WIDE_INT >= 64
4322 /* Count the number of bits in BYTES for which aligned stores could
4325 for (i = (TARGET_BWX ? 1 : 4); i * BITS_PER_UNIT <= align ; i <<= 1)
4329 /* If we have appropriate alignment (and it wouldn't take too many
4330 instructions otherwise), mask out the bytes we need. */
4331 if (TARGET_BWX ? words > 2 : bytes > 0)
4338 mem = adjust_address (orig_dst, DImode, ofs);
4339 set_mem_alias_set (mem, 0);
4341 mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
4343 tmp = expand_binop (DImode, and_optab, mem, GEN_INT (mask),
4344 NULL_RTX, 1, OPTAB_WIDEN);
4346 emit_move_insn (mem, tmp);
4349 else if (align >= 32 && bytes < 4)
4354 mem = adjust_address (orig_dst, SImode, ofs);
4355 set_mem_alias_set (mem, 0);
4357 mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
4359 tmp = expand_binop (SImode, and_optab, mem, GEN_INT (mask),
4360 NULL_RTX, 1, OPTAB_WIDEN);
4362 emit_move_insn (mem, tmp);
4368 if (!TARGET_BWX && bytes >= 4)
4370 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
4380 emit_move_insn (adjust_address (orig_dst, HImode, ofs),
4384 } while (bytes >= 2);
4386 else if (! TARGET_BWX)
4388 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
4396 emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
4404 /* Returns a mask so that zap(x, value) == x & mask. */
4407 alpha_expand_zap_mask (HOST_WIDE_INT value)
4412 if (HOST_BITS_PER_WIDE_INT >= 64)
4414 HOST_WIDE_INT mask = 0;
4416 for (i = 7; i >= 0; --i)
4419 if (!((value >> i) & 1))
4423 result = gen_int_mode (mask, DImode);
4425 else if (HOST_BITS_PER_WIDE_INT == 32)
4427 HOST_WIDE_INT mask_lo = 0, mask_hi = 0;
4429 for (i = 7; i >= 4; --i)
4432 if (!((value >> i) & 1))
4436 for (i = 3; i >= 0; --i)
4439 if (!((value >> i) & 1))
4443 result = immed_double_const (mask_lo, mask_hi, DImode);
4452 alpha_expand_builtin_vector_binop (rtx (*gen) (rtx, rtx, rtx),
4453 enum machine_mode mode,
4454 rtx op0, rtx op1, rtx op2)
4456 op0 = gen_lowpart (mode, op0);
4458 if (op1 == const0_rtx)
4459 op1 = CONST0_RTX (mode);
4461 op1 = gen_lowpart (mode, op1);
4463 if (op2 == const0_rtx)
4464 op2 = CONST0_RTX (mode);
4466 op2 = gen_lowpart (mode, op2);
4468 emit_insn ((*gen) (op0, op1, op2));
4471 /* Adjust the cost of a scheduling dependency. Return the new cost of
4472 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
4475 alpha_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
4477 enum attr_type insn_type, dep_insn_type;
4479 /* If the dependence is an anti-dependence, there is no cost. For an
4480 output dependence, there is sometimes a cost, but it doesn't seem
4481 worth handling those few cases. */
4482 if (REG_NOTE_KIND (link) != 0)
4485 /* If we can't recognize the insns, we can't really do anything. */
4486 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
4489 insn_type = get_attr_type (insn);
4490 dep_insn_type = get_attr_type (dep_insn);
4492 /* Bring in the user-defined memory latency. */
4493 if (dep_insn_type == TYPE_ILD
4494 || dep_insn_type == TYPE_FLD
4495 || dep_insn_type == TYPE_LDSYM)
4496 cost += alpha_memory_latency-1;
4498 /* Everything else handled in DFA bypasses now. */
4503 /* The number of instructions that can be issued per cycle. */
4506 alpha_issue_rate (void)
4508 return (alpha_tune == PROCESSOR_EV4 ? 2 : 4);
4511 /* How many alternative schedules to try. This should be as wide as the
4512 scheduling freedom in the DFA, but no wider. Making this value too
4513 large results extra work for the scheduler.
4515 For EV4, loads can be issued to either IB0 or IB1, thus we have 2
4516 alternative schedules. For EV5, we can choose between E0/E1 and
4517 FA/FM. For EV6, an arithmetic insn can be issued to U0/U1/L0/L1. */
4520 alpha_multipass_dfa_lookahead (void)
4522 return (alpha_tune == PROCESSOR_EV6 ? 4 : 2);
4525 /* Machine-specific function data. */
4527 struct machine_function GTY(())
4530 /* List of call information words for calls from this function. */
4531 struct rtx_def *first_ciw;
4532 struct rtx_def *last_ciw;
4535 /* List of deferred case vectors. */
4536 struct rtx_def *addr_list;
4539 const char *some_ld_name;
4541 /* For TARGET_LD_BUGGY_LDGP. */
4542 struct rtx_def *gp_save_rtx;
4545 /* How to allocate a 'struct machine_function'. */
4547 static struct machine_function *
4548 alpha_init_machine_status (void)
4550 return ((struct machine_function *)
4551 ggc_alloc_cleared (sizeof (struct machine_function)));
4554 /* Functions to save and restore alpha_return_addr_rtx. */
4556 /* Start the ball rolling with RETURN_ADDR_RTX. */
4559 alpha_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
4564 return get_hard_reg_initial_val (Pmode, REG_RA);
4567 /* Return or create a memory slot containing the gp value for the current
4568 function. Needed only if TARGET_LD_BUGGY_LDGP. */
4571 alpha_gp_save_rtx (void)
4573 rtx seq, m = cfun->machine->gp_save_rtx;
4579 m = assign_stack_local (DImode, UNITS_PER_WORD, BITS_PER_WORD);
4580 m = validize_mem (m);
4581 emit_move_insn (m, pic_offset_table_rtx);
4585 emit_insn_after (seq, entry_of_function ());
4587 cfun->machine->gp_save_rtx = m;
4594 alpha_ra_ever_killed (void)
4598 if (!has_hard_reg_initial_val (Pmode, REG_RA))
4599 return regs_ever_live[REG_RA];
4601 push_topmost_sequence ();
4603 pop_topmost_sequence ();
4605 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
4609 /* Return the trap mode suffix applicable to the current
4610 instruction, or NULL. */
4613 get_trap_mode_suffix (void)
4615 enum attr_trap_suffix s = get_attr_trap_suffix (current_output_insn);
4619 case TRAP_SUFFIX_NONE:
4622 case TRAP_SUFFIX_SU:
4623 if (alpha_fptm >= ALPHA_FPTM_SU)
4627 case TRAP_SUFFIX_SUI:
4628 if (alpha_fptm >= ALPHA_FPTM_SUI)
4632 case TRAP_SUFFIX_V_SV:
4640 case ALPHA_FPTM_SUI:
4645 case TRAP_SUFFIX_V_SV_SVI:
4654 case ALPHA_FPTM_SUI:
4659 case TRAP_SUFFIX_U_SU_SUI:
4668 case ALPHA_FPTM_SUI:
4676 /* Return the rounding mode suffix applicable to the current
4677 instruction, or NULL. */
4680 get_round_mode_suffix (void)
4682 enum attr_round_suffix s = get_attr_round_suffix (current_output_insn);
4686 case ROUND_SUFFIX_NONE:
4688 case ROUND_SUFFIX_NORMAL:
4691 case ALPHA_FPRM_NORM:
4693 case ALPHA_FPRM_MINF:
4695 case ALPHA_FPRM_CHOP:
4697 case ALPHA_FPRM_DYN:
4702 case ROUND_SUFFIX_C:
4708 /* Locate some local-dynamic symbol still in use by this function
4709 so that we can print its name in some movdi_er_tlsldm pattern. */
4712 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
4716 if (GET_CODE (x) == SYMBOL_REF
4717 && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
4719 cfun->machine->some_ld_name = XSTR (x, 0);
4727 get_some_local_dynamic_name (void)
4731 if (cfun->machine->some_ld_name)
4732 return cfun->machine->some_ld_name;
4734 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
4736 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
4737 return cfun->machine->some_ld_name;
4742 /* Print an operand. Recognize special options, documented below. */
4745 print_operand (FILE *file, rtx x, int code)
4752 /* Print the assembler name of the current function. */
4753 assemble_name (file, alpha_fnname);
4757 assemble_name (file, get_some_local_dynamic_name ());
4762 const char *trap = get_trap_mode_suffix ();
4763 const char *round = get_round_mode_suffix ();
4766 fprintf (file, (TARGET_AS_SLASH_BEFORE_SUFFIX ? "/%s%s" : "%s%s"),
4767 (trap ? trap : ""), (round ? round : ""));
4772 /* Generates single precision instruction suffix. */
4773 fputc ((TARGET_FLOAT_VAX ? 'f' : 's'), file);
4777 /* Generates double precision instruction suffix. */
4778 fputc ((TARGET_FLOAT_VAX ? 'g' : 't'), file);
4782 /* Generates a nop after a noreturn call at the very end of the
4784 if (next_real_insn (current_output_insn) == 0)
4785 fprintf (file, "\n\tnop");
4789 if (alpha_this_literal_sequence_number == 0)
4790 alpha_this_literal_sequence_number = alpha_next_sequence_number++;
4791 fprintf (file, "%d", alpha_this_literal_sequence_number);
4795 if (alpha_this_gpdisp_sequence_number == 0)
4796 alpha_this_gpdisp_sequence_number = alpha_next_sequence_number++;
4797 fprintf (file, "%d", alpha_this_gpdisp_sequence_number);
4801 if (GET_CODE (x) == HIGH)
4802 output_addr_const (file, XEXP (x, 0));
4804 output_operand_lossage ("invalid %%H value");
4811 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD_CALL)
4813 x = XVECEXP (x, 0, 0);
4814 lituse = "lituse_tlsgd";
4816 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM_CALL)
4818 x = XVECEXP (x, 0, 0);
4819 lituse = "lituse_tlsldm";
4821 else if (GET_CODE (x) == CONST_INT)
4822 lituse = "lituse_jsr";
4825 output_operand_lossage ("invalid %%J value");
4829 if (x != const0_rtx)
4830 fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x));
4835 /* If this operand is the constant zero, write it as "$31". */
4836 if (GET_CODE (x) == REG)
4837 fprintf (file, "%s", reg_names[REGNO (x)]);
4838 else if (x == CONST0_RTX (GET_MODE (x)))
4839 fprintf (file, "$31");
4841 output_operand_lossage ("invalid %%r value");
4845 /* Similar, but for floating-point. */
4846 if (GET_CODE (x) == REG)
4847 fprintf (file, "%s", reg_names[REGNO (x)]);
4848 else if (x == CONST0_RTX (GET_MODE (x)))
4849 fprintf (file, "$f31");
4851 output_operand_lossage ("invalid %%R value");
4855 /* Write the 1's complement of a constant. */
4856 if (GET_CODE (x) != CONST_INT)
4857 output_operand_lossage ("invalid %%N value");
4859 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
4863 /* Write 1 << C, for a constant C. */
4864 if (GET_CODE (x) != CONST_INT)
4865 output_operand_lossage ("invalid %%P value");
4867 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
4871 /* Write the high-order 16 bits of a constant, sign-extended. */
4872 if (GET_CODE (x) != CONST_INT)
4873 output_operand_lossage ("invalid %%h value");
4875 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
4879 /* Write the low-order 16 bits of a constant, sign-extended. */
4880 if (GET_CODE (x) != CONST_INT)
4881 output_operand_lossage ("invalid %%L value");
4883 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4884 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
4888 /* Write mask for ZAP insn. */
4889 if (GET_CODE (x) == CONST_DOUBLE)
4891 HOST_WIDE_INT mask = 0;
4892 HOST_WIDE_INT value;
4894 value = CONST_DOUBLE_LOW (x);
4895 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
4900 value = CONST_DOUBLE_HIGH (x);
4901 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
4904 mask |= (1 << (i + sizeof (int)));
4906 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
4909 else if (GET_CODE (x) == CONST_INT)
4911 HOST_WIDE_INT mask = 0, value = INTVAL (x);
4913 for (i = 0; i < 8; i++, value >>= 8)
4917 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
4920 output_operand_lossage ("invalid %%m value");
4924 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
4925 if (GET_CODE (x) != CONST_INT
4926 || (INTVAL (x) != 8 && INTVAL (x) != 16
4927 && INTVAL (x) != 32 && INTVAL (x) != 64))
4928 output_operand_lossage ("invalid %%M value");
4930 fprintf (file, "%s",
4931 (INTVAL (x) == 8 ? "b"
4932 : INTVAL (x) == 16 ? "w"
4933 : INTVAL (x) == 32 ? "l"
4938 /* Similar, except do it from the mask. */
4939 if (GET_CODE (x) == CONST_INT)
4941 HOST_WIDE_INT value = INTVAL (x);
4948 if (value == 0xffff)
4953 if (value == 0xffffffff)
4964 else if (HOST_BITS_PER_WIDE_INT == 32
4965 && GET_CODE (x) == CONST_DOUBLE
4966 && CONST_DOUBLE_LOW (x) == 0xffffffff
4967 && CONST_DOUBLE_HIGH (x) == 0)
4972 output_operand_lossage ("invalid %%U value");
4976 /* Write the constant value divided by 8 for little-endian mode or
4977 (56 - value) / 8 for big-endian mode. */
4979 if (GET_CODE (x) != CONST_INT
4980 || (unsigned HOST_WIDE_INT) INTVAL (x) >= (WORDS_BIG_ENDIAN
4983 || (INTVAL (x) & 7) != 0)
4984 output_operand_lossage ("invalid %%s value");
4986 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4988 ? (56 - INTVAL (x)) / 8
4993 /* Same, except compute (64 - c) / 8 */
4995 if (GET_CODE (x) != CONST_INT
4996 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
4997 && (INTVAL (x) & 7) != 8)
4998 output_operand_lossage ("invalid %%s value");
5000 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
5005 /* On Unicos/Mk systems: use a DEX expression if the symbol
5006 clashes with a register name. */
5007 int dex = unicosmk_need_dex (x);
5009 fprintf (file, "DEX(%d)", dex);
5011 output_addr_const (file, x);
5015 case 'C': case 'D': case 'c': case 'd':
5016 /* Write out comparison name. */
5018 enum rtx_code c = GET_CODE (x);
5020 if (!COMPARISON_P (x))
5021 output_operand_lossage ("invalid %%C value");
5023 else if (code == 'D')
5024 c = reverse_condition (c);
5025 else if (code == 'c')
5026 c = swap_condition (c);
5027 else if (code == 'd')
5028 c = swap_condition (reverse_condition (c));
5031 fprintf (file, "ule");
5033 fprintf (file, "ult");
5034 else if (c == UNORDERED)
5035 fprintf (file, "un");
5037 fprintf (file, "%s", GET_RTX_NAME (c));
5042 /* Write the divide or modulus operator. */
5043 switch (GET_CODE (x))
5046 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
5049 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
5052 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
5055 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
5058 output_operand_lossage ("invalid %%E value");
5064 /* Write "_u" for unaligned access. */
5065 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
5066 fprintf (file, "_u");
5070 if (GET_CODE (x) == REG)
5071 fprintf (file, "%s", reg_names[REGNO (x)]);
5072 else if (GET_CODE (x) == MEM)
5073 output_address (XEXP (x, 0));
5074 else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
5076 switch (XINT (XEXP (x, 0), 1))
5080 output_addr_const (file, XVECEXP (XEXP (x, 0), 0, 0));
5083 output_operand_lossage ("unknown relocation unspec");
5088 output_addr_const (file, x);
5092 output_operand_lossage ("invalid %%xn code");
5097 print_operand_address (FILE *file, rtx addr)
5100 HOST_WIDE_INT offset = 0;
5102 if (GET_CODE (addr) == AND)
5103 addr = XEXP (addr, 0);
5105 if (GET_CODE (addr) == PLUS
5106 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5108 offset = INTVAL (XEXP (addr, 1));
5109 addr = XEXP (addr, 0);
5112 if (GET_CODE (addr) == LO_SUM)
5114 const char *reloc16, *reloclo;
5115 rtx op1 = XEXP (addr, 1);
5117 if (GET_CODE (op1) == CONST && GET_CODE (XEXP (op1, 0)) == UNSPEC)
5119 op1 = XEXP (op1, 0);
5120 switch (XINT (op1, 1))
5124 reloclo = (alpha_tls_size == 16 ? "dtprel" : "dtprello");
5128 reloclo = (alpha_tls_size == 16 ? "tprel" : "tprello");
5131 output_operand_lossage ("unknown relocation unspec");
5135 output_addr_const (file, XVECEXP (op1, 0, 0));
5140 reloclo = "gprellow";
5141 output_addr_const (file, op1);
5145 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
5147 addr = XEXP (addr, 0);
5148 if (GET_CODE (addr) == REG)
5149 basereg = REGNO (addr);
5150 else if (GET_CODE (addr) == SUBREG
5151 && GET_CODE (SUBREG_REG (addr)) == REG)
5152 basereg = subreg_regno (addr);
5156 fprintf (file, "($%d)\t\t!%s", basereg,
5157 (basereg == 29 ? reloc16 : reloclo));
5161 if (GET_CODE (addr) == REG)
5162 basereg = REGNO (addr);
5163 else if (GET_CODE (addr) == SUBREG
5164 && GET_CODE (SUBREG_REG (addr)) == REG)
5165 basereg = subreg_regno (addr);
5166 else if (GET_CODE (addr) == CONST_INT)
5167 offset = INTVAL (addr);
5169 #if TARGET_ABI_OPEN_VMS
5170 else if (GET_CODE (addr) == SYMBOL_REF)
5172 fprintf (file, "%s", XSTR (addr, 0));
5175 else if (GET_CODE (addr) == CONST
5176 && GET_CODE (XEXP (addr, 0)) == PLUS
5177 && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF)
5179 fprintf (file, "%s+" HOST_WIDE_INT_PRINT_DEC,
5180 XSTR (XEXP (XEXP (addr, 0), 0), 0),
5181 INTVAL (XEXP (XEXP (addr, 0), 1)));
5189 fprintf (file, HOST_WIDE_INT_PRINT_DEC "($%d)", offset, basereg);
5192 /* Emit RTL insns to initialize the variable parts of a trampoline at
5193 TRAMP. FNADDR is an RTX for the address of the function's pure
5194 code. CXT is an RTX for the static chain value for the function.
5196 The three offset parameters are for the individual template's
5197 layout. A JMPOFS < 0 indicates that the trampoline does not
5198 contain instructions at all.
5200 We assume here that a function will be called many more times than
5201 its address is taken (e.g., it might be passed to qsort), so we
5202 take the trouble to initialize the "hint" field in the JMP insn.
5203 Note that the hint field is PC (new) + 4 * bits 13:0. */
5206 alpha_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt,
5207 int fnofs, int cxtofs, int jmpofs)
5209 rtx temp, temp1, addr;
5210 /* VMS really uses DImode pointers in memory at this point. */
5211 enum machine_mode mode = TARGET_ABI_OPEN_VMS ? Pmode : ptr_mode;
5213 #ifdef POINTERS_EXTEND_UNSIGNED
5214 fnaddr = convert_memory_address (mode, fnaddr);
5215 cxt = convert_memory_address (mode, cxt);
5218 /* Store function address and CXT. */
5219 addr = memory_address (mode, plus_constant (tramp, fnofs));
5220 emit_move_insn (gen_rtx_MEM (mode, addr), fnaddr);
5221 addr = memory_address (mode, plus_constant (tramp, cxtofs));
5222 emit_move_insn (gen_rtx_MEM (mode, addr), cxt);
5224 /* This has been disabled since the hint only has a 32k range, and in
5225 no existing OS is the stack within 32k of the text segment. */
5226 if (0 && jmpofs >= 0)
5228 /* Compute hint value. */
5229 temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
5230 temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
5232 temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
5233 build_int_cst (NULL_TREE, 2), NULL_RTX, 1);
5234 temp = expand_and (SImode, gen_lowpart (SImode, temp),
5235 GEN_INT (0x3fff), 0);
5237 /* Merge in the hint. */
5238 addr = memory_address (SImode, plus_constant (tramp, jmpofs));
5239 temp1 = force_reg (SImode, gen_rtx_MEM (SImode, addr));
5240 temp1 = expand_and (SImode, temp1, GEN_INT (0xffffc000), NULL_RTX);
5241 temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
5243 emit_move_insn (gen_rtx_MEM (SImode, addr), temp1);
5246 #ifdef ENABLE_EXECUTE_STACK
5247 emit_library_call (init_one_libfunc ("__enable_execute_stack"),
5248 0, VOIDmode, 1, tramp, Pmode);
5252 emit_insn (gen_imb ());
5255 /* Determine where to put an argument to a function.
5256 Value is zero to push the argument on the stack,
5257 or a hard register in which to store the argument.
5259 MODE is the argument's machine mode.
5260 TYPE is the data type of the argument (as a tree).
5261 This is null for libcalls where that information may
5263 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5264 the preceding args and about the function being called.
5265 NAMED is nonzero if this argument is a named parameter
5266 (otherwise it is an extra parameter matching an ellipsis).
5268 On Alpha the first 6 words of args are normally in registers
5269 and the rest are pushed. */
5272 function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode, tree type,
5273 int named ATTRIBUTE_UNUSED)
5278 /* Don't get confused and pass small structures in FP registers. */
5279 if (type && AGGREGATE_TYPE_P (type))
5283 #ifdef ENABLE_CHECKING
5284 /* With alpha_split_complex_arg, we shouldn't see any raw complex
5286 if (COMPLEX_MODE_P (mode))
5290 /* Set up defaults for FP operands passed in FP registers, and
5291 integral operands passed in integer registers. */
5292 if (TARGET_FPREGS && GET_MODE_CLASS (mode) == MODE_FLOAT)
5298 /* ??? Irritatingly, the definition of CUMULATIVE_ARGS is different for
5299 the three platforms, so we can't avoid conditional compilation. */
5300 #if TARGET_ABI_OPEN_VMS
5302 if (mode == VOIDmode)
5303 return alpha_arg_info_reg_val (cum);
5305 num_args = cum.num_args;
5307 || targetm.calls.must_pass_in_stack (mode, type))
5310 #elif TARGET_ABI_UNICOSMK
5314 /* If this is the last argument, generate the call info word (CIW). */
5315 /* ??? We don't include the caller's line number in the CIW because
5316 I don't know how to determine it if debug infos are turned off. */
5317 if (mode == VOIDmode)
5326 for (i = 0; i < cum.num_reg_words && i < 5; i++)
5327 if (cum.reg_args_type[i])
5328 lo |= (1 << (7 - i));
5330 if (cum.num_reg_words == 6 && cum.reg_args_type[5])
5333 lo |= cum.num_reg_words;
5335 #if HOST_BITS_PER_WIDE_INT == 32
5336 hi = (cum.num_args << 20) | cum.num_arg_words;
5338 lo = lo | ((HOST_WIDE_INT) cum.num_args << 52)
5339 | ((HOST_WIDE_INT) cum.num_arg_words << 32);
5342 ciw = immed_double_const (lo, hi, DImode);
5344 return gen_rtx_UNSPEC (DImode, gen_rtvec (1, ciw),
5345 UNSPEC_UMK_LOAD_CIW);
5348 size = ALPHA_ARG_SIZE (mode, type, named);
5349 num_args = cum.num_reg_words;
5351 || cum.num_reg_words + size > 6
5352 || targetm.calls.must_pass_in_stack (mode, type))
5354 else if (type && TYPE_MODE (type) == BLKmode)
5358 reg1 = gen_rtx_REG (DImode, num_args + 16);
5359 reg1 = gen_rtx_EXPR_LIST (DImode, reg1, const0_rtx);
5361 /* The argument fits in two registers. Note that we still need to
5362 reserve a register for empty structures. */
5366 return gen_rtx_PARALLEL (mode, gen_rtvec (1, reg1));
5369 reg2 = gen_rtx_REG (DImode, num_args + 17);
5370 reg2 = gen_rtx_EXPR_LIST (DImode, reg2, GEN_INT (8));
5371 return gen_rtx_PARALLEL (mode, gen_rtvec (2, reg1, reg2));
5375 #elif TARGET_ABI_OSF
5381 /* VOID is passed as a special flag for "last argument". */
5382 if (type == void_type_node)
5384 else if (targetm.calls.must_pass_in_stack (mode, type))
5388 #error Unhandled ABI
5391 return gen_rtx_REG (mode, num_args + basereg);
5395 alpha_arg_partial_bytes (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
5396 enum machine_mode mode ATTRIBUTE_UNUSED,
5397 tree type ATTRIBUTE_UNUSED,
5398 bool named ATTRIBUTE_UNUSED)
5402 #if TARGET_ABI_OPEN_VMS
5403 if (cum->num_args < 6
5404 && 6 < cum->num_args + ALPHA_ARG_SIZE (mode, type, named))
5405 words = 6 - (CUM).num_args;
5406 #elif TARGET_ABI_UNICOSMK
5407 /* Never any split arguments. */
5408 #elif TARGET_ABI_OSF
5409 if (*cum < 6 && 6 < *cum + ALPHA_ARG_SIZE (mode, type, named))
5412 #error Unhandled ABI
5415 return words * UNITS_PER_WORD;
5419 /* Return true if TYPE must be returned in memory, instead of in registers. */
5422 alpha_return_in_memory (tree type, tree fndecl ATTRIBUTE_UNUSED)
5424 enum machine_mode mode = VOIDmode;
5429 mode = TYPE_MODE (type);
5431 /* All aggregates are returned in memory. */
5432 if (AGGREGATE_TYPE_P (type))
5436 size = GET_MODE_SIZE (mode);
5437 switch (GET_MODE_CLASS (mode))
5439 case MODE_VECTOR_FLOAT:
5440 /* Pass all float vectors in memory, like an aggregate. */
5443 case MODE_COMPLEX_FLOAT:
5444 /* We judge complex floats on the size of their element,
5445 not the size of the whole type. */
5446 size = GET_MODE_UNIT_SIZE (mode);
5451 case MODE_COMPLEX_INT:
5452 case MODE_VECTOR_INT:
5456 /* ??? We get called on all sorts of random stuff from
5457 aggregate_value_p. We can't abort, but it's not clear
5458 what's safe to return. Pretend it's a struct I guess. */
5462 /* Otherwise types must fit in one register. */
5463 return size > UNITS_PER_WORD;
5466 /* Return true if TYPE should be passed by invisible reference. */
5469 alpha_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
5470 enum machine_mode mode,
5471 tree type ATTRIBUTE_UNUSED,
5472 bool named ATTRIBUTE_UNUSED)
5474 return mode == TFmode || mode == TCmode;
5477 /* Define how to find the value returned by a function. VALTYPE is the
5478 data type of the value (as a tree). If the precise function being
5479 called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0.
5480 MODE is set instead of VALTYPE for libcalls.
5482 On Alpha the value is found in $0 for integer functions and
5483 $f0 for floating-point functions. */
5486 function_value (tree valtype, tree func ATTRIBUTE_UNUSED,
5487 enum machine_mode mode)
5489 unsigned int regnum, dummy;
5490 enum mode_class class;
5492 #ifdef ENABLE_CHECKING
5493 if (valtype && alpha_return_in_memory (valtype, func))
5498 mode = TYPE_MODE (valtype);
5500 class = GET_MODE_CLASS (mode);
5504 PROMOTE_MODE (mode, dummy, valtype);
5507 case MODE_COMPLEX_INT:
5508 case MODE_VECTOR_INT:
5516 case MODE_COMPLEX_FLOAT:
5518 enum machine_mode cmode = GET_MODE_INNER (mode);
5520 return gen_rtx_PARALLEL
5523 gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 32),
5525 gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 33),
5526 GEN_INT (GET_MODE_SIZE (cmode)))));
5533 return gen_rtx_REG (mode, regnum);
5536 /* TCmode complex values are passed by invisible reference. We
5537 should not split these values. */
5540 alpha_split_complex_arg (tree type)
5542 return TYPE_MODE (type) != TCmode;
5546 alpha_build_builtin_va_list (void)
5548 tree base, ofs, space, record, type_decl;
5550 if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
5551 return ptr_type_node;
5553 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
5554 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
5555 TREE_CHAIN (record) = type_decl;
5556 TYPE_NAME (record) = type_decl;
5558 /* C++? SET_IS_AGGR_TYPE (record, 1); */
5560 /* Dummy field to prevent alignment warnings. */
5561 space = build_decl (FIELD_DECL, NULL_TREE, integer_type_node);
5562 DECL_FIELD_CONTEXT (space) = record;
5563 DECL_ARTIFICIAL (space) = 1;
5564 DECL_IGNORED_P (space) = 1;
5566 ofs = build_decl (FIELD_DECL, get_identifier ("__offset"),
5568 DECL_FIELD_CONTEXT (ofs) = record;
5569 TREE_CHAIN (ofs) = space;
5571 base = build_decl (FIELD_DECL, get_identifier ("__base"),
5573 DECL_FIELD_CONTEXT (base) = record;
5574 TREE_CHAIN (base) = ofs;
5576 TYPE_FIELDS (record) = base;
5577 layout_type (record);
5582 /* Perform any needed actions needed for a function that is receiving a
5583 variable number of arguments. */
5586 alpha_setup_incoming_varargs (CUMULATIVE_ARGS *pcum,
5587 enum machine_mode mode ATTRIBUTE_UNUSED,
5588 tree type ATTRIBUTE_UNUSED,
5589 int *pretend_size, int no_rtl)
5591 #if TARGET_ABI_UNICOSMK
5592 /* On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
5593 arguments on the stack. Unfortunately, it doesn't always store the first
5594 one (i.e. the one that arrives in $16 or $f16). This is not a problem
5595 with stdargs as we always have at least one named argument there. */
5596 int num_reg_words = pcum->num_reg_words;
5597 if (num_reg_words < 6)
5601 emit_insn (gen_umk_mismatch_args (GEN_INT (num_reg_words + 1)));
5602 emit_insn (gen_arg_home_umk ());
5606 #elif TARGET_ABI_OPEN_VMS
5607 /* For VMS, we allocate space for all 6 arg registers plus a count.
5609 However, if NO registers need to be saved, don't allocate any space.
5610 This is not only because we won't need the space, but because AP
5611 includes the current_pretend_args_size and we don't want to mess up
5612 any ap-relative addresses already made. */
5613 if (pcum->num_args < 6)
5617 emit_move_insn (gen_rtx_REG (DImode, 1), virtual_incoming_args_rtx);
5618 emit_insn (gen_arg_home ());
5620 *pretend_size = 7 * UNITS_PER_WORD;
5623 /* On OSF/1 and friends, we allocate space for all 12 arg registers, but
5624 only push those that are remaining. However, if NO registers need to
5625 be saved, don't allocate any space. This is not only because we won't
5626 need the space, but because AP includes the current_pretend_args_size
5627 and we don't want to mess up any ap-relative addresses already made.
5629 If we are not to use the floating-point registers, save the integer
5630 registers where we would put the floating-point registers. This is
5631 not the most efficient way to implement varargs with just one register
5632 class, but it isn't worth doing anything more efficient in this rare
5634 CUMULATIVE_ARGS cum = *pcum;
5641 int set = get_varargs_alias_set ();
5644 tmp = gen_rtx_MEM (BLKmode,
5645 plus_constant (virtual_incoming_args_rtx,
5646 (cum + 6) * UNITS_PER_WORD));
5647 set_mem_alias_set (tmp, set);
5648 move_block_from_reg (16 + cum, tmp, 6 - cum);
5650 tmp = gen_rtx_MEM (BLKmode,
5651 plus_constant (virtual_incoming_args_rtx,
5652 cum * UNITS_PER_WORD));
5653 set_mem_alias_set (tmp, set);
5654 move_block_from_reg (16 + (TARGET_FPREGS ? 32 : 0) + cum, tmp,
5657 *pretend_size = 12 * UNITS_PER_WORD;
5662 alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
5664 HOST_WIDE_INT offset;
5665 tree t, offset_field, base_field;
5667 if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
5670 if (TARGET_ABI_UNICOSMK)
5671 std_expand_builtin_va_start (valist, nextarg);
5673 /* For Unix, TARGET_SETUP_INCOMING_VARARGS moves the starting address base
5674 up by 48, storing fp arg registers in the first 48 bytes, and the
5675 integer arg registers in the next 48 bytes. This is only done,
5676 however, if any integer registers need to be stored.
5678 If no integer registers need be stored, then we must subtract 48
5679 in order to account for the integer arg registers which are counted
5680 in argsize above, but which are not actually stored on the stack.
5681 Must further be careful here about structures straddling the last
5682 integer argument register; that futzes with pretend_args_size,
5683 which changes the meaning of AP. */
5686 offset = TARGET_ABI_OPEN_VMS ? UNITS_PER_WORD : 6 * UNITS_PER_WORD;
5688 offset = -6 * UNITS_PER_WORD + current_function_pretend_args_size;
5690 if (TARGET_ABI_OPEN_VMS)
5692 nextarg = plus_constant (nextarg, offset);
5693 nextarg = plus_constant (nextarg, NUM_ARGS * UNITS_PER_WORD);
5694 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
5695 make_tree (ptr_type_node, nextarg));
5696 TREE_SIDE_EFFECTS (t) = 1;
5698 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5702 base_field = TYPE_FIELDS (TREE_TYPE (valist));
5703 offset_field = TREE_CHAIN (base_field);
5705 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
5706 valist, base_field, NULL_TREE);
5707 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
5708 valist, offset_field, NULL_TREE);
5710 t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
5711 t = build (PLUS_EXPR, ptr_type_node, t,
5712 build_int_cst (NULL_TREE, offset));
5713 t = build (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
5714 TREE_SIDE_EFFECTS (t) = 1;
5715 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5717 t = build_int_cst (NULL_TREE, NUM_ARGS * UNITS_PER_WORD);
5718 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
5719 TREE_SIDE_EFFECTS (t) = 1;
5720 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5725 alpha_gimplify_va_arg_1 (tree type, tree base, tree offset, tree *pre_p)
5727 tree type_size, ptr_type, addend, t, addr, internal_post;
5729 /* If the type could not be passed in registers, skip the block
5730 reserved for the registers. */
5731 if (targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
5733 t = build_int_cst (TREE_TYPE (offset), 6*8);
5734 t = build (MODIFY_EXPR, TREE_TYPE (offset), offset,
5735 build (MAX_EXPR, TREE_TYPE (offset), offset, t));
5736 gimplify_and_add (t, pre_p);
5740 ptr_type = build_pointer_type (type);
5742 if (TREE_CODE (type) == COMPLEX_TYPE)
5744 tree real_part, imag_part, real_temp;
5746 real_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
5749 /* Copy the value into a new temporary, lest the formal temporary
5750 be reused out from under us. */
5751 real_temp = get_initialized_tmp_var (real_part, pre_p, NULL);
5753 imag_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
5756 return build (COMPLEX_EXPR, type, real_temp, imag_part);
5758 else if (TREE_CODE (type) == REAL_TYPE)
5760 tree fpaddend, cond, fourtyeight;
5762 fourtyeight = build_int_cst (TREE_TYPE (addend), 6*8);
5763 fpaddend = fold (build (MINUS_EXPR, TREE_TYPE (addend),
5764 addend, fourtyeight));
5765 cond = fold (build (LT_EXPR, boolean_type_node, addend, fourtyeight));
5766 addend = fold (build (COND_EXPR, TREE_TYPE (addend), cond,
5770 /* Build the final address and force that value into a temporary. */
5771 addr = build (PLUS_EXPR, ptr_type, fold_convert (ptr_type, base),
5772 fold_convert (ptr_type, addend));
5773 internal_post = NULL;
5774 gimplify_expr (&addr, pre_p, &internal_post, is_gimple_val, fb_rvalue);
5775 append_to_statement_list (internal_post, pre_p);
5777 /* Update the offset field. */
5778 type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type));
5779 if (type_size == NULL || TREE_OVERFLOW (type_size))
5783 t = size_binop (PLUS_EXPR, type_size, size_int (7));
5784 t = size_binop (TRUNC_DIV_EXPR, t, size_int (8));
5785 t = size_binop (MULT_EXPR, t, size_int (8));
5787 t = fold_convert (TREE_TYPE (offset), t);
5788 t = build (MODIFY_EXPR, void_type_node, offset,
5789 build (PLUS_EXPR, TREE_TYPE (offset), offset, t));
5790 gimplify_and_add (t, pre_p);
5792 return build_fold_indirect_ref (addr);
5796 alpha_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
5798 tree offset_field, base_field, offset, base, t, r;
5801 if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
5802 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
5804 base_field = TYPE_FIELDS (va_list_type_node);
5805 offset_field = TREE_CHAIN (base_field);
5806 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
5807 valist, base_field, NULL_TREE);
5808 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
5809 valist, offset_field, NULL_TREE);
5811 /* Pull the fields of the structure out into temporaries. Since we never
5812 modify the base field, we can use a formal temporary. Sign-extend the
5813 offset field so that it's the proper width for pointer arithmetic. */
5814 base = get_formal_tmp_var (base_field, pre_p);
5816 t = fold_convert (lang_hooks.types.type_for_size (64, 0), offset_field);
5817 offset = get_initialized_tmp_var (t, pre_p, NULL);
5819 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
5821 type = build_pointer_type (type);
5823 /* Find the value. Note that this will be a stable indirection, or
5824 a composite of stable indirections in the case of complex. */
5825 r = alpha_gimplify_va_arg_1 (type, base, offset, pre_p);
5827 /* Stuff the offset temporary back into its field. */
5828 t = build (MODIFY_EXPR, void_type_node, offset_field,
5829 fold_convert (TREE_TYPE (offset_field), offset));
5830 gimplify_and_add (t, pre_p);
5833 r = build_fold_indirect_ref (r);
5842 ALPHA_BUILTIN_CMPBGE,
5843 ALPHA_BUILTIN_EXTBL,
5844 ALPHA_BUILTIN_EXTWL,
5845 ALPHA_BUILTIN_EXTLL,
5846 ALPHA_BUILTIN_EXTQL,
5847 ALPHA_BUILTIN_EXTWH,
5848 ALPHA_BUILTIN_EXTLH,
5849 ALPHA_BUILTIN_EXTQH,
5850 ALPHA_BUILTIN_INSBL,
5851 ALPHA_BUILTIN_INSWL,
5852 ALPHA_BUILTIN_INSLL,
5853 ALPHA_BUILTIN_INSQL,
5854 ALPHA_BUILTIN_INSWH,
5855 ALPHA_BUILTIN_INSLH,
5856 ALPHA_BUILTIN_INSQH,
5857 ALPHA_BUILTIN_MSKBL,
5858 ALPHA_BUILTIN_MSKWL,
5859 ALPHA_BUILTIN_MSKLL,
5860 ALPHA_BUILTIN_MSKQL,
5861 ALPHA_BUILTIN_MSKWH,
5862 ALPHA_BUILTIN_MSKLH,
5863 ALPHA_BUILTIN_MSKQH,
5864 ALPHA_BUILTIN_UMULH,
5866 ALPHA_BUILTIN_ZAPNOT,
5867 ALPHA_BUILTIN_AMASK,
5868 ALPHA_BUILTIN_IMPLVER,
5870 ALPHA_BUILTIN_THREAD_POINTER,
5871 ALPHA_BUILTIN_SET_THREAD_POINTER,
5874 ALPHA_BUILTIN_MINUB8,
5875 ALPHA_BUILTIN_MINSB8,
5876 ALPHA_BUILTIN_MINUW4,
5877 ALPHA_BUILTIN_MINSW4,
5878 ALPHA_BUILTIN_MAXUB8,
5879 ALPHA_BUILTIN_MAXSB8,
5880 ALPHA_BUILTIN_MAXUW4,
5881 ALPHA_BUILTIN_MAXSW4,
5885 ALPHA_BUILTIN_UNPKBL,
5886 ALPHA_BUILTIN_UNPKBW,
5891 ALPHA_BUILTIN_CTPOP,
5896 static unsigned int const code_for_builtin[ALPHA_BUILTIN_max] = {
5897 CODE_FOR_builtin_cmpbge,
5898 CODE_FOR_builtin_extbl,
5899 CODE_FOR_builtin_extwl,
5900 CODE_FOR_builtin_extll,
5901 CODE_FOR_builtin_extql,
5902 CODE_FOR_builtin_extwh,
5903 CODE_FOR_builtin_extlh,
5904 CODE_FOR_builtin_extqh,
5905 CODE_FOR_builtin_insbl,
5906 CODE_FOR_builtin_inswl,
5907 CODE_FOR_builtin_insll,
5908 CODE_FOR_builtin_insql,
5909 CODE_FOR_builtin_inswh,
5910 CODE_FOR_builtin_inslh,
5911 CODE_FOR_builtin_insqh,
5912 CODE_FOR_builtin_mskbl,
5913 CODE_FOR_builtin_mskwl,
5914 CODE_FOR_builtin_mskll,
5915 CODE_FOR_builtin_mskql,
5916 CODE_FOR_builtin_mskwh,
5917 CODE_FOR_builtin_msklh,
5918 CODE_FOR_builtin_mskqh,
5919 CODE_FOR_umuldi3_highpart,
5920 CODE_FOR_builtin_zap,
5921 CODE_FOR_builtin_zapnot,
5922 CODE_FOR_builtin_amask,
5923 CODE_FOR_builtin_implver,
5924 CODE_FOR_builtin_rpcc,
5929 CODE_FOR_builtin_minub8,
5930 CODE_FOR_builtin_minsb8,
5931 CODE_FOR_builtin_minuw4,
5932 CODE_FOR_builtin_minsw4,
5933 CODE_FOR_builtin_maxub8,
5934 CODE_FOR_builtin_maxsb8,
5935 CODE_FOR_builtin_maxuw4,
5936 CODE_FOR_builtin_maxsw4,
5937 CODE_FOR_builtin_perr,
5938 CODE_FOR_builtin_pklb,
5939 CODE_FOR_builtin_pkwb,
5940 CODE_FOR_builtin_unpkbl,
5941 CODE_FOR_builtin_unpkbw,
5946 CODE_FOR_popcountdi2
5949 struct alpha_builtin_def
5952 enum alpha_builtin code;
5953 unsigned int target_mask;
5957 static struct alpha_builtin_def const zero_arg_builtins[] = {
5958 { "__builtin_alpha_implver", ALPHA_BUILTIN_IMPLVER, 0, true },
5959 { "__builtin_alpha_rpcc", ALPHA_BUILTIN_RPCC, 0, false }
5962 static struct alpha_builtin_def const one_arg_builtins[] = {
5963 { "__builtin_alpha_amask", ALPHA_BUILTIN_AMASK, 0, true },
5964 { "__builtin_alpha_pklb", ALPHA_BUILTIN_PKLB, MASK_MAX, true },
5965 { "__builtin_alpha_pkwb", ALPHA_BUILTIN_PKWB, MASK_MAX, true },
5966 { "__builtin_alpha_unpkbl", ALPHA_BUILTIN_UNPKBL, MASK_MAX, true },
5967 { "__builtin_alpha_unpkbw", ALPHA_BUILTIN_UNPKBW, MASK_MAX, true },
5968 { "__builtin_alpha_cttz", ALPHA_BUILTIN_CTTZ, MASK_CIX, true },
5969 { "__builtin_alpha_ctlz", ALPHA_BUILTIN_CTLZ, MASK_CIX, true },
5970 { "__builtin_alpha_ctpop", ALPHA_BUILTIN_CTPOP, MASK_CIX, true }
5973 static struct alpha_builtin_def const two_arg_builtins[] = {
5974 { "__builtin_alpha_cmpbge", ALPHA_BUILTIN_CMPBGE, 0, true },
5975 { "__builtin_alpha_extbl", ALPHA_BUILTIN_EXTBL, 0, true },
5976 { "__builtin_alpha_extwl", ALPHA_BUILTIN_EXTWL, 0, true },
5977 { "__builtin_alpha_extll", ALPHA_BUILTIN_EXTLL, 0, true },
5978 { "__builtin_alpha_extql", ALPHA_BUILTIN_EXTQL, 0, true },
5979 { "__builtin_alpha_extwh", ALPHA_BUILTIN_EXTWH, 0, true },
5980 { "__builtin_alpha_extlh", ALPHA_BUILTIN_EXTLH, 0, true },
5981 { "__builtin_alpha_extqh", ALPHA_BUILTIN_EXTQH, 0, true },
5982 { "__builtin_alpha_insbl", ALPHA_BUILTIN_INSBL, 0, true },
5983 { "__builtin_alpha_inswl", ALPHA_BUILTIN_INSWL, 0, true },
5984 { "__builtin_alpha_insll", ALPHA_BUILTIN_INSLL, 0, true },
5985 { "__builtin_alpha_insql", ALPHA_BUILTIN_INSQL, 0, true },
5986 { "__builtin_alpha_inswh", ALPHA_BUILTIN_INSWH, 0, true },
5987 { "__builtin_alpha_inslh", ALPHA_BUILTIN_INSLH, 0, true },
5988 { "__builtin_alpha_insqh", ALPHA_BUILTIN_INSQH, 0, true },
5989 { "__builtin_alpha_mskbl", ALPHA_BUILTIN_MSKBL, 0, true },
5990 { "__builtin_alpha_mskwl", ALPHA_BUILTIN_MSKWL, 0, true },
5991 { "__builtin_alpha_mskll", ALPHA_BUILTIN_MSKLL, 0, true },
5992 { "__builtin_alpha_mskql", ALPHA_BUILTIN_MSKQL, 0, true },
5993 { "__builtin_alpha_mskwh", ALPHA_BUILTIN_MSKWH, 0, true },
5994 { "__builtin_alpha_msklh", ALPHA_BUILTIN_MSKLH, 0, true },
5995 { "__builtin_alpha_mskqh", ALPHA_BUILTIN_MSKQH, 0, true },
5996 { "__builtin_alpha_umulh", ALPHA_BUILTIN_UMULH, 0, true },
5997 { "__builtin_alpha_zap", ALPHA_BUILTIN_ZAP, 0, true },
5998 { "__builtin_alpha_zapnot", ALPHA_BUILTIN_ZAPNOT, 0, true },
5999 { "__builtin_alpha_minub8", ALPHA_BUILTIN_MINUB8, MASK_MAX, true },
6000 { "__builtin_alpha_minsb8", ALPHA_BUILTIN_MINSB8, MASK_MAX, true },
6001 { "__builtin_alpha_minuw4", ALPHA_BUILTIN_MINUW4, MASK_MAX, true },
6002 { "__builtin_alpha_minsw4", ALPHA_BUILTIN_MINSW4, MASK_MAX, true },
6003 { "__builtin_alpha_maxub8", ALPHA_BUILTIN_MAXUB8, MASK_MAX, true },
6004 { "__builtin_alpha_maxsb8", ALPHA_BUILTIN_MAXSB8, MASK_MAX, true },
6005 { "__builtin_alpha_maxuw4", ALPHA_BUILTIN_MAXUW4, MASK_MAX, true },
6006 { "__builtin_alpha_maxsw4", ALPHA_BUILTIN_MAXSW4, MASK_MAX, true },
6007 { "__builtin_alpha_perr", ALPHA_BUILTIN_PERR, MASK_MAX, true }
6010 static GTY(()) tree alpha_v8qi_u;
6011 static GTY(()) tree alpha_v8qi_s;
6012 static GTY(()) tree alpha_v4hi_u;
6013 static GTY(()) tree alpha_v4hi_s;
6016 alpha_init_builtins (void)
6018 const struct alpha_builtin_def *p;
6019 tree ftype, attrs[2];
6022 attrs[0] = tree_cons (get_identifier ("nothrow"), NULL, NULL);
6023 attrs[1] = tree_cons (get_identifier ("const"), NULL, attrs[0]);
6025 ftype = build_function_type (long_integer_type_node, void_list_node);
6027 p = zero_arg_builtins;
6028 for (i = 0; i < ARRAY_SIZE (zero_arg_builtins); ++i, ++p)
6029 if ((target_flags & p->target_mask) == p->target_mask)
6030 lang_hooks.builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
6031 NULL, attrs[p->is_const]);
6033 ftype = build_function_type_list (long_integer_type_node,
6034 long_integer_type_node, NULL_TREE);
6036 p = one_arg_builtins;
6037 for (i = 0; i < ARRAY_SIZE (one_arg_builtins); ++i, ++p)
6038 if ((target_flags & p->target_mask) == p->target_mask)
6039 lang_hooks.builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
6040 NULL, attrs[p->is_const]);
6042 ftype = build_function_type_list (long_integer_type_node,
6043 long_integer_type_node,
6044 long_integer_type_node, NULL_TREE);
6046 p = two_arg_builtins;
6047 for (i = 0; i < ARRAY_SIZE (two_arg_builtins); ++i, ++p)
6048 if ((target_flags & p->target_mask) == p->target_mask)
6049 lang_hooks.builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
6050 NULL, attrs[p->is_const]);
6052 ftype = build_function_type (ptr_type_node, void_list_node);
6053 lang_hooks.builtin_function ("__builtin_thread_pointer", ftype,
6054 ALPHA_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
6057 ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
6058 lang_hooks.builtin_function ("__builtin_set_thread_pointer", ftype,
6059 ALPHA_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
6062 alpha_v8qi_u = build_vector_type (unsigned_intQI_type_node, 8);
6063 alpha_v8qi_s = build_vector_type (intQI_type_node, 8);
6064 alpha_v4hi_u = build_vector_type (unsigned_intHI_type_node, 4);
6065 alpha_v4hi_s = build_vector_type (intHI_type_node, 4);
6068 /* Expand an expression EXP that calls a built-in function,
6069 with result going to TARGET if that's convenient
6070 (and in mode MODE if that's convenient).
6071 SUBTARGET may be used as the target for computing one of EXP's operands.
6072 IGNORE is nonzero if the value is to be ignored. */
6075 alpha_expand_builtin (tree exp, rtx target,
6076 rtx subtarget ATTRIBUTE_UNUSED,
6077 enum machine_mode mode ATTRIBUTE_UNUSED,
6078 int ignore ATTRIBUTE_UNUSED)
6082 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
6083 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
6084 tree arglist = TREE_OPERAND (exp, 1);
6085 enum insn_code icode;
6086 rtx op[MAX_ARGS], pat;
6090 if (fcode >= ALPHA_BUILTIN_max)
6091 internal_error ("bad builtin fcode");
6092 icode = code_for_builtin[fcode];
6094 internal_error ("bad builtin fcode");
6096 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
6098 for (arglist = TREE_OPERAND (exp, 1), arity = 0;
6100 arglist = TREE_CHAIN (arglist), arity++)
6102 const struct insn_operand_data *insn_op;
6104 tree arg = TREE_VALUE (arglist);
6105 if (arg == error_mark_node)
6107 if (arity > MAX_ARGS)
6110 insn_op = &insn_data[icode].operand[arity + nonvoid];
6112 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
6114 if (!(*insn_op->predicate) (op[arity], insn_op->mode))
6115 op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
6120 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6122 || GET_MODE (target) != tmode
6123 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
6124 target = gen_reg_rtx (tmode);
6130 pat = GEN_FCN (icode) (target);
6134 pat = GEN_FCN (icode) (target, op[0]);
6136 pat = GEN_FCN (icode) (op[0]);
6139 pat = GEN_FCN (icode) (target, op[0], op[1]);
6155 /* Several bits below assume HWI >= 64 bits. This should be enforced
6157 #if HOST_BITS_PER_WIDE_INT < 64
6158 # error "HOST_WIDE_INT too small"
6161 /* Fold the builtin for the CMPBGE instruction. This is a vector comparison
6162 with an 8 bit output vector. OPINT contains the integer operands; bit N
6163 of OP_CONST is set if OPINT[N] is valid. */
6166 alpha_fold_builtin_cmpbge (unsigned HOST_WIDE_INT opint[], long op_const)
6171 for (i = 0, val = 0; i < 8; ++i)
6173 unsigned HOST_WIDE_INT c0 = (opint[0] >> (i * 8)) & 0xff;
6174 unsigned HOST_WIDE_INT c1 = (opint[1] >> (i * 8)) & 0xff;
6178 return build_int_cst (long_integer_type_node, val);
6180 else if (op_const == 2 && opint[1] == 0)
6181 return build_int_cst (long_integer_type_node, 0xff);
6185 /* Fold the builtin for the ZAPNOT instruction. This is essentially a
6186 specialized form of an AND operation. Other byte manipulation instructions
6187 are defined in terms of this instruction, so this is also used as a
6188 subroutine for other builtins.
6190 OP contains the tree operands; OPINT contains the extracted integer values.
6191 Bit N of OP_CONST it set if OPINT[N] is valid. OP may be null if only
6192 OPINT may be considered. */
6195 alpha_fold_builtin_zapnot (tree *op, unsigned HOST_WIDE_INT opint[],
6200 unsigned HOST_WIDE_INT mask = 0;
6203 for (i = 0; i < 8; ++i)
6204 if ((opint[1] >> i) & 1)
6205 mask |= (unsigned HOST_WIDE_INT)0xff << (i * 8);
6208 return build_int_cst (long_integer_type_node, opint[0] & mask);
6211 return fold (build2 (BIT_AND_EXPR, long_integer_type_node, op[0],
6212 build_int_cst (long_integer_type_node, mask)));
6214 else if ((op_const & 1) && opint[0] == 0)
6215 return build_int_cst (long_integer_type_node, 0);
6219 /* Fold the builtins for the EXT family of instructions. */
6222 alpha_fold_builtin_extxx (tree op[], unsigned HOST_WIDE_INT opint[],
6223 long op_const, unsigned HOST_WIDE_INT bytemask,
6227 tree *zap_op = NULL;
6231 unsigned HOST_WIDE_INT loc;
6234 if (BYTES_BIG_ENDIAN)
6242 unsigned HOST_WIDE_INT temp = opint[0];
6255 opint[1] = bytemask;
6256 return alpha_fold_builtin_zapnot (zap_op, opint, zap_const);
6259 /* Fold the builtins for the INS family of instructions. */
6262 alpha_fold_builtin_insxx (tree op[], unsigned HOST_WIDE_INT opint[],
6263 long op_const, unsigned HOST_WIDE_INT bytemask,
6266 if ((op_const & 1) && opint[0] == 0)
6267 return build_int_cst (long_integer_type_node, 0);
6271 unsigned HOST_WIDE_INT temp, loc, byteloc;
6272 tree *zap_op = NULL;
6275 if (BYTES_BIG_ENDIAN)
6282 byteloc = (64 - (loc * 8)) & 0x3f;
6299 opint[1] = bytemask;
6300 return alpha_fold_builtin_zapnot (zap_op, opint, op_const);
6307 alpha_fold_builtin_mskxx (tree op[], unsigned HOST_WIDE_INT opint[],
6308 long op_const, unsigned HOST_WIDE_INT bytemask,
6313 unsigned HOST_WIDE_INT loc;
6316 if (BYTES_BIG_ENDIAN)
6323 opint[1] = bytemask ^ 0xff;
6326 return alpha_fold_builtin_zapnot (op, opint, op_const);
6330 alpha_fold_builtin_umulh (unsigned HOST_WIDE_INT opint[], long op_const)
6336 unsigned HOST_WIDE_INT l;
6339 mul_double (opint[0], 0, opint[1], 0, &l, &h);
6341 #if HOST_BITS_PER_WIDE_INT > 64
6345 return build_int_cst (long_integer_type_node, h);
6349 opint[1] = opint[0];
6352 /* Note that (X*1) >> 64 == 0. */
6353 if (opint[1] == 0 || opint[1] == 1)
6354 return build_int_cst (long_integer_type_node, 0);
6361 alpha_fold_vector_minmax (enum tree_code code, tree op[], tree vtype)
6363 tree op0 = fold_convert (vtype, op[0]);
6364 tree op1 = fold_convert (vtype, op[1]);
6365 tree val = fold (build2 (code, vtype, op0, op1));
6366 return fold_convert (long_integer_type_node, val);
6370 alpha_fold_builtin_perr (unsigned HOST_WIDE_INT opint[], long op_const)
6372 unsigned HOST_WIDE_INT temp = 0;
6378 for (i = 0; i < 8; ++i)
6380 unsigned HOST_WIDE_INT a = (opint[0] >> (i * 8)) & 0xff;
6381 unsigned HOST_WIDE_INT b = (opint[1] >> (i * 8)) & 0xff;
6388 return build_int_cst (long_integer_type_node, temp);
6392 alpha_fold_builtin_pklb (unsigned HOST_WIDE_INT opint[], long op_const)
6394 unsigned HOST_WIDE_INT temp;
6399 temp = opint[0] & 0xff;
6400 temp |= (opint[0] >> 24) & 0xff00;
6402 return build_int_cst (long_integer_type_node, temp);
6406 alpha_fold_builtin_pkwb (unsigned HOST_WIDE_INT opint[], long op_const)
6408 unsigned HOST_WIDE_INT temp;
6413 temp = opint[0] & 0xff;
6414 temp |= (opint[0] >> 8) & 0xff00;
6415 temp |= (opint[0] >> 16) & 0xff0000;
6416 temp |= (opint[0] >> 24) & 0xff000000;
6418 return build_int_cst (long_integer_type_node, temp);
6422 alpha_fold_builtin_unpkbl (unsigned HOST_WIDE_INT opint[], long op_const)
6424 unsigned HOST_WIDE_INT temp;
6429 temp = opint[0] & 0xff;
6430 temp |= (opint[0] & 0xff00) << 24;
6432 return build_int_cst (long_integer_type_node, temp);
6436 alpha_fold_builtin_unpkbw (unsigned HOST_WIDE_INT opint[], long op_const)
6438 unsigned HOST_WIDE_INT temp;
6443 temp = opint[0] & 0xff;
6444 temp |= (opint[0] & 0x0000ff00) << 8;
6445 temp |= (opint[0] & 0x00ff0000) << 16;
6446 temp |= (opint[0] & 0xff000000) << 24;
6448 return build_int_cst (long_integer_type_node, temp);
6452 alpha_fold_builtin_cttz (unsigned HOST_WIDE_INT opint[], long op_const)
6454 unsigned HOST_WIDE_INT temp;
6462 temp = exact_log2 (opint[0] & -opint[0]);
6464 return build_int_cst (long_integer_type_node, temp);
6468 alpha_fold_builtin_ctlz (unsigned HOST_WIDE_INT opint[], long op_const)
6470 unsigned HOST_WIDE_INT temp;
6478 temp = 64 - floor_log2 (opint[0]) - 1;
6480 return build_int_cst (long_integer_type_node, temp);
6484 alpha_fold_builtin_ctpop (unsigned HOST_WIDE_INT opint[], long op_const)
6486 unsigned HOST_WIDE_INT temp, op;
6494 temp++, op &= op - 1;
6496 return build_int_cst (long_integer_type_node, temp);
6499 /* Fold one of our builtin functions. */
6502 alpha_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
6504 tree op[MAX_ARGS], t;
6505 unsigned HOST_WIDE_INT opint[MAX_ARGS];
6506 long op_const = 0, arity = 0;
6508 for (t = arglist; t ; t = TREE_CHAIN (t), ++arity)
6510 tree arg = TREE_VALUE (t);
6511 if (arg == error_mark_node)
6513 if (arity >= MAX_ARGS)
6518 if (TREE_CODE (arg) == INTEGER_CST)
6520 op_const |= 1L << arity;
6521 opint[arity] = int_cst_value (arg);
6525 switch (DECL_FUNCTION_CODE (fndecl))
6527 case ALPHA_BUILTIN_CMPBGE:
6528 return alpha_fold_builtin_cmpbge (opint, op_const);
6530 case ALPHA_BUILTIN_EXTBL:
6531 return alpha_fold_builtin_extxx (op, opint, op_const, 0x01, false);
6532 case ALPHA_BUILTIN_EXTWL:
6533 return alpha_fold_builtin_extxx (op, opint, op_const, 0x03, false);
6534 case ALPHA_BUILTIN_EXTLL:
6535 return alpha_fold_builtin_extxx (op, opint, op_const, 0x0f, false);
6536 case ALPHA_BUILTIN_EXTQL:
6537 return alpha_fold_builtin_extxx (op, opint, op_const, 0xff, false);
6538 case ALPHA_BUILTIN_EXTWH:
6539 return alpha_fold_builtin_extxx (op, opint, op_const, 0x03, true);
6540 case ALPHA_BUILTIN_EXTLH:
6541 return alpha_fold_builtin_extxx (op, opint, op_const, 0x0f, true);
6542 case ALPHA_BUILTIN_EXTQH:
6543 return alpha_fold_builtin_extxx (op, opint, op_const, 0xff, true);
6545 case ALPHA_BUILTIN_INSBL:
6546 return alpha_fold_builtin_insxx (op, opint, op_const, 0x01, false);
6547 case ALPHA_BUILTIN_INSWL:
6548 return alpha_fold_builtin_insxx (op, opint, op_const, 0x03, false);
6549 case ALPHA_BUILTIN_INSLL:
6550 return alpha_fold_builtin_insxx (op, opint, op_const, 0x0f, false);
6551 case ALPHA_BUILTIN_INSQL:
6552 return alpha_fold_builtin_insxx (op, opint, op_const, 0xff, false);
6553 case ALPHA_BUILTIN_INSWH:
6554 return alpha_fold_builtin_insxx (op, opint, op_const, 0x03, true);
6555 case ALPHA_BUILTIN_INSLH:
6556 return alpha_fold_builtin_insxx (op, opint, op_const, 0x0f, true);
6557 case ALPHA_BUILTIN_INSQH:
6558 return alpha_fold_builtin_insxx (op, opint, op_const, 0xff, true);
6560 case ALPHA_BUILTIN_MSKBL:
6561 return alpha_fold_builtin_mskxx (op, opint, op_const, 0x01, false);
6562 case ALPHA_BUILTIN_MSKWL:
6563 return alpha_fold_builtin_mskxx (op, opint, op_const, 0x03, false);
6564 case ALPHA_BUILTIN_MSKLL:
6565 return alpha_fold_builtin_mskxx (op, opint, op_const, 0x0f, false);
6566 case ALPHA_BUILTIN_MSKQL:
6567 return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, false);
6568 case ALPHA_BUILTIN_MSKWH:
6569 return alpha_fold_builtin_mskxx (op, opint, op_const, 0x03, true);
6570 case ALPHA_BUILTIN_MSKLH:
6571 return alpha_fold_builtin_mskxx (op, opint, op_const, 0x0f, true);
6572 case ALPHA_BUILTIN_MSKQH:
6573 return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, true);
6575 case ALPHA_BUILTIN_UMULH:
6576 return alpha_fold_builtin_umulh (opint, op_const);
6578 case ALPHA_BUILTIN_ZAP:
6581 case ALPHA_BUILTIN_ZAPNOT:
6582 return alpha_fold_builtin_zapnot (op, opint, op_const);
6584 case ALPHA_BUILTIN_MINUB8:
6585 return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v8qi_u);
6586 case ALPHA_BUILTIN_MINSB8:
6587 return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v8qi_s);
6588 case ALPHA_BUILTIN_MINUW4:
6589 return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v4hi_u);
6590 case ALPHA_BUILTIN_MINSW4:
6591 return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v4hi_s);
6592 case ALPHA_BUILTIN_MAXUB8:
6593 return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v8qi_u);
6594 case ALPHA_BUILTIN_MAXSB8:
6595 return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v8qi_s);
6596 case ALPHA_BUILTIN_MAXUW4:
6597 return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v4hi_u);
6598 case ALPHA_BUILTIN_MAXSW4:
6599 return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v4hi_s);
6601 case ALPHA_BUILTIN_PERR:
6602 return alpha_fold_builtin_perr (opint, op_const);
6603 case ALPHA_BUILTIN_PKLB:
6604 return alpha_fold_builtin_pklb (opint, op_const);
6605 case ALPHA_BUILTIN_PKWB:
6606 return alpha_fold_builtin_pkwb (opint, op_const);
6607 case ALPHA_BUILTIN_UNPKBL:
6608 return alpha_fold_builtin_unpkbl (opint, op_const);
6609 case ALPHA_BUILTIN_UNPKBW:
6610 return alpha_fold_builtin_unpkbw (opint, op_const);
6612 case ALPHA_BUILTIN_CTTZ:
6613 return alpha_fold_builtin_cttz (opint, op_const);
6614 case ALPHA_BUILTIN_CTLZ:
6615 return alpha_fold_builtin_ctlz (opint, op_const);
6616 case ALPHA_BUILTIN_CTPOP:
6617 return alpha_fold_builtin_ctpop (opint, op_const);
6619 case ALPHA_BUILTIN_AMASK:
6620 case ALPHA_BUILTIN_IMPLVER:
6621 case ALPHA_BUILTIN_RPCC:
6622 case ALPHA_BUILTIN_THREAD_POINTER:
6623 case ALPHA_BUILTIN_SET_THREAD_POINTER:
6624 /* None of these are foldable at compile-time. */
6630 /* This page contains routines that are used to determine what the function
6631 prologue and epilogue code will do and write them out. */
6633 /* Compute the size of the save area in the stack. */
6635 /* These variables are used for communication between the following functions.
6636 They indicate various things about the current function being compiled
6637 that are used to tell what kind of prologue, epilogue and procedure
6638 descriptor to generate. */
6640 /* Nonzero if we need a stack procedure. */
6641 enum alpha_procedure_types {PT_NULL = 0, PT_REGISTER = 1, PT_STACK = 2};
6642 static enum alpha_procedure_types alpha_procedure_type;
6644 /* Register number (either FP or SP) that is used to unwind the frame. */
6645 static int vms_unwind_regno;
6647 /* Register number used to save FP. We need not have one for RA since
6648 we don't modify it for register procedures. This is only defined
6649 for register frame procedures. */
6650 static int vms_save_fp_regno;
6652 /* Register number used to reference objects off our PV. */
6653 static int vms_base_regno;
6655 /* Compute register masks for saved registers. */
6658 alpha_sa_mask (unsigned long *imaskP, unsigned long *fmaskP)
6660 unsigned long imask = 0;
6661 unsigned long fmask = 0;
6664 /* When outputting a thunk, we don't have valid register life info,
6665 but assemble_start_function wants to output .frame and .mask
6667 if (current_function_is_thunk)
6674 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
6675 imask |= (1UL << HARD_FRAME_POINTER_REGNUM);
6677 /* One for every register we have to save. */
6678 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
6679 if (! fixed_regs[i] && ! call_used_regs[i]
6680 && regs_ever_live[i] && i != REG_RA
6681 && (!TARGET_ABI_UNICOSMK || i != HARD_FRAME_POINTER_REGNUM))
6684 imask |= (1UL << i);
6686 fmask |= (1UL << (i - 32));
6689 /* We need to restore these for the handler. */
6690 if (current_function_calls_eh_return)
6694 unsigned regno = EH_RETURN_DATA_REGNO (i);
6695 if (regno == INVALID_REGNUM)
6697 imask |= 1UL << regno;
6701 /* If any register spilled, then spill the return address also. */
6702 /* ??? This is required by the Digital stack unwind specification
6703 and isn't needed if we're doing Dwarf2 unwinding. */
6704 if (imask || fmask || alpha_ra_ever_killed ())
6705 imask |= (1UL << REG_RA);
6712 alpha_sa_size (void)
6714 unsigned long mask[2];
6718 alpha_sa_mask (&mask[0], &mask[1]);
6720 if (TARGET_ABI_UNICOSMK)
6722 if (mask[0] || mask[1])
6727 for (j = 0; j < 2; ++j)
6728 for (i = 0; i < 32; ++i)
6729 if ((mask[j] >> i) & 1)
6733 if (TARGET_ABI_UNICOSMK)
6735 /* We might not need to generate a frame if we don't make any calls
6736 (including calls to __T3E_MISMATCH if this is a vararg function),
6737 don't have any local variables which require stack slots, don't
6738 use alloca and have not determined that we need a frame for other
6741 alpha_procedure_type
6742 = (sa_size || get_frame_size() != 0
6743 || current_function_outgoing_args_size
6744 || current_function_stdarg || current_function_calls_alloca
6745 || frame_pointer_needed)
6746 ? PT_STACK : PT_REGISTER;
6748 /* Always reserve space for saving callee-saved registers if we
6749 need a frame as required by the calling convention. */
6750 if (alpha_procedure_type == PT_STACK)
6753 else if (TARGET_ABI_OPEN_VMS)
6755 /* Start by assuming we can use a register procedure if we don't
6756 make any calls (REG_RA not used) or need to save any
6757 registers and a stack procedure if we do. */
6758 if ((mask[0] >> REG_RA) & 1)
6759 alpha_procedure_type = PT_STACK;
6760 else if (get_frame_size() != 0)
6761 alpha_procedure_type = PT_REGISTER;
6763 alpha_procedure_type = PT_NULL;
6765 /* Don't reserve space for saving FP & RA yet. Do that later after we've
6766 made the final decision on stack procedure vs register procedure. */
6767 if (alpha_procedure_type == PT_STACK)
6770 /* Decide whether to refer to objects off our PV via FP or PV.
6771 If we need FP for something else or if we receive a nonlocal
6772 goto (which expects PV to contain the value), we must use PV.
6773 Otherwise, start by assuming we can use FP. */
6776 = (frame_pointer_needed
6777 || current_function_has_nonlocal_label
6778 || alpha_procedure_type == PT_STACK
6779 || current_function_outgoing_args_size)
6780 ? REG_PV : HARD_FRAME_POINTER_REGNUM;
6782 /* If we want to copy PV into FP, we need to find some register
6783 in which to save FP. */
6785 vms_save_fp_regno = -1;
6786 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
6787 for (i = 0; i < 32; i++)
6788 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
6789 vms_save_fp_regno = i;
6791 if (vms_save_fp_regno == -1 && alpha_procedure_type == PT_REGISTER)
6792 vms_base_regno = REG_PV, alpha_procedure_type = PT_STACK;
6793 else if (alpha_procedure_type == PT_NULL)
6794 vms_base_regno = REG_PV;
6796 /* Stack unwinding should be done via FP unless we use it for PV. */
6797 vms_unwind_regno = (vms_base_regno == REG_PV
6798 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
6800 /* If this is a stack procedure, allow space for saving FP and RA. */
6801 if (alpha_procedure_type == PT_STACK)
6806 /* Our size must be even (multiple of 16 bytes). */
6814 /* Define the offset between two registers, one to be eliminated,
6815 and the other its replacement, at the start of a routine. */
6818 alpha_initial_elimination_offset (unsigned int from,
6819 unsigned int to ATTRIBUTE_UNUSED)
6823 ret = alpha_sa_size ();
6824 ret += ALPHA_ROUND (current_function_outgoing_args_size);
6826 if (from == FRAME_POINTER_REGNUM)
6828 else if (from == ARG_POINTER_REGNUM)
6829 ret += (ALPHA_ROUND (get_frame_size ()
6830 + current_function_pretend_args_size)
6831 - current_function_pretend_args_size);
6839 alpha_pv_save_size (void)
6842 return alpha_procedure_type == PT_STACK ? 8 : 0;
6846 alpha_using_fp (void)
6849 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
6852 #if TARGET_ABI_OPEN_VMS
6854 const struct attribute_spec vms_attribute_table[] =
6856 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
6857 { "overlaid", 0, 0, true, false, false, NULL },
6858 { "global", 0, 0, true, false, false, NULL },
6859 { "initialize", 0, 0, true, false, false, NULL },
6860 { NULL, 0, 0, false, false, false, NULL }
6866 find_lo_sum_using_gp (rtx *px, void *data ATTRIBUTE_UNUSED)
6868 return GET_CODE (*px) == LO_SUM && XEXP (*px, 0) == pic_offset_table_rtx;
6872 alpha_find_lo_sum_using_gp (rtx insn)
6874 return for_each_rtx (&PATTERN (insn), find_lo_sum_using_gp, NULL) > 0;
6878 alpha_does_function_need_gp (void)
6882 /* The GP being variable is an OSF abi thing. */
6883 if (! TARGET_ABI_OSF)
6886 /* We need the gp to load the address of __mcount. */
6887 if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
6890 /* The code emitted by alpha_output_mi_thunk_osf uses the gp. */
6891 if (current_function_is_thunk)
6894 /* The nonlocal receiver pattern assumes that the gp is valid for
6895 the nested function. Reasonable because it's almost always set
6896 correctly already. For the cases where that's wrong, make sure
6897 the nested function loads its gp on entry. */
6898 if (current_function_has_nonlocal_goto)
6901 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
6902 Even if we are a static function, we still need to do this in case
6903 our address is taken and passed to something like qsort. */
6905 push_topmost_sequence ();
6906 insn = get_insns ();
6907 pop_topmost_sequence ();
6909 for (; insn; insn = NEXT_INSN (insn))
6911 && GET_CODE (PATTERN (insn)) != USE
6912 && GET_CODE (PATTERN (insn)) != CLOBBER
6913 && get_attr_usegp (insn))
6920 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
6924 set_frame_related_p (void)
6926 rtx seq = get_insns ();
6937 while (insn != NULL_RTX)
6939 RTX_FRAME_RELATED_P (insn) = 1;
6940 insn = NEXT_INSN (insn);
6942 seq = emit_insn (seq);
6946 seq = emit_insn (seq);
6947 RTX_FRAME_RELATED_P (seq) = 1;
6952 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
6954 /* Generates a store with the proper unwind info attached. VALUE is
6955 stored at BASE_REG+BASE_OFS. If FRAME_BIAS is nonzero, then BASE_REG
6956 contains SP+FRAME_BIAS, and that is the unwind info that should be
6957 generated. If FRAME_REG != VALUE, then VALUE is being stored on
6958 behalf of FRAME_REG, and FRAME_REG should be present in the unwind. */
6961 emit_frame_store_1 (rtx value, rtx base_reg, HOST_WIDE_INT frame_bias,
6962 HOST_WIDE_INT base_ofs, rtx frame_reg)
6964 rtx addr, mem, insn;
6966 addr = plus_constant (base_reg, base_ofs);
6967 mem = gen_rtx_MEM (DImode, addr);
6968 set_mem_alias_set (mem, alpha_sr_alias_set);
6970 insn = emit_move_insn (mem, value);
6971 RTX_FRAME_RELATED_P (insn) = 1;
6973 if (frame_bias || value != frame_reg)
6977 addr = plus_constant (stack_pointer_rtx, frame_bias + base_ofs);
6978 mem = gen_rtx_MEM (DImode, addr);
6982 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6983 gen_rtx_SET (VOIDmode, mem, frame_reg),
6989 emit_frame_store (unsigned int regno, rtx base_reg,
6990 HOST_WIDE_INT frame_bias, HOST_WIDE_INT base_ofs)
6992 rtx reg = gen_rtx_REG (DImode, regno);
6993 emit_frame_store_1 (reg, base_reg, frame_bias, base_ofs, reg);
6996 /* Write function prologue. */
6998 /* On vms we have two kinds of functions:
7000 - stack frame (PROC_STACK)
7001 these are 'normal' functions with local vars and which are
7002 calling other functions
7003 - register frame (PROC_REGISTER)
7004 keeps all data in registers, needs no stack
7006 We must pass this to the assembler so it can generate the
7007 proper pdsc (procedure descriptor)
7008 This is done with the '.pdesc' command.
7010 On not-vms, we don't really differentiate between the two, as we can
7011 simply allocate stack without saving registers. */
7014 alpha_expand_prologue (void)
7016 /* Registers to save. */
7017 unsigned long imask = 0;
7018 unsigned long fmask = 0;
7019 /* Stack space needed for pushing registers clobbered by us. */
7020 HOST_WIDE_INT sa_size;
7021 /* Complete stack size needed. */
7022 HOST_WIDE_INT frame_size;
7023 /* Offset from base reg to register save area. */
7024 HOST_WIDE_INT reg_offset;
7028 sa_size = alpha_sa_size ();
7030 frame_size = get_frame_size ();
7031 if (TARGET_ABI_OPEN_VMS)
7032 frame_size = ALPHA_ROUND (sa_size
7033 + (alpha_procedure_type == PT_STACK ? 8 : 0)
7035 + current_function_pretend_args_size);
7036 else if (TARGET_ABI_UNICOSMK)
7037 /* We have to allocate space for the DSIB if we generate a frame. */
7038 frame_size = ALPHA_ROUND (sa_size
7039 + (alpha_procedure_type == PT_STACK ? 48 : 0))
7040 + ALPHA_ROUND (frame_size
7041 + current_function_outgoing_args_size);
7043 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
7045 + ALPHA_ROUND (frame_size
7046 + current_function_pretend_args_size));
7048 if (TARGET_ABI_OPEN_VMS)
7051 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
7053 alpha_sa_mask (&imask, &fmask);
7055 /* Emit an insn to reload GP, if needed. */
7058 alpha_function_needs_gp = alpha_does_function_need_gp ();
7059 if (alpha_function_needs_gp)
7060 emit_insn (gen_prologue_ldgp ());
7063 /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert
7064 the call to mcount ourselves, rather than having the linker do it
7065 magically in response to -pg. Since _mcount has special linkage,
7066 don't represent the call as a call. */
7067 if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
7068 emit_insn (gen_prologue_mcount ());
7070 if (TARGET_ABI_UNICOSMK)
7071 unicosmk_gen_dsib (&imask);
7073 /* Adjust the stack by the frame size. If the frame size is > 4096
7074 bytes, we need to be sure we probe somewhere in the first and last
7075 4096 bytes (we can probably get away without the latter test) and
7076 every 8192 bytes in between. If the frame size is > 32768, we
7077 do this in a loop. Otherwise, we generate the explicit probe
7080 Note that we are only allowed to adjust sp once in the prologue. */
7082 if (frame_size <= 32768)
7084 if (frame_size > 4096)
7089 emit_insn (gen_probe_stack (GEN_INT (TARGET_ABI_UNICOSMK
7092 while ((probed += 8192) < frame_size);
7094 /* We only have to do this probe if we aren't saving registers. */
7095 if (sa_size == 0 && probed + 4096 < frame_size)
7096 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
7099 if (frame_size != 0)
7100 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
7101 GEN_INT (TARGET_ABI_UNICOSMK
7107 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
7108 number of 8192 byte blocks to probe. We then probe each block
7109 in the loop and then set SP to the proper location. If the
7110 amount remaining is > 4096, we have to do one more probe if we
7111 are not saving any registers. */
7113 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
7114 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
7115 rtx ptr = gen_rtx_REG (DImode, 22);
7116 rtx count = gen_rtx_REG (DImode, 23);
7119 emit_move_insn (count, GEN_INT (blocks));
7120 emit_insn (gen_adddi3 (ptr, stack_pointer_rtx,
7121 GEN_INT (TARGET_ABI_UNICOSMK ? 4096 - 64 : 4096)));
7123 /* Because of the difficulty in emitting a new basic block this
7124 late in the compilation, generate the loop as a single insn. */
7125 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
7127 if (leftover > 4096 && sa_size == 0)
7129 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
7130 MEM_VOLATILE_P (last) = 1;
7131 emit_move_insn (last, const0_rtx);
7134 if (TARGET_ABI_WINDOWS_NT)
7136 /* For NT stack unwind (done by 'reverse execution'), it's
7137 not OK to take the result of a loop, even though the value
7138 is already in ptr, so we reload it via a single operation
7139 and subtract it to sp.
7141 Yes, that's correct -- we have to reload the whole constant
7142 into a temporary via ldah+lda then subtract from sp. */
7144 HOST_WIDE_INT lo, hi;
7145 lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
7146 hi = frame_size - lo;
7148 emit_move_insn (ptr, GEN_INT (hi));
7149 emit_insn (gen_adddi3 (ptr, ptr, GEN_INT (lo)));
7150 seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
7155 seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
7156 GEN_INT (-leftover)));
7159 /* This alternative is special, because the DWARF code cannot
7160 possibly intuit through the loop above. So we invent this
7161 note it looks at instead. */
7162 RTX_FRAME_RELATED_P (seq) = 1;
7164 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
7165 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
7166 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
7167 GEN_INT (TARGET_ABI_UNICOSMK
7173 if (!TARGET_ABI_UNICOSMK)
7175 HOST_WIDE_INT sa_bias = 0;
7177 /* Cope with very large offsets to the register save area. */
7178 sa_reg = stack_pointer_rtx;
7179 if (reg_offset + sa_size > 0x8000)
7181 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
7184 if (low + sa_size <= 0x8000)
7185 sa_bias = reg_offset - low, reg_offset = low;
7187 sa_bias = reg_offset, reg_offset = 0;
7189 sa_reg = gen_rtx_REG (DImode, 24);
7190 sa_bias_rtx = GEN_INT (sa_bias);
7192 if (add_operand (sa_bias_rtx, DImode))
7193 emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_bias_rtx));
7196 emit_move_insn (sa_reg, sa_bias_rtx);
7197 emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_reg));
7201 /* Save regs in stack order. Beginning with VMS PV. */
7202 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
7203 emit_frame_store (REG_PV, stack_pointer_rtx, 0, 0);
7205 /* Save register RA next. */
7206 if (imask & (1UL << REG_RA))
7208 emit_frame_store (REG_RA, sa_reg, sa_bias, reg_offset);
7209 imask &= ~(1UL << REG_RA);
7213 /* Now save any other registers required to be saved. */
7214 for (i = 0; i < 31; i++)
7215 if (imask & (1UL << i))
7217 emit_frame_store (i, sa_reg, sa_bias, reg_offset);
7221 for (i = 0; i < 31; i++)
7222 if (fmask & (1UL << i))
7224 emit_frame_store (i+32, sa_reg, sa_bias, reg_offset);
7228 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
7230 /* The standard frame on the T3E includes space for saving registers.
7231 We just have to use it. We don't have to save the return address and
7232 the old frame pointer here - they are saved in the DSIB. */
7235 for (i = 9; i < 15; i++)
7236 if (imask & (1UL << i))
7238 emit_frame_store (i, hard_frame_pointer_rtx, 0, reg_offset);
7241 for (i = 2; i < 10; i++)
7242 if (fmask & (1UL << i))
7244 emit_frame_store (i+32, hard_frame_pointer_rtx, 0, reg_offset);
7249 if (TARGET_ABI_OPEN_VMS)
7251 if (alpha_procedure_type == PT_REGISTER)
7252 /* Register frame procedures save the fp.
7253 ?? Ought to have a dwarf2 save for this. */
7254 emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
7255 hard_frame_pointer_rtx);
7257 if (alpha_procedure_type != PT_NULL && vms_base_regno != REG_PV)
7258 emit_insn (gen_force_movdi (gen_rtx_REG (DImode, vms_base_regno),
7259 gen_rtx_REG (DImode, REG_PV)));
7261 if (alpha_procedure_type != PT_NULL
7262 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
7263 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
7265 /* If we have to allocate space for outgoing args, do it now. */
7266 if (current_function_outgoing_args_size != 0)
7269 = emit_move_insn (stack_pointer_rtx,
7271 (hard_frame_pointer_rtx,
7273 (current_function_outgoing_args_size))));
7275 /* Only set FRAME_RELATED_P on the stack adjustment we just emitted
7276 if ! frame_pointer_needed. Setting the bit will change the CFA
7277 computation rule to use sp again, which would be wrong if we had
7278 frame_pointer_needed, as this means sp might move unpredictably
7282 frame_pointer_needed
7283 => vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
7285 current_function_outgoing_args_size != 0
7286 => alpha_procedure_type != PT_NULL,
7288 so when we are not setting the bit here, we are guaranteed to
7289 have emitted an FRP frame pointer update just before. */
7290 RTX_FRAME_RELATED_P (seq) = ! frame_pointer_needed;
7293 else if (!TARGET_ABI_UNICOSMK)
7295 /* If we need a frame pointer, set it from the stack pointer. */
7296 if (frame_pointer_needed)
7298 if (TARGET_CAN_FAULT_IN_PROLOGUE)
7299 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
7301 /* This must always be the last instruction in the
7302 prologue, thus we emit a special move + clobber. */
7303 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
7304 stack_pointer_rtx, sa_reg)));
7308 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
7309 the prologue, for exception handling reasons, we cannot do this for
7310 any insn that might fault. We could prevent this for mems with a
7311 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
7312 have to prevent all such scheduling with a blockage.
7314 Linux, on the other hand, never bothered to implement OSF/1's
7315 exception handling, and so doesn't care about such things. Anyone
7316 planning to use dwarf2 frame-unwind info can also omit the blockage. */
7318 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
7319 emit_insn (gen_blockage ());
7322 /* Count the number of .file directives, so that .loc is up to date. */
7323 int num_source_filenames = 0;
7325 /* Output the textual info surrounding the prologue. */
7328 alpha_start_function (FILE *file, const char *fnname,
7329 tree decl ATTRIBUTE_UNUSED)
7331 unsigned long imask = 0;
7332 unsigned long fmask = 0;
7333 /* Stack space needed for pushing registers clobbered by us. */
7334 HOST_WIDE_INT sa_size;
7335 /* Complete stack size needed. */
7336 unsigned HOST_WIDE_INT frame_size;
7337 /* Offset from base reg to register save area. */
7338 HOST_WIDE_INT reg_offset;
7339 char *entry_label = (char *) alloca (strlen (fnname) + 6);
7342 /* Don't emit an extern directive for functions defined in the same file. */
7343 if (TARGET_ABI_UNICOSMK)
7346 name_tree = get_identifier (fnname);
7347 TREE_ASM_WRITTEN (name_tree) = 1;
7350 alpha_fnname = fnname;
7351 sa_size = alpha_sa_size ();
7353 frame_size = get_frame_size ();
7354 if (TARGET_ABI_OPEN_VMS)
7355 frame_size = ALPHA_ROUND (sa_size
7356 + (alpha_procedure_type == PT_STACK ? 8 : 0)
7358 + current_function_pretend_args_size);
7359 else if (TARGET_ABI_UNICOSMK)
7360 frame_size = ALPHA_ROUND (sa_size
7361 + (alpha_procedure_type == PT_STACK ? 48 : 0))
7362 + ALPHA_ROUND (frame_size
7363 + current_function_outgoing_args_size);
7365 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
7367 + ALPHA_ROUND (frame_size
7368 + current_function_pretend_args_size));
7370 if (TARGET_ABI_OPEN_VMS)
7373 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
7375 alpha_sa_mask (&imask, &fmask);
7377 /* Ecoff can handle multiple .file directives, so put out file and lineno.
7378 We have to do that before the .ent directive as we cannot switch
7379 files within procedures with native ecoff because line numbers are
7380 linked to procedure descriptors.
7381 Outputting the lineno helps debugging of one line functions as they
7382 would otherwise get no line number at all. Please note that we would
7383 like to put out last_linenum from final.c, but it is not accessible. */
7385 if (write_symbols == SDB_DEBUG)
7387 #ifdef ASM_OUTPUT_SOURCE_FILENAME
7388 ASM_OUTPUT_SOURCE_FILENAME (file,
7389 DECL_SOURCE_FILE (current_function_decl));
7391 #ifdef SDB_OUTPUT_SOURCE_LINE
7392 if (debug_info_level != DINFO_LEVEL_TERSE)
7393 SDB_OUTPUT_SOURCE_LINE (file,
7394 DECL_SOURCE_LINE (current_function_decl));
7398 /* Issue function start and label. */
7399 if (TARGET_ABI_OPEN_VMS
7400 || (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive))
7402 fputs ("\t.ent ", file);
7403 assemble_name (file, fnname);
7406 /* If the function needs GP, we'll write the "..ng" label there.
7407 Otherwise, do it here. */
7409 && ! alpha_function_needs_gp
7410 && ! current_function_is_thunk)
7413 assemble_name (file, fnname);
7414 fputs ("..ng:\n", file);
7418 strcpy (entry_label, fnname);
7419 if (TARGET_ABI_OPEN_VMS)
7420 strcat (entry_label, "..en");
7422 /* For public functions, the label must be globalized by appending an
7423 additional colon. */
7424 if (TARGET_ABI_UNICOSMK && TREE_PUBLIC (decl))
7425 strcat (entry_label, ":");
7427 ASM_OUTPUT_LABEL (file, entry_label);
7428 inside_function = TRUE;
7430 if (TARGET_ABI_OPEN_VMS)
7431 fprintf (file, "\t.base $%d\n", vms_base_regno);
7433 if (!TARGET_ABI_OPEN_VMS && !TARGET_ABI_UNICOSMK && TARGET_IEEE_CONFORMANT
7434 && !flag_inhibit_size_directive)
7436 /* Set flags in procedure descriptor to request IEEE-conformant
7437 math-library routines. The value we set it to is PDSC_EXC_IEEE
7438 (/usr/include/pdsc.h). */
7439 fputs ("\t.eflag 48\n", file);
7442 /* Set up offsets to alpha virtual arg/local debugging pointer. */
7443 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
7444 alpha_arg_offset = -frame_size + 48;
7446 /* Describe our frame. If the frame size is larger than an integer,
7447 print it as zero to avoid an assembler error. We won't be
7448 properly describing such a frame, but that's the best we can do. */
7449 if (TARGET_ABI_UNICOSMK)
7451 else if (TARGET_ABI_OPEN_VMS)
7452 fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,"
7453 HOST_WIDE_INT_PRINT_DEC "\n",
7455 frame_size >= (1UL << 31) ? 0 : frame_size,
7457 else if (!flag_inhibit_size_directive)
7458 fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,%d\n",
7459 (frame_pointer_needed
7460 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
7461 frame_size >= (1UL << 31) ? 0 : frame_size,
7462 current_function_pretend_args_size);
7464 /* Describe which registers were spilled. */
7465 if (TARGET_ABI_UNICOSMK)
7467 else if (TARGET_ABI_OPEN_VMS)
7470 /* ??? Does VMS care if mask contains ra? The old code didn't
7471 set it, so I don't here. */
7472 fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1UL << REG_RA));
7474 fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
7475 if (alpha_procedure_type == PT_REGISTER)
7476 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
7478 else if (!flag_inhibit_size_directive)
7482 fprintf (file, "\t.mask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", imask,
7483 frame_size >= (1UL << 31) ? 0 : reg_offset - frame_size);
7485 for (i = 0; i < 32; ++i)
7486 if (imask & (1UL << i))
7491 fprintf (file, "\t.fmask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", fmask,
7492 frame_size >= (1UL << 31) ? 0 : reg_offset - frame_size);
7495 #if TARGET_ABI_OPEN_VMS
7496 /* Ifdef'ed cause link_section are only available then. */
7497 readonly_data_section ();
7498 fprintf (file, "\t.align 3\n");
7499 assemble_name (file, fnname); fputs ("..na:\n", file);
7500 fputs ("\t.ascii \"", file);
7501 assemble_name (file, fnname);
7502 fputs ("\\0\"\n", file);
7503 alpha_need_linkage (fnname, 1);
7508 /* Emit the .prologue note at the scheduled end of the prologue. */
7511 alpha_output_function_end_prologue (FILE *file)
7513 if (TARGET_ABI_UNICOSMK)
7515 else if (TARGET_ABI_OPEN_VMS)
7516 fputs ("\t.prologue\n", file);
7517 else if (TARGET_ABI_WINDOWS_NT)
7518 fputs ("\t.prologue 0\n", file);
7519 else if (!flag_inhibit_size_directive)
7520 fprintf (file, "\t.prologue %d\n",
7521 alpha_function_needs_gp || current_function_is_thunk);
7524 /* Write function epilogue. */
7526 /* ??? At some point we will want to support full unwind, and so will
7527 need to mark the epilogue as well. At the moment, we just confuse
7530 #define FRP(exp) exp
7533 alpha_expand_epilogue (void)
7535 /* Registers to save. */
7536 unsigned long imask = 0;
7537 unsigned long fmask = 0;
7538 /* Stack space needed for pushing registers clobbered by us. */
7539 HOST_WIDE_INT sa_size;
7540 /* Complete stack size needed. */
7541 HOST_WIDE_INT frame_size;
7542 /* Offset from base reg to register save area. */
7543 HOST_WIDE_INT reg_offset;
7544 int fp_is_frame_pointer, fp_offset;
7545 rtx sa_reg, sa_reg_exp = NULL;
7546 rtx sp_adj1, sp_adj2, mem;
7550 sa_size = alpha_sa_size ();
7552 frame_size = get_frame_size ();
7553 if (TARGET_ABI_OPEN_VMS)
7554 frame_size = ALPHA_ROUND (sa_size
7555 + (alpha_procedure_type == PT_STACK ? 8 : 0)
7557 + current_function_pretend_args_size);
7558 else if (TARGET_ABI_UNICOSMK)
7559 frame_size = ALPHA_ROUND (sa_size
7560 + (alpha_procedure_type == PT_STACK ? 48 : 0))
7561 + ALPHA_ROUND (frame_size
7562 + current_function_outgoing_args_size);
7564 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
7566 + ALPHA_ROUND (frame_size
7567 + current_function_pretend_args_size));
7569 if (TARGET_ABI_OPEN_VMS)
7571 if (alpha_procedure_type == PT_STACK)
7577 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
7579 alpha_sa_mask (&imask, &fmask);
7582 = ((TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
7583 || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed));
7585 sa_reg = stack_pointer_rtx;
7587 if (current_function_calls_eh_return)
7588 eh_ofs = EH_RETURN_STACKADJ_RTX;
7592 if (!TARGET_ABI_UNICOSMK && sa_size)
7594 /* If we have a frame pointer, restore SP from it. */
7595 if ((TARGET_ABI_OPEN_VMS
7596 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
7597 || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed))
7598 FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
7600 /* Cope with very large offsets to the register save area. */
7601 if (reg_offset + sa_size > 0x8000)
7603 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
7606 if (low + sa_size <= 0x8000)
7607 bias = reg_offset - low, reg_offset = low;
7609 bias = reg_offset, reg_offset = 0;
7611 sa_reg = gen_rtx_REG (DImode, 22);
7612 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
7614 FRP (emit_move_insn (sa_reg, sa_reg_exp));
7617 /* Restore registers in order, excepting a true frame pointer. */
7619 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
7621 set_mem_alias_set (mem, alpha_sr_alias_set);
7622 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
7625 imask &= ~(1UL << REG_RA);
7627 for (i = 0; i < 31; ++i)
7628 if (imask & (1UL << i))
7630 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
7631 fp_offset = reg_offset;
7634 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
7635 set_mem_alias_set (mem, alpha_sr_alias_set);
7636 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
7641 for (i = 0; i < 31; ++i)
7642 if (fmask & (1UL << i))
7644 mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
7645 set_mem_alias_set (mem, alpha_sr_alias_set);
7646 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
7650 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
7652 /* Restore callee-saved general-purpose registers. */
7656 for (i = 9; i < 15; i++)
7657 if (imask & (1UL << i))
7659 mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx,
7661 set_mem_alias_set (mem, alpha_sr_alias_set);
7662 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
7666 for (i = 2; i < 10; i++)
7667 if (fmask & (1UL << i))
7669 mem = gen_rtx_MEM (DFmode, plus_constant(hard_frame_pointer_rtx,
7671 set_mem_alias_set (mem, alpha_sr_alias_set);
7672 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
7676 /* Restore the return address from the DSIB. */
7678 mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx, -8));
7679 set_mem_alias_set (mem, alpha_sr_alias_set);
7680 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
7683 if (frame_size || eh_ofs)
7685 sp_adj1 = stack_pointer_rtx;
7689 sp_adj1 = gen_rtx_REG (DImode, 23);
7690 emit_move_insn (sp_adj1,
7691 gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
7694 /* If the stack size is large, begin computation into a temporary
7695 register so as not to interfere with a potential fp restore,
7696 which must be consecutive with an SP restore. */
7697 if (frame_size < 32768
7698 && ! (TARGET_ABI_UNICOSMK && current_function_calls_alloca))
7699 sp_adj2 = GEN_INT (frame_size);
7700 else if (TARGET_ABI_UNICOSMK)
7702 sp_adj1 = gen_rtx_REG (DImode, 23);
7703 FRP (emit_move_insn (sp_adj1, hard_frame_pointer_rtx));
7704 sp_adj2 = const0_rtx;
7706 else if (frame_size < 0x40007fffL)
7708 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
7710 sp_adj2 = plus_constant (sp_adj1, frame_size - low);
7711 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
7715 sp_adj1 = gen_rtx_REG (DImode, 23);
7716 FRP (emit_move_insn (sp_adj1, sp_adj2));
7718 sp_adj2 = GEN_INT (low);
7722 rtx tmp = gen_rtx_REG (DImode, 23);
7723 FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size,
7727 /* We can't drop new things to memory this late, afaik,
7728 so build it up by pieces. */
7729 FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
7730 -(frame_size < 0)));
7736 /* From now on, things must be in order. So emit blockages. */
7738 /* Restore the frame pointer. */
7739 if (TARGET_ABI_UNICOSMK)
7741 emit_insn (gen_blockage ());
7742 mem = gen_rtx_MEM (DImode,
7743 plus_constant (hard_frame_pointer_rtx, -16));
7744 set_mem_alias_set (mem, alpha_sr_alias_set);
7745 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
7747 else if (fp_is_frame_pointer)
7749 emit_insn (gen_blockage ());
7750 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, fp_offset));
7751 set_mem_alias_set (mem, alpha_sr_alias_set);
7752 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
7754 else if (TARGET_ABI_OPEN_VMS)
7756 emit_insn (gen_blockage ());
7757 FRP (emit_move_insn (hard_frame_pointer_rtx,
7758 gen_rtx_REG (DImode, vms_save_fp_regno)));
7761 /* Restore the stack pointer. */
7762 emit_insn (gen_blockage ());
7763 if (sp_adj2 == const0_rtx)
7764 FRP (emit_move_insn (stack_pointer_rtx, sp_adj1));
7766 FRP (emit_move_insn (stack_pointer_rtx,
7767 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
7771 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_REGISTER)
7773 emit_insn (gen_blockage ());
7774 FRP (emit_move_insn (hard_frame_pointer_rtx,
7775 gen_rtx_REG (DImode, vms_save_fp_regno)));
7777 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type != PT_STACK)
7779 /* Decrement the frame pointer if the function does not have a
7782 emit_insn (gen_blockage ());
7783 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
7784 hard_frame_pointer_rtx, constm1_rtx)));
7789 /* Output the rest of the textual info surrounding the epilogue. */
7792 alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED)
7794 #if TARGET_ABI_OPEN_VMS
7795 alpha_write_linkage (file, fnname, decl);
7798 /* End the function. */
7799 if (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive)
7801 fputs ("\t.end ", file);
7802 assemble_name (file, fnname);
7805 inside_function = FALSE;
7807 /* Output jump tables and the static subroutine information block. */
7808 if (TARGET_ABI_UNICOSMK)
7810 unicosmk_output_ssib (file, fnname);
7811 unicosmk_output_deferred_case_vectors (file);
7816 /* Emit a tail call to FUNCTION after adjusting THIS by DELTA.
7818 In order to avoid the hordes of differences between generated code
7819 with and without TARGET_EXPLICIT_RELOCS, and to avoid duplicating
7820 lots of code loading up large constants, generate rtl and emit it
7821 instead of going straight to text.
7823 Not sure why this idea hasn't been explored before... */
7826 alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
7827 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
7830 HOST_WIDE_INT hi, lo;
7831 rtx this, insn, funexp;
7833 reset_block_changes ();
7835 /* We always require a valid GP. */
7836 emit_insn (gen_prologue_ldgp ());
7837 emit_note (NOTE_INSN_PROLOGUE_END);
7839 /* Find the "this" pointer. If the function returns a structure,
7840 the structure return pointer is in $16. */
7841 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
7842 this = gen_rtx_REG (Pmode, 17);
7844 this = gen_rtx_REG (Pmode, 16);
7846 /* Add DELTA. When possible we use ldah+lda. Otherwise load the
7847 entire constant for the add. */
7848 lo = ((delta & 0xffff) ^ 0x8000) - 0x8000;
7849 hi = (((delta - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
7850 if (hi + lo == delta)
7853 emit_insn (gen_adddi3 (this, this, GEN_INT (hi)));
7855 emit_insn (gen_adddi3 (this, this, GEN_INT (lo)));
7859 rtx tmp = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 0),
7860 delta, -(delta < 0));
7861 emit_insn (gen_adddi3 (this, this, tmp));
7864 /* Add a delta stored in the vtable at VCALL_OFFSET. */
7869 tmp = gen_rtx_REG (Pmode, 0);
7870 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
7872 lo = ((vcall_offset & 0xffff) ^ 0x8000) - 0x8000;
7873 hi = (((vcall_offset - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
7874 if (hi + lo == vcall_offset)
7877 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (hi)));
7881 tmp2 = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 1),
7882 vcall_offset, -(vcall_offset < 0));
7883 emit_insn (gen_adddi3 (tmp, tmp, tmp2));
7887 tmp2 = gen_rtx_PLUS (Pmode, tmp, GEN_INT (lo));
7890 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp2));
7892 emit_insn (gen_adddi3 (this, this, tmp));
7895 /* Generate a tail call to the target function. */
7896 if (! TREE_USED (function))
7898 assemble_external (function);
7899 TREE_USED (function) = 1;
7901 funexp = XEXP (DECL_RTL (function), 0);
7902 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
7903 insn = emit_call_insn (gen_sibcall (funexp, const0_rtx));
7904 SIBLING_CALL_P (insn) = 1;
7906 /* Run just enough of rest_of_compilation to get the insns emitted.
7907 There's not really enough bulk here to make other passes such as
7908 instruction scheduling worth while. Note that use_thunk calls
7909 assemble_start_function and assemble_end_function. */
7910 insn = get_insns ();
7911 insn_locators_initialize ();
7912 shorten_branches (insn);
7913 final_start_function (insn, file, 1);
7914 final (insn, file, 1);
7915 final_end_function ();
7917 #endif /* TARGET_ABI_OSF */
7919 /* Debugging support. */
7923 /* Count the number of sdb related labels are generated (to find block
7924 start and end boundaries). */
7926 int sdb_label_count = 0;
7928 /* Name of the file containing the current function. */
7930 static const char *current_function_file = "";
7932 /* Offsets to alpha virtual arg/local debugging pointers. */
7934 long alpha_arg_offset;
7935 long alpha_auto_offset;
7937 /* Emit a new filename to a stream. */
7940 alpha_output_filename (FILE *stream, const char *name)
7942 static int first_time = TRUE;
7947 ++num_source_filenames;
7948 current_function_file = name;
7949 fprintf (stream, "\t.file\t%d ", num_source_filenames);
7950 output_quoted_string (stream, name);
7951 fprintf (stream, "\n");
7952 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
7953 fprintf (stream, "\t#@stabs\n");
7956 else if (write_symbols == DBX_DEBUG)
7957 /* dbxout.c will emit an appropriate .stabs directive. */
7960 else if (name != current_function_file
7961 && strcmp (name, current_function_file) != 0)
7963 if (inside_function && ! TARGET_GAS)
7964 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
7967 ++num_source_filenames;
7968 current_function_file = name;
7969 fprintf (stream, "\t.file\t%d ", num_source_filenames);
7972 output_quoted_string (stream, name);
7973 fprintf (stream, "\n");
7977 /* Structure to show the current status of registers and memory. */
7979 struct shadow_summary
7982 unsigned int i : 31; /* Mask of int regs */
7983 unsigned int fp : 31; /* Mask of fp regs */
7984 unsigned int mem : 1; /* mem == imem | fpmem */
7988 /* Summary the effects of expression X on the machine. Update SUM, a pointer
7989 to the summary structure. SET is nonzero if the insn is setting the
7990 object, otherwise zero. */
7993 summarize_insn (rtx x, struct shadow_summary *sum, int set)
7995 const char *format_ptr;
8001 switch (GET_CODE (x))
8003 /* ??? Note that this case would be incorrect if the Alpha had a
8004 ZERO_EXTRACT in SET_DEST. */
8006 summarize_insn (SET_SRC (x), sum, 0);
8007 summarize_insn (SET_DEST (x), sum, 1);
8011 summarize_insn (XEXP (x, 0), sum, 1);
8015 summarize_insn (XEXP (x, 0), sum, 0);
8019 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
8020 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
8024 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
8025 summarize_insn (XVECEXP (x, 0, i), sum, 0);
8029 summarize_insn (SUBREG_REG (x), sum, 0);
8034 int regno = REGNO (x);
8035 unsigned long mask = ((unsigned long) 1) << (regno % 32);
8037 if (regno == 31 || regno == 63)
8043 sum->defd.i |= mask;
8045 sum->defd.fp |= mask;
8050 sum->used.i |= mask;
8052 sum->used.fp |= mask;
8063 /* Find the regs used in memory address computation: */
8064 summarize_insn (XEXP (x, 0), sum, 0);
8067 case CONST_INT: case CONST_DOUBLE:
8068 case SYMBOL_REF: case LABEL_REF: case CONST:
8069 case SCRATCH: case ASM_INPUT:
8072 /* Handle common unary and binary ops for efficiency. */
8073 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
8074 case MOD: case UDIV: case UMOD: case AND: case IOR:
8075 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
8076 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
8077 case NE: case EQ: case GE: case GT: case LE:
8078 case LT: case GEU: case GTU: case LEU: case LTU:
8079 summarize_insn (XEXP (x, 0), sum, 0);
8080 summarize_insn (XEXP (x, 1), sum, 0);
8083 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
8084 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
8085 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
8086 case SQRT: case FFS:
8087 summarize_insn (XEXP (x, 0), sum, 0);
8091 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
8092 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
8093 switch (format_ptr[i])
8096 summarize_insn (XEXP (x, i), sum, 0);
8100 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
8101 summarize_insn (XVECEXP (x, i, j), sum, 0);
8113 /* Ensure a sufficient number of `trapb' insns are in the code when
8114 the user requests code with a trap precision of functions or
8117 In naive mode, when the user requests a trap-precision of
8118 "instruction", a trapb is needed after every instruction that may
8119 generate a trap. This ensures that the code is resumption safe but
8122 When optimizations are turned on, we delay issuing a trapb as long
8123 as possible. In this context, a trap shadow is the sequence of
8124 instructions that starts with a (potentially) trap generating
8125 instruction and extends to the next trapb or call_pal instruction
8126 (but GCC never generates call_pal by itself). We can delay (and
8127 therefore sometimes omit) a trapb subject to the following
8130 (a) On entry to the trap shadow, if any Alpha register or memory
8131 location contains a value that is used as an operand value by some
8132 instruction in the trap shadow (live on entry), then no instruction
8133 in the trap shadow may modify the register or memory location.
8135 (b) Within the trap shadow, the computation of the base register
8136 for a memory load or store instruction may not involve using the
8137 result of an instruction that might generate an UNPREDICTABLE
8140 (c) Within the trap shadow, no register may be used more than once
8141 as a destination register. (This is to make life easier for the
8144 (d) The trap shadow may not include any branch instructions. */
8147 alpha_handle_trap_shadows (void)
8149 struct shadow_summary shadow;
8150 int trap_pending, exception_nesting;
8154 exception_nesting = 0;
8157 shadow.used.mem = 0;
8158 shadow.defd = shadow.used;
8160 for (i = get_insns (); i ; i = NEXT_INSN (i))
8162 if (GET_CODE (i) == NOTE)
8164 switch (NOTE_LINE_NUMBER (i))
8166 case NOTE_INSN_EH_REGION_BEG:
8167 exception_nesting++;
8172 case NOTE_INSN_EH_REGION_END:
8173 exception_nesting--;
8178 case NOTE_INSN_EPILOGUE_BEG:
8179 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
8184 else if (trap_pending)
8186 if (alpha_tp == ALPHA_TP_FUNC)
8188 if (GET_CODE (i) == JUMP_INSN
8189 && GET_CODE (PATTERN (i)) == RETURN)
8192 else if (alpha_tp == ALPHA_TP_INSN)
8196 struct shadow_summary sum;
8201 sum.defd = sum.used;
8203 switch (GET_CODE (i))
8206 /* Annoyingly, get_attr_trap will abort on these. */
8207 if (GET_CODE (PATTERN (i)) == USE
8208 || GET_CODE (PATTERN (i)) == CLOBBER)
8211 summarize_insn (PATTERN (i), &sum, 0);
8213 if ((sum.defd.i & shadow.defd.i)
8214 || (sum.defd.fp & shadow.defd.fp))
8216 /* (c) would be violated */
8220 /* Combine shadow with summary of current insn: */
8221 shadow.used.i |= sum.used.i;
8222 shadow.used.fp |= sum.used.fp;
8223 shadow.used.mem |= sum.used.mem;
8224 shadow.defd.i |= sum.defd.i;
8225 shadow.defd.fp |= sum.defd.fp;
8226 shadow.defd.mem |= sum.defd.mem;
8228 if ((sum.defd.i & shadow.used.i)
8229 || (sum.defd.fp & shadow.used.fp)
8230 || (sum.defd.mem & shadow.used.mem))
8232 /* (a) would be violated (also takes care of (b)) */
8233 if (get_attr_trap (i) == TRAP_YES
8234 && ((sum.defd.i & sum.used.i)
8235 || (sum.defd.fp & sum.used.fp)))
8254 n = emit_insn_before (gen_trapb (), i);
8255 PUT_MODE (n, TImode);
8256 PUT_MODE (i, TImode);
8260 shadow.used.mem = 0;
8261 shadow.defd = shadow.used;
8266 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
8267 && GET_CODE (i) == INSN
8268 && GET_CODE (PATTERN (i)) != USE
8269 && GET_CODE (PATTERN (i)) != CLOBBER
8270 && get_attr_trap (i) == TRAP_YES)
8272 if (optimize && !trap_pending)
8273 summarize_insn (PATTERN (i), &shadow, 0);
8279 /* Alpha can only issue instruction groups simultaneously if they are
8280 suitably aligned. This is very processor-specific. */
8282 enum alphaev4_pipe {
8289 enum alphaev5_pipe {
8300 static enum alphaev4_pipe
8301 alphaev4_insn_pipe (rtx insn)
8303 if (recog_memoized (insn) < 0)
8305 if (get_attr_length (insn) != 4)
8308 switch (get_attr_type (insn))
8342 static enum alphaev5_pipe
8343 alphaev5_insn_pipe (rtx insn)
8345 if (recog_memoized (insn) < 0)
8347 if (get_attr_length (insn) != 4)
8350 switch (get_attr_type (insn))
8391 /* IN_USE is a mask of the slots currently filled within the insn group.
8392 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
8393 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
8395 LEN is, of course, the length of the group in bytes. */
8398 alphaev4_next_group (rtx insn, int *pin_use, int *plen)
8405 || GET_CODE (PATTERN (insn)) == CLOBBER
8406 || GET_CODE (PATTERN (insn)) == USE)
8411 enum alphaev4_pipe pipe;
8413 pipe = alphaev4_insn_pipe (insn);
8417 /* Force complex instructions to start new groups. */
8421 /* If this is a completely unrecognized insn, its an asm.
8422 We don't know how long it is, so record length as -1 to
8423 signal a needed realignment. */
8424 if (recog_memoized (insn) < 0)
8427 len = get_attr_length (insn);
8431 if (in_use & EV4_IB0)
8433 if (in_use & EV4_IB1)
8438 in_use |= EV4_IB0 | EV4_IBX;
8442 if (in_use & EV4_IB0)
8444 if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
8452 if (in_use & EV4_IB1)
8462 /* Haifa doesn't do well scheduling branches. */
8463 if (GET_CODE (insn) == JUMP_INSN)
8467 insn = next_nonnote_insn (insn);
8469 if (!insn || ! INSN_P (insn))
8472 /* Let Haifa tell us where it thinks insn group boundaries are. */
8473 if (GET_MODE (insn) == TImode)
8476 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
8481 insn = next_nonnote_insn (insn);
8489 /* IN_USE is a mask of the slots currently filled within the insn group.
8490 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
8491 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
8493 LEN is, of course, the length of the group in bytes. */
8496 alphaev5_next_group (rtx insn, int *pin_use, int *plen)
8503 || GET_CODE (PATTERN (insn)) == CLOBBER
8504 || GET_CODE (PATTERN (insn)) == USE)
8509 enum alphaev5_pipe pipe;
8511 pipe = alphaev5_insn_pipe (insn);
8515 /* Force complex instructions to start new groups. */
8519 /* If this is a completely unrecognized insn, its an asm.
8520 We don't know how long it is, so record length as -1 to
8521 signal a needed realignment. */
8522 if (recog_memoized (insn) < 0)
8525 len = get_attr_length (insn);
8528 /* ??? Most of the places below, we would like to abort, as
8529 it would indicate an error either in Haifa, or in the
8530 scheduling description. Unfortunately, Haifa never
8531 schedules the last instruction of the BB, so we don't
8532 have an accurate TI bit to go off. */
8534 if (in_use & EV5_E0)
8536 if (in_use & EV5_E1)
8541 in_use |= EV5_E0 | EV5_E01;
8545 if (in_use & EV5_E0)
8547 if (!(in_use & EV5_E01) || (in_use & EV5_E1))
8555 if (in_use & EV5_E1)
8561 if (in_use & EV5_FA)
8563 if (in_use & EV5_FM)
8568 in_use |= EV5_FA | EV5_FAM;
8572 if (in_use & EV5_FA)
8578 if (in_use & EV5_FM)
8591 /* Haifa doesn't do well scheduling branches. */
8592 /* ??? If this is predicted not-taken, slotting continues, except
8593 that no more IBR, FBR, or JSR insns may be slotted. */
8594 if (GET_CODE (insn) == JUMP_INSN)
8598 insn = next_nonnote_insn (insn);
8600 if (!insn || ! INSN_P (insn))
8603 /* Let Haifa tell us where it thinks insn group boundaries are. */
8604 if (GET_MODE (insn) == TImode)
8607 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
8612 insn = next_nonnote_insn (insn);
8621 alphaev4_next_nop (int *pin_use)
8623 int in_use = *pin_use;
8626 if (!(in_use & EV4_IB0))
8631 else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
8636 else if (TARGET_FP && !(in_use & EV4_IB1))
8649 alphaev5_next_nop (int *pin_use)
8651 int in_use = *pin_use;
8654 if (!(in_use & EV5_E1))
8659 else if (TARGET_FP && !(in_use & EV5_FA))
8664 else if (TARGET_FP && !(in_use & EV5_FM))
8676 /* The instruction group alignment main loop. */
8679 alpha_align_insns (unsigned int max_align,
8680 rtx (*next_group) (rtx, int *, int *),
8681 rtx (*next_nop) (int *))
8683 /* ALIGN is the known alignment for the insn group. */
8685 /* OFS is the offset of the current insn in the insn group. */
8687 int prev_in_use, in_use, len;
8690 /* Let shorten branches care for assigning alignments to code labels. */
8691 shorten_branches (get_insns ());
8693 if (align_functions < 4)
8695 else if ((unsigned int) align_functions < max_align)
8696 align = align_functions;
8700 ofs = prev_in_use = 0;
8702 if (GET_CODE (i) == NOTE)
8703 i = next_nonnote_insn (i);
8707 next = (*next_group) (i, &in_use, &len);
8709 /* When we see a label, resync alignment etc. */
8710 if (GET_CODE (i) == CODE_LABEL)
8712 unsigned int new_align = 1 << label_to_alignment (i);
8714 if (new_align >= align)
8716 align = new_align < max_align ? new_align : max_align;
8720 else if (ofs & (new_align-1))
8721 ofs = (ofs | (new_align-1)) + 1;
8726 /* Handle complex instructions special. */
8727 else if (in_use == 0)
8729 /* Asms will have length < 0. This is a signal that we have
8730 lost alignment knowledge. Assume, however, that the asm
8731 will not mis-align instructions. */
8740 /* If the known alignment is smaller than the recognized insn group,
8741 realign the output. */
8742 else if ((int) align < len)
8744 unsigned int new_log_align = len > 8 ? 4 : 3;
8747 where = prev = prev_nonnote_insn (i);
8748 if (!where || GET_CODE (where) != CODE_LABEL)
8751 /* Can't realign between a call and its gp reload. */
8752 if (! (TARGET_EXPLICIT_RELOCS
8753 && prev && GET_CODE (prev) == CALL_INSN))
8755 emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
8756 align = 1 << new_log_align;
8761 /* If the group won't fit in the same INT16 as the previous,
8762 we need to add padding to keep the group together. Rather
8763 than simply leaving the insn filling to the assembler, we
8764 can make use of the knowledge of what sorts of instructions
8765 were issued in the previous group to make sure that all of
8766 the added nops are really free. */
8767 else if (ofs + len > (int) align)
8769 int nop_count = (align - ofs) / 4;
8772 /* Insert nops before labels, branches, and calls to truly merge
8773 the execution of the nops with the previous instruction group. */
8774 where = prev_nonnote_insn (i);
8777 if (GET_CODE (where) == CODE_LABEL)
8779 rtx where2 = prev_nonnote_insn (where);
8780 if (where2 && GET_CODE (where2) == JUMP_INSN)
8783 else if (GET_CODE (where) == INSN)
8790 emit_insn_before ((*next_nop)(&prev_in_use), where);
8791 while (--nop_count);
8795 ofs = (ofs + len) & (align - 1);
8796 prev_in_use = in_use;
8801 /* Machine dependent reorg pass. */
8806 if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
8807 alpha_handle_trap_shadows ();
8809 /* Due to the number of extra trapb insns, don't bother fixing up
8810 alignment when trap precision is instruction. Moreover, we can
8811 only do our job when sched2 is run. */
8812 if (optimize && !optimize_size
8813 && alpha_tp != ALPHA_TP_INSN
8814 && flag_schedule_insns_after_reload)
8816 if (alpha_tune == PROCESSOR_EV4)
8817 alpha_align_insns (8, alphaev4_next_group, alphaev4_next_nop);
8818 else if (alpha_tune == PROCESSOR_EV5)
8819 alpha_align_insns (16, alphaev5_next_group, alphaev5_next_nop);
8823 #if !TARGET_ABI_UNICOSMK
8830 alpha_file_start (void)
8832 #ifdef OBJECT_FORMAT_ELF
8833 /* If emitting dwarf2 debug information, we cannot generate a .file
8834 directive to start the file, as it will conflict with dwarf2out
8835 file numbers. So it's only useful when emitting mdebug output. */
8836 targetm.file_start_file_directive = (write_symbols == DBX_DEBUG);
8839 default_file_start ();
8841 fprintf (asm_out_file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
8844 fputs ("\t.set noreorder\n", asm_out_file);
8845 fputs ("\t.set volatile\n", asm_out_file);
8846 if (!TARGET_ABI_OPEN_VMS)
8847 fputs ("\t.set noat\n", asm_out_file);
8848 if (TARGET_EXPLICIT_RELOCS)
8849 fputs ("\t.set nomacro\n", asm_out_file);
8850 if (TARGET_SUPPORT_ARCH | TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX)
8854 if (alpha_cpu == PROCESSOR_EV6 || TARGET_FIX || TARGET_CIX)
8856 else if (TARGET_MAX)
8858 else if (TARGET_BWX)
8860 else if (alpha_cpu == PROCESSOR_EV5)
8865 fprintf (asm_out_file, "\t.arch %s\n", arch);
8870 #ifdef OBJECT_FORMAT_ELF
8872 /* Switch to the section to which we should output X. The only thing
8873 special we do here is to honor small data. */
8876 alpha_elf_select_rtx_section (enum machine_mode mode, rtx x,
8877 unsigned HOST_WIDE_INT align)
8879 if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value)
8880 /* ??? Consider using mergeable sdata sections. */
8883 default_elf_select_rtx_section (mode, x, align);
8886 #endif /* OBJECT_FORMAT_ELF */
8888 /* Structure to collect function names for final output in link section. */
8889 /* Note that items marked with GTY can't be ifdef'ed out. */
8891 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
8892 enum reloc_kind {KIND_LINKAGE, KIND_CODEADDR};
8894 struct alpha_links GTY(())
8898 enum links_kind lkind;
8899 enum reloc_kind rkind;
8902 struct alpha_funcs GTY(())
8905 splay_tree GTY ((param1_is (char *), param2_is (struct alpha_links *)))
8909 static GTY ((param1_is (char *), param2_is (struct alpha_links *)))
8910 splay_tree alpha_links_tree;
8911 static GTY ((param1_is (tree), param2_is (struct alpha_funcs *)))
8912 splay_tree alpha_funcs_tree;
8914 static GTY(()) int alpha_funcs_num;
8916 #if TARGET_ABI_OPEN_VMS
8918 /* Return the VMS argument type corresponding to MODE. */
8921 alpha_arg_type (enum machine_mode mode)
8926 return TARGET_FLOAT_VAX ? FF : FS;
8928 return TARGET_FLOAT_VAX ? FD : FT;
8934 /* Return an rtx for an integer representing the VMS Argument Information
8938 alpha_arg_info_reg_val (CUMULATIVE_ARGS cum)
8940 unsigned HOST_WIDE_INT regval = cum.num_args;
8943 for (i = 0; i < 6; i++)
8944 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
8946 return GEN_INT (regval);
8949 /* Make (or fake) .linkage entry for function call.
8951 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.
8953 Return an SYMBOL_REF rtx for the linkage. */
8956 alpha_need_linkage (const char *name, int is_local)
8958 splay_tree_node node;
8959 struct alpha_links *al;
8966 struct alpha_funcs *cfaf;
8968 if (!alpha_funcs_tree)
8969 alpha_funcs_tree = splay_tree_new_ggc ((splay_tree_compare_fn)
8970 splay_tree_compare_pointers);
8972 cfaf = (struct alpha_funcs *) ggc_alloc (sizeof (struct alpha_funcs));
8975 cfaf->num = ++alpha_funcs_num;
8977 splay_tree_insert (alpha_funcs_tree,
8978 (splay_tree_key) current_function_decl,
8979 (splay_tree_value) cfaf);
8982 if (alpha_links_tree)
8984 /* Is this name already defined? */
8986 node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
8989 al = (struct alpha_links *) node->value;
8992 /* Defined here but external assumed. */
8993 if (al->lkind == KIND_EXTERN)
8994 al->lkind = KIND_LOCAL;
8998 /* Used here but unused assumed. */
8999 if (al->lkind == KIND_UNUSED)
9000 al->lkind = KIND_LOCAL;
9006 alpha_links_tree = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
9008 al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
9009 name = ggc_strdup (name);
9011 /* Assume external if no definition. */
9012 al->lkind = (is_local ? KIND_UNUSED : KIND_EXTERN);
9014 /* Ensure we have an IDENTIFIER so assemble_name can mark it used. */
9015 get_identifier (name);
9017 /* Construct a SYMBOL_REF for us to call. */
9019 size_t name_len = strlen (name);
9020 char *linksym = alloca (name_len + 6);
9022 memcpy (linksym + 1, name, name_len);
9023 memcpy (linksym + 1 + name_len, "..lk", 5);
9024 al->linkage = gen_rtx_SYMBOL_REF (Pmode,
9025 ggc_alloc_string (linksym, name_len + 5));
9028 splay_tree_insert (alpha_links_tree, (splay_tree_key) name,
9029 (splay_tree_value) al);
9035 alpha_use_linkage (rtx linkage, tree cfundecl, int lflag, int rflag)
9037 splay_tree_node cfunnode;
9038 struct alpha_funcs *cfaf;
9039 struct alpha_links *al;
9040 const char *name = XSTR (linkage, 0);
9042 cfaf = (struct alpha_funcs *) 0;
9043 al = (struct alpha_links *) 0;
9045 cfunnode = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) cfundecl);
9046 cfaf = (struct alpha_funcs *) cfunnode->value;
9050 splay_tree_node lnode;
9052 /* Is this name already defined? */
9054 lnode = splay_tree_lookup (cfaf->links, (splay_tree_key) name);
9056 al = (struct alpha_links *) lnode->value;
9059 cfaf->links = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
9067 splay_tree_node node = 0;
9068 struct alpha_links *anl;
9073 name_len = strlen (name);
9075 al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
9076 al->num = cfaf->num;
9078 node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
9081 anl = (struct alpha_links *) node->value;
9082 al->lkind = anl->lkind;
9085 sprintf (buf, "$%d..%s..lk", cfaf->num, name);
9086 buflen = strlen (buf);
9087 linksym = alloca (buflen + 1);
9088 memcpy (linksym, buf, buflen + 1);
9090 al->linkage = gen_rtx_SYMBOL_REF
9091 (Pmode, ggc_alloc_string (linksym, buflen + 1));
9093 splay_tree_insert (cfaf->links, (splay_tree_key) name,
9094 (splay_tree_value) al);
9098 al->rkind = KIND_CODEADDR;
9100 al->rkind = KIND_LINKAGE;
9103 return gen_rtx_MEM (Pmode, plus_constant (al->linkage, 8));
9109 alpha_write_one_linkage (splay_tree_node node, void *data)
9111 const char *const name = (const char *) node->key;
9112 struct alpha_links *link = (struct alpha_links *) node->value;
9113 FILE *stream = (FILE *) data;
9115 fprintf (stream, "$%d..%s..lk:\n", link->num, name);
9116 if (link->rkind == KIND_CODEADDR)
9118 if (link->lkind == KIND_LOCAL)
9120 /* Local and used */
9121 fprintf (stream, "\t.quad %s..en\n", name);
9125 /* External and used, request code address. */
9126 fprintf (stream, "\t.code_address %s\n", name);
9131 if (link->lkind == KIND_LOCAL)
9133 /* Local and used, build linkage pair. */
9134 fprintf (stream, "\t.quad %s..en\n", name);
9135 fprintf (stream, "\t.quad %s\n", name);
9139 /* External and used, request linkage pair. */
9140 fprintf (stream, "\t.linkage %s\n", name);
9148 alpha_write_linkage (FILE *stream, const char *funname, tree fundecl)
9150 splay_tree_node node;
9151 struct alpha_funcs *func;
9154 fprintf (stream, "\t.align 3\n");
9155 node = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) fundecl);
9156 func = (struct alpha_funcs *) node->value;
9158 fputs ("\t.name ", stream);
9159 assemble_name (stream, funname);
9160 fputs ("..na\n", stream);
9161 ASM_OUTPUT_LABEL (stream, funname);
9162 fprintf (stream, "\t.pdesc ");
9163 assemble_name (stream, funname);
9164 fprintf (stream, "..en,%s\n",
9165 alpha_procedure_type == PT_STACK ? "stack"
9166 : alpha_procedure_type == PT_REGISTER ? "reg" : "null");
9170 splay_tree_foreach (func->links, alpha_write_one_linkage, stream);
9171 /* splay_tree_delete (func->links); */
9175 /* Given a decl, a section name, and whether the decl initializer
9176 has relocs, choose attributes for the section. */
9178 #define SECTION_VMS_OVERLAY SECTION_FORGET
9179 #define SECTION_VMS_GLOBAL SECTION_MACH_DEP
9180 #define SECTION_VMS_INITIALIZE (SECTION_VMS_GLOBAL << 1)
9183 vms_section_type_flags (tree decl, const char *name, int reloc)
9185 unsigned int flags = default_section_type_flags (decl, name, reloc);
9187 if (decl && DECL_ATTRIBUTES (decl)
9188 && lookup_attribute ("overlaid", DECL_ATTRIBUTES (decl)))
9189 flags |= SECTION_VMS_OVERLAY;
9190 if (decl && DECL_ATTRIBUTES (decl)
9191 && lookup_attribute ("global", DECL_ATTRIBUTES (decl)))
9192 flags |= SECTION_VMS_GLOBAL;
9193 if (decl && DECL_ATTRIBUTES (decl)
9194 && lookup_attribute ("initialize", DECL_ATTRIBUTES (decl)))
9195 flags |= SECTION_VMS_INITIALIZE;
9200 /* Switch to an arbitrary section NAME with attributes as specified
9201 by FLAGS. ALIGN specifies any known alignment requirements for
9202 the section; 0 if the default should be used. */
9205 vms_asm_named_section (const char *name, unsigned int flags,
9206 tree decl ATTRIBUTE_UNUSED)
9208 fputc ('\n', asm_out_file);
9209 fprintf (asm_out_file, ".section\t%s", name);
9211 if (flags & SECTION_VMS_OVERLAY)
9212 fprintf (asm_out_file, ",OVR");
9213 if (flags & SECTION_VMS_GLOBAL)
9214 fprintf (asm_out_file, ",GBL");
9215 if (flags & SECTION_VMS_INITIALIZE)
9216 fprintf (asm_out_file, ",NOMOD");
9217 if (flags & SECTION_DEBUG)
9218 fprintf (asm_out_file, ",NOWRT");
9220 fputc ('\n', asm_out_file);
9223 /* Record an element in the table of global constructors. SYMBOL is
9224 a SYMBOL_REF of the function to be called; PRIORITY is a number
9225 between 0 and MAX_INIT_PRIORITY.
9227 Differs from default_ctors_section_asm_out_constructor in that the
9228 width of the .ctors entry is always 64 bits, rather than the 32 bits
9229 used by a normal pointer. */
9232 vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
9235 assemble_align (BITS_PER_WORD);
9236 assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
9240 vms_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
9243 assemble_align (BITS_PER_WORD);
9244 assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
9249 alpha_need_linkage (const char *name ATTRIBUTE_UNUSED,
9250 int is_local ATTRIBUTE_UNUSED)
9256 alpha_use_linkage (rtx linkage ATTRIBUTE_UNUSED,
9257 tree cfundecl ATTRIBUTE_UNUSED,
9258 int lflag ATTRIBUTE_UNUSED,
9259 int rflag ATTRIBUTE_UNUSED)
9264 #endif /* TARGET_ABI_OPEN_VMS */
9266 #if TARGET_ABI_UNICOSMK
9268 /* This evaluates to true if we do not know how to pass TYPE solely in
9269 registers. This is the case for all arguments that do not fit in two
9273 unicosmk_must_pass_in_stack (enum machine_mode mode, tree type)
9278 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
9280 if (TREE_ADDRESSABLE (type))
9283 return ALPHA_ARG_SIZE (mode, type, 0) > 2;
9286 /* Define the offset between two registers, one to be eliminated, and the
9287 other its replacement, at the start of a routine. */
9290 unicosmk_initial_elimination_offset (int from, int to)
9294 fixed_size = alpha_sa_size();
9295 if (fixed_size != 0)
9298 if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
9300 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
9302 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
9303 return (ALPHA_ROUND (current_function_outgoing_args_size)
9304 + ALPHA_ROUND (get_frame_size()));
9305 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
9306 return (ALPHA_ROUND (fixed_size)
9307 + ALPHA_ROUND (get_frame_size()
9308 + current_function_outgoing_args_size));
9313 /* Output the module name for .ident and .end directives. We have to strip
9314 directories and add make sure that the module name starts with a letter
9318 unicosmk_output_module_name (FILE *file)
9320 const char *name = lbasename (main_input_filename);
9321 unsigned len = strlen (name);
9322 char *clean_name = alloca (len + 2);
9323 char *ptr = clean_name;
9325 /* CAM only accepts module names that start with a letter or '$'. We
9326 prefix the module name with a '$' if necessary. */
9328 if (!ISALPHA (*name))
9330 memcpy (ptr, name, len + 1);
9331 clean_symbol_name (clean_name);
9332 fputs (clean_name, file);
9335 /* Output the definition of a common variable. */
9338 unicosmk_output_common (FILE *file, const char *name, int size, int align)
9341 printf ("T3E__: common %s\n", name);
9344 fputs("\t.endp\n\n\t.psect ", file);
9345 assemble_name(file, name);
9346 fprintf(file, ",%d,common\n", floor_log2 (align / BITS_PER_UNIT));
9347 fprintf(file, "\t.byte\t0:%d\n", size);
9349 /* Mark the symbol as defined in this module. */
9350 name_tree = get_identifier (name);
9351 TREE_ASM_WRITTEN (name_tree) = 1;
9354 #define SECTION_PUBLIC SECTION_MACH_DEP
9355 #define SECTION_MAIN (SECTION_PUBLIC << 1)
9356 static int current_section_align;
9359 unicosmk_section_type_flags (tree decl, const char *name,
9360 int reloc ATTRIBUTE_UNUSED)
9362 unsigned int flags = default_section_type_flags (decl, name, reloc);
9367 if (TREE_CODE (decl) == FUNCTION_DECL)
9369 current_section_align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
9370 if (align_functions_log > current_section_align)
9371 current_section_align = align_functions_log;
9373 if (! strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), "main"))
9374 flags |= SECTION_MAIN;
9377 current_section_align = floor_log2 (DECL_ALIGN (decl) / BITS_PER_UNIT);
9379 if (TREE_PUBLIC (decl))
9380 flags |= SECTION_PUBLIC;
9385 /* Generate a section name for decl and associate it with the
9389 unicosmk_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
9397 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
9398 name = default_strip_name_encoding (name);
9399 len = strlen (name);
9401 if (TREE_CODE (decl) == FUNCTION_DECL)
9405 /* It is essential that we prefix the section name here because
9406 otherwise the section names generated for constructors and
9407 destructors confuse collect2. */
9409 string = alloca (len + 6);
9410 sprintf (string, "code@%s", name);
9411 DECL_SECTION_NAME (decl) = build_string (len + 5, string);
9413 else if (TREE_PUBLIC (decl))
9414 DECL_SECTION_NAME (decl) = build_string (len, name);
9419 string = alloca (len + 6);
9420 sprintf (string, "data@%s", name);
9421 DECL_SECTION_NAME (decl) = build_string (len + 5, string);
9425 /* Switch to an arbitrary section NAME with attributes as specified
9426 by FLAGS. ALIGN specifies any known alignment requirements for
9427 the section; 0 if the default should be used. */
9430 unicosmk_asm_named_section (const char *name, unsigned int flags,
9431 tree decl ATTRIBUTE_UNUSED)
9435 /* Close the previous section. */
9437 fputs ("\t.endp\n\n", asm_out_file);
9439 /* Find out what kind of section we are opening. */
9441 if (flags & SECTION_MAIN)
9442 fputs ("\t.start\tmain\n", asm_out_file);
9444 if (flags & SECTION_CODE)
9446 else if (flags & SECTION_PUBLIC)
9451 if (current_section_align != 0)
9452 fprintf (asm_out_file, "\t.psect\t%s,%d,%s\n", name,
9453 current_section_align, kind);
9455 fprintf (asm_out_file, "\t.psect\t%s,%s\n", name, kind);
9459 unicosmk_insert_attributes (tree decl, tree *attr_ptr ATTRIBUTE_UNUSED)
9462 && (TREE_PUBLIC (decl) || TREE_CODE (decl) == FUNCTION_DECL))
9463 unicosmk_unique_section (decl, 0);
9466 /* Output an alignment directive. We have to use the macro 'gcc@code@align'
9467 in code sections because .align fill unused space with zeroes. */
9470 unicosmk_output_align (FILE *file, int align)
9472 if (inside_function)
9473 fprintf (file, "\tgcc@code@align\t%d\n", align);
9475 fprintf (file, "\t.align\t%d\n", align);
9478 /* Add a case vector to the current function's list of deferred case
9479 vectors. Case vectors have to be put into a separate section because CAM
9480 does not allow data definitions in code sections. */
9483 unicosmk_defer_case_vector (rtx lab, rtx vec)
9485 struct machine_function *machine = cfun->machine;
9487 vec = gen_rtx_EXPR_LIST (VOIDmode, lab, vec);
9488 machine->addr_list = gen_rtx_EXPR_LIST (VOIDmode, vec,
9489 machine->addr_list);
9492 /* Output a case vector. */
9495 unicosmk_output_addr_vec (FILE *file, rtx vec)
9497 rtx lab = XEXP (vec, 0);
9498 rtx body = XEXP (vec, 1);
9499 int vlen = XVECLEN (body, 0);
9502 (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (lab));
9504 for (idx = 0; idx < vlen; idx++)
9506 ASM_OUTPUT_ADDR_VEC_ELT
9507 (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
9511 /* Output current function's deferred case vectors. */
9514 unicosmk_output_deferred_case_vectors (FILE *file)
9516 struct machine_function *machine = cfun->machine;
9519 if (machine->addr_list == NULL_RTX)
9523 for (t = machine->addr_list; t; t = XEXP (t, 1))
9524 unicosmk_output_addr_vec (file, XEXP (t, 0));
9527 /* Generate the name of the SSIB section for the current function. */
9529 #define SSIB_PREFIX "__SSIB_"
9530 #define SSIB_PREFIX_LEN 7
9533 unicosmk_ssib_name (void)
9535 /* This is ok since CAM won't be able to deal with names longer than that
9538 static char name[256];
9544 x = DECL_RTL (cfun->decl);
9545 if (GET_CODE (x) != MEM)
9548 if (GET_CODE (x) != SYMBOL_REF)
9550 fnname = XSTR (x, 0);
9552 len = strlen (fnname);
9553 if (len + SSIB_PREFIX_LEN > 255)
9554 len = 255 - SSIB_PREFIX_LEN;
9556 strcpy (name, SSIB_PREFIX);
9557 strncpy (name + SSIB_PREFIX_LEN, fnname, len);
9558 name[len + SSIB_PREFIX_LEN] = 0;
9563 /* Set up the dynamic subprogram information block (DSIB) and update the
9564 frame pointer register ($15) for subroutines which have a frame. If the
9565 subroutine doesn't have a frame, simply increment $15. */
9568 unicosmk_gen_dsib (unsigned long *imaskP)
9570 if (alpha_procedure_type == PT_STACK)
9572 const char *ssib_name;
9575 /* Allocate 64 bytes for the DSIB. */
9577 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
9579 emit_insn (gen_blockage ());
9581 /* Save the return address. */
9583 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 56));
9584 set_mem_alias_set (mem, alpha_sr_alias_set);
9585 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
9586 (*imaskP) &= ~(1UL << REG_RA);
9588 /* Save the old frame pointer. */
9590 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 48));
9591 set_mem_alias_set (mem, alpha_sr_alias_set);
9592 FRP (emit_move_insn (mem, hard_frame_pointer_rtx));
9593 (*imaskP) &= ~(1UL << HARD_FRAME_POINTER_REGNUM);
9595 emit_insn (gen_blockage ());
9597 /* Store the SSIB pointer. */
9599 ssib_name = ggc_strdup (unicosmk_ssib_name ());
9600 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 32));
9601 set_mem_alias_set (mem, alpha_sr_alias_set);
9603 FRP (emit_move_insn (gen_rtx_REG (DImode, 5),
9604 gen_rtx_SYMBOL_REF (Pmode, ssib_name)));
9605 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 5)));
9607 /* Save the CIW index. */
9609 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 24));
9610 set_mem_alias_set (mem, alpha_sr_alias_set);
9611 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 25)));
9613 emit_insn (gen_blockage ());
9615 /* Set the new frame pointer. */
9617 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
9618 stack_pointer_rtx, GEN_INT (64))));
9623 /* Increment the frame pointer register to indicate that we do not
9626 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
9627 hard_frame_pointer_rtx, const1_rtx)));
9631 /* Output the static subroutine information block for the current
9635 unicosmk_output_ssib (FILE *file, const char *fnname)
9641 struct machine_function *machine = cfun->machine;
9644 fprintf (file, "\t.endp\n\n\t.psect\t%s%s,data\n", user_label_prefix,
9645 unicosmk_ssib_name ());
9647 /* Some required stuff and the function name length. */
9649 len = strlen (fnname);
9650 fprintf (file, "\t.quad\t^X20008%2.2X28\n", len);
9653 ??? We don't do that yet. */
9655 fputs ("\t.quad\t0\n", file);
9657 /* Function address. */
9659 fputs ("\t.quad\t", file);
9660 assemble_name (file, fnname);
9663 fputs ("\t.quad\t0\n", file);
9664 fputs ("\t.quad\t0\n", file);
9667 ??? We do it the same way Cray CC does it but this could be
9670 for( i = 0; i < len; i++ )
9671 fprintf (file, "\t.byte\t%d\n", (int)(fnname[i]));
9672 if( (len % 8) == 0 )
9673 fputs ("\t.quad\t0\n", file);
9675 fprintf (file, "\t.bits\t%d : 0\n", (8 - (len % 8))*8);
9677 /* All call information words used in the function. */
9679 for (x = machine->first_ciw; x; x = XEXP (x, 1))
9682 #if HOST_BITS_PER_WIDE_INT == 32
9683 fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_DOUBLE_HEX "\n",
9684 CONST_DOUBLE_HIGH (ciw), CONST_DOUBLE_LOW (ciw));
9686 fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n", INTVAL (ciw));
9691 /* Add a call information word (CIW) to the list of the current function's
9692 CIWs and return its index.
9694 X is a CONST_INT or CONST_DOUBLE representing the CIW. */
9697 unicosmk_add_call_info_word (rtx x)
9700 struct machine_function *machine = cfun->machine;
9702 node = gen_rtx_EXPR_LIST (VOIDmode, x, NULL_RTX);
9703 if (machine->first_ciw == NULL_RTX)
9704 machine->first_ciw = node;
9706 XEXP (machine->last_ciw, 1) = node;
9708 machine->last_ciw = node;
9709 ++machine->ciw_count;
9711 return GEN_INT (machine->ciw_count
9712 + strlen (current_function_name ())/8 + 5);
9715 static char unicosmk_section_buf[100];
9718 unicosmk_text_section (void)
9720 static int count = 0;
9721 sprintf (unicosmk_section_buf, "\t.endp\n\n\t.psect\tgcc@text___%d,code",
9723 return unicosmk_section_buf;
9727 unicosmk_data_section (void)
9729 static int count = 1;
9730 sprintf (unicosmk_section_buf, "\t.endp\n\n\t.psect\tgcc@data___%d,data",
9732 return unicosmk_section_buf;
9735 /* The Cray assembler doesn't accept extern declarations for symbols which
9736 are defined in the same file. We have to keep track of all global
9737 symbols which are referenced and/or defined in a source file and output
9738 extern declarations for those which are referenced but not defined at
9741 /* List of identifiers for which an extern declaration might have to be
9743 /* FIXME: needs to use GC, so it can be saved and restored for PCH. */
9745 struct unicosmk_extern_list
9747 struct unicosmk_extern_list *next;
9751 static struct unicosmk_extern_list *unicosmk_extern_head = 0;
9753 /* Output extern declarations which are required for every asm file. */
9756 unicosmk_output_default_externs (FILE *file)
9758 static const char *const externs[] =
9759 { "__T3E_MISMATCH" };
9764 n = ARRAY_SIZE (externs);
9766 for (i = 0; i < n; i++)
9767 fprintf (file, "\t.extern\t%s\n", externs[i]);
9770 /* Output extern declarations for global symbols which are have been
9771 referenced but not defined. */
9774 unicosmk_output_externs (FILE *file)
9776 struct unicosmk_extern_list *p;
9777 const char *real_name;
9781 len = strlen (user_label_prefix);
9782 for (p = unicosmk_extern_head; p != 0; p = p->next)
9784 /* We have to strip the encoding and possibly remove user_label_prefix
9785 from the identifier in order to handle -fleading-underscore and
9786 explicit asm names correctly (cf. gcc.dg/asm-names-1.c). */
9787 real_name = default_strip_name_encoding (p->name);
9788 if (len && p->name[0] == '*'
9789 && !memcmp (real_name, user_label_prefix, len))
9792 name_tree = get_identifier (real_name);
9793 if (! TREE_ASM_WRITTEN (name_tree))
9795 TREE_ASM_WRITTEN (name_tree) = 1;
9796 fputs ("\t.extern\t", file);
9797 assemble_name (file, p->name);
9803 /* Record an extern. */
9806 unicosmk_add_extern (const char *name)
9808 struct unicosmk_extern_list *p;
9810 p = (struct unicosmk_extern_list *)
9811 xmalloc (sizeof (struct unicosmk_extern_list));
9812 p->next = unicosmk_extern_head;
9814 unicosmk_extern_head = p;
9817 /* The Cray assembler generates incorrect code if identifiers which
9818 conflict with register names are used as instruction operands. We have
9819 to replace such identifiers with DEX expressions. */
9821 /* Structure to collect identifiers which have been replaced by DEX
9823 /* FIXME: needs to use GC, so it can be saved and restored for PCH. */
9825 struct unicosmk_dex {
9826 struct unicosmk_dex *next;
9830 /* List of identifiers which have been replaced by DEX expressions. The DEX
9831 number is determined by the position in the list. */
9833 static struct unicosmk_dex *unicosmk_dex_list = NULL;
9835 /* The number of elements in the DEX list. */
9837 static int unicosmk_dex_count = 0;
9839 /* Check if NAME must be replaced by a DEX expression. */
9842 unicosmk_special_name (const char *name)
9850 if (name[0] != 'r' && name[0] != 'f' && name[0] != 'R' && name[0] != 'F')
9856 return (name[2] == '\0' || (ISDIGIT (name[2]) && name[3] == '\0'));
9859 return (name[2] == '\0'
9860 || ((name[2] == '0' || name[2] == '1') && name[3] == '\0'));
9863 return (ISDIGIT (name[1]) && name[2] == '\0');
9867 /* Return the DEX number if X must be replaced by a DEX expression and 0
9871 unicosmk_need_dex (rtx x)
9873 struct unicosmk_dex *dex;
9877 if (GET_CODE (x) != SYMBOL_REF)
9881 if (! unicosmk_special_name (name))
9884 i = unicosmk_dex_count;
9885 for (dex = unicosmk_dex_list; dex; dex = dex->next)
9887 if (! strcmp (name, dex->name))
9892 dex = (struct unicosmk_dex *) xmalloc (sizeof (struct unicosmk_dex));
9894 dex->next = unicosmk_dex_list;
9895 unicosmk_dex_list = dex;
9897 ++unicosmk_dex_count;
9898 return unicosmk_dex_count;
9901 /* Output the DEX definitions for this file. */
9904 unicosmk_output_dex (FILE *file)
9906 struct unicosmk_dex *dex;
9909 if (unicosmk_dex_list == NULL)
9912 fprintf (file, "\t.dexstart\n");
9914 i = unicosmk_dex_count;
9915 for (dex = unicosmk_dex_list; dex; dex = dex->next)
9917 fprintf (file, "\tDEX (%d) = ", i);
9918 assemble_name (file, dex->name);
9923 fprintf (file, "\t.dexend\n");
9926 /* Output text that to appear at the beginning of an assembler file. */
9929 unicosmk_file_start (void)
9933 fputs ("\t.ident\t", asm_out_file);
9934 unicosmk_output_module_name (asm_out_file);
9935 fputs ("\n\n", asm_out_file);
9937 /* The Unicos/Mk assembler uses different register names. Instead of trying
9938 to support them, we simply use micro definitions. */
9940 /* CAM has different register names: rN for the integer register N and fN
9941 for the floating-point register N. Instead of trying to use these in
9942 alpha.md, we define the symbols $N and $fN to refer to the appropriate
9945 for (i = 0; i < 32; ++i)
9946 fprintf (asm_out_file, "$%d <- r%d\n", i, i);
9948 for (i = 0; i < 32; ++i)
9949 fprintf (asm_out_file, "$f%d <- f%d\n", i, i);
9951 putc ('\n', asm_out_file);
9953 /* The .align directive fill unused space with zeroes which does not work
9954 in code sections. We define the macro 'gcc@code@align' which uses nops
9955 instead. Note that it assumes that code sections always have the
9956 biggest possible alignment since . refers to the current offset from
9957 the beginning of the section. */
9959 fputs ("\t.macro gcc@code@align n\n", asm_out_file);
9960 fputs ("gcc@n@bytes = 1 << n\n", asm_out_file);
9961 fputs ("gcc@here = . % gcc@n@bytes\n", asm_out_file);
9962 fputs ("\t.if ne, gcc@here, 0\n", asm_out_file);
9963 fputs ("\t.repeat (gcc@n@bytes - gcc@here) / 4\n", asm_out_file);
9964 fputs ("\tbis r31,r31,r31\n", asm_out_file);
9965 fputs ("\t.endr\n", asm_out_file);
9966 fputs ("\t.endif\n", asm_out_file);
9967 fputs ("\t.endm gcc@code@align\n\n", asm_out_file);
9969 /* Output extern declarations which should always be visible. */
9970 unicosmk_output_default_externs (asm_out_file);
9972 /* Open a dummy section. We always need to be inside a section for the
9973 section-switching code to work correctly.
9974 ??? This should be a module id or something like that. I still have to
9975 figure out what the rules for those are. */
9976 fputs ("\n\t.psect\t$SG00000,data\n", asm_out_file);
9979 /* Output text to appear at the end of an assembler file. This includes all
9980 pending extern declarations and DEX expressions. */
9983 unicosmk_file_end (void)
9985 fputs ("\t.endp\n\n", asm_out_file);
9987 /* Output all pending externs. */
9989 unicosmk_output_externs (asm_out_file);
9991 /* Output dex definitions used for functions whose names conflict with
9994 unicosmk_output_dex (asm_out_file);
9996 fputs ("\t.end\t", asm_out_file);
9997 unicosmk_output_module_name (asm_out_file);
9998 putc ('\n', asm_out_file);
10004 unicosmk_output_deferred_case_vectors (FILE *file ATTRIBUTE_UNUSED)
10008 unicosmk_gen_dsib (unsigned long *imaskP ATTRIBUTE_UNUSED)
10012 unicosmk_output_ssib (FILE * file ATTRIBUTE_UNUSED,
10013 const char * fnname ATTRIBUTE_UNUSED)
10017 unicosmk_add_call_info_word (rtx x ATTRIBUTE_UNUSED)
10023 unicosmk_need_dex (rtx x ATTRIBUTE_UNUSED)
10028 #endif /* TARGET_ABI_UNICOSMK */
10031 alpha_init_libfuncs (void)
10033 if (TARGET_ABI_UNICOSMK)
10035 /* Prevent gcc from generating calls to __divsi3. */
10036 set_optab_libfunc (sdiv_optab, SImode, 0);
10037 set_optab_libfunc (udiv_optab, SImode, 0);
10039 /* Use the functions provided by the system library
10040 for DImode integer division. */
10041 set_optab_libfunc (sdiv_optab, DImode, "$sldiv");
10042 set_optab_libfunc (udiv_optab, DImode, "$uldiv");
10044 else if (TARGET_ABI_OPEN_VMS)
10046 /* Use the VMS runtime library functions for division and
10048 set_optab_libfunc (sdiv_optab, SImode, "OTS$DIV_I");
10049 set_optab_libfunc (sdiv_optab, DImode, "OTS$DIV_L");
10050 set_optab_libfunc (udiv_optab, SImode, "OTS$DIV_UI");
10051 set_optab_libfunc (udiv_optab, DImode, "OTS$DIV_UL");
10052 set_optab_libfunc (smod_optab, SImode, "OTS$REM_I");
10053 set_optab_libfunc (smod_optab, DImode, "OTS$REM_L");
10054 set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI");
10055 set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL");
10060 /* Initialize the GCC target structure. */
10061 #if TARGET_ABI_OPEN_VMS
10062 # undef TARGET_ATTRIBUTE_TABLE
10063 # define TARGET_ATTRIBUTE_TABLE vms_attribute_table
10064 # undef TARGET_SECTION_TYPE_FLAGS
10065 # define TARGET_SECTION_TYPE_FLAGS vms_section_type_flags
10068 #undef TARGET_IN_SMALL_DATA_P
10069 #define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p
10071 #if TARGET_ABI_UNICOSMK
10072 # undef TARGET_INSERT_ATTRIBUTES
10073 # define TARGET_INSERT_ATTRIBUTES unicosmk_insert_attributes
10074 # undef TARGET_SECTION_TYPE_FLAGS
10075 # define TARGET_SECTION_TYPE_FLAGS unicosmk_section_type_flags
10076 # undef TARGET_ASM_UNIQUE_SECTION
10077 # define TARGET_ASM_UNIQUE_SECTION unicosmk_unique_section
10078 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
10079 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
10080 # undef TARGET_ASM_GLOBALIZE_LABEL
10081 # define TARGET_ASM_GLOBALIZE_LABEL hook_void_FILEptr_constcharptr
10082 # undef TARGET_MUST_PASS_IN_STACK
10083 # define TARGET_MUST_PASS_IN_STACK unicosmk_must_pass_in_stack
10086 #undef TARGET_ASM_ALIGNED_HI_OP
10087 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
10088 #undef TARGET_ASM_ALIGNED_DI_OP
10089 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
10091 /* Default unaligned ops are provided for ELF systems. To get unaligned
10092 data for non-ELF systems, we have to turn off auto alignment. */
10093 #ifndef OBJECT_FORMAT_ELF
10094 #undef TARGET_ASM_UNALIGNED_HI_OP
10095 #define TARGET_ASM_UNALIGNED_HI_OP "\t.align 0\n\t.word\t"
10096 #undef TARGET_ASM_UNALIGNED_SI_OP
10097 #define TARGET_ASM_UNALIGNED_SI_OP "\t.align 0\n\t.long\t"
10098 #undef TARGET_ASM_UNALIGNED_DI_OP
10099 #define TARGET_ASM_UNALIGNED_DI_OP "\t.align 0\n\t.quad\t"
10102 #ifdef OBJECT_FORMAT_ELF
10103 #undef TARGET_ASM_SELECT_RTX_SECTION
10104 #define TARGET_ASM_SELECT_RTX_SECTION alpha_elf_select_rtx_section
10107 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
10108 #define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
10110 #undef TARGET_INIT_LIBFUNCS
10111 #define TARGET_INIT_LIBFUNCS alpha_init_libfuncs
10113 #if TARGET_ABI_UNICOSMK
10114 #undef TARGET_ASM_FILE_START
10115 #define TARGET_ASM_FILE_START unicosmk_file_start
10116 #undef TARGET_ASM_FILE_END
10117 #define TARGET_ASM_FILE_END unicosmk_file_end
10119 #undef TARGET_ASM_FILE_START
10120 #define TARGET_ASM_FILE_START alpha_file_start
10121 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
10122 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
10125 #undef TARGET_SCHED_ADJUST_COST
10126 #define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
10127 #undef TARGET_SCHED_ISSUE_RATE
10128 #define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
10129 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
10130 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
10131 alpha_multipass_dfa_lookahead
10133 #undef TARGET_HAVE_TLS
10134 #define TARGET_HAVE_TLS HAVE_AS_TLS
10136 #undef TARGET_INIT_BUILTINS
10137 #define TARGET_INIT_BUILTINS alpha_init_builtins
10138 #undef TARGET_EXPAND_BUILTIN
10139 #define TARGET_EXPAND_BUILTIN alpha_expand_builtin
10140 #undef TARGET_FOLD_BUILTIN
10141 #define TARGET_FOLD_BUILTIN alpha_fold_builtin
10143 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
10144 #define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall
10145 #undef TARGET_CANNOT_COPY_INSN_P
10146 #define TARGET_CANNOT_COPY_INSN_P alpha_cannot_copy_insn_p
10147 #undef TARGET_CANNOT_FORCE_CONST_MEM
10148 #define TARGET_CANNOT_FORCE_CONST_MEM alpha_cannot_force_const_mem
10151 #undef TARGET_ASM_OUTPUT_MI_THUNK
10152 #define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
10153 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
10154 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
10157 #undef TARGET_RTX_COSTS
10158 #define TARGET_RTX_COSTS alpha_rtx_costs
10159 #undef TARGET_ADDRESS_COST
10160 #define TARGET_ADDRESS_COST hook_int_rtx_0
10162 #undef TARGET_MACHINE_DEPENDENT_REORG
10163 #define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg
10165 #undef TARGET_PROMOTE_FUNCTION_ARGS
10166 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
10167 #undef TARGET_PROMOTE_FUNCTION_RETURN
10168 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
10169 #undef TARGET_PROMOTE_PROTOTYPES
10170 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_false
10171 #undef TARGET_RETURN_IN_MEMORY
10172 #define TARGET_RETURN_IN_MEMORY alpha_return_in_memory
10173 #undef TARGET_PASS_BY_REFERENCE
10174 #define TARGET_PASS_BY_REFERENCE alpha_pass_by_reference
10175 #undef TARGET_SETUP_INCOMING_VARARGS
10176 #define TARGET_SETUP_INCOMING_VARARGS alpha_setup_incoming_varargs
10177 #undef TARGET_STRICT_ARGUMENT_NAMING
10178 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
10179 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
10180 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
10181 #undef TARGET_SPLIT_COMPLEX_ARG
10182 #define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg
10183 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
10184 #define TARGET_GIMPLIFY_VA_ARG_EXPR alpha_gimplify_va_arg
10185 #undef TARGET_ARG_PARTIAL_BYTES
10186 #define TARGET_ARG_PARTIAL_BYTES alpha_arg_partial_bytes
10188 #undef TARGET_SCALAR_MODE_SUPPORTED_P
10189 #define TARGET_SCALAR_MODE_SUPPORTED_P alpha_scalar_mode_supported_p
10190 #undef TARGET_VECTOR_MODE_SUPPORTED_P
10191 #define TARGET_VECTOR_MODE_SUPPORTED_P alpha_vector_mode_supported_p
10193 #undef TARGET_BUILD_BUILTIN_VA_LIST
10194 #define TARGET_BUILD_BUILTIN_VA_LIST alpha_build_builtin_va_list
10196 /* The Alpha architecture does not require sequential consistency. See
10197 http://www.cs.umd.edu/~pugh/java/memoryModel/AlphaReordering.html
10198 for an example of how it can be violated in practice. */
10199 #undef TARGET_RELAXED_ORDERING
10200 #define TARGET_RELAXED_ORDERING true
10202 #undef TARGET_DEFAULT_TARGET_FLAGS
10203 #define TARGET_DEFAULT_TARGET_FLAGS \
10204 (TARGET_DEFAULT | TARGET_CPU_DEFAULT | TARGET_DEFAULT_EXPLICIT_RELOCS)
10205 #undef TARGET_HANDLE_OPTION
10206 #define TARGET_HANDLE_OPTION alpha_handle_option
10208 struct gcc_target targetm = TARGET_INITIALIZER;
10211 #include "gt-alpha.h"