1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992-2013 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
24 #include "coretypes.h"
28 #include "stor-layout.h"
32 #include "hard-reg-set.h"
33 #include "insn-config.h"
34 #include "conditions.h"
36 #include "insn-attr.h"
45 #include "diagnostic-core.h"
49 #include "target-def.h"
50 #include "common/common-target.h"
52 #include "langhooks.h"
53 #include "splay-tree.h"
56 #include "gimple-ssa.h"
57 #include "stringpool.h"
58 #include "tree-ssanames.h"
59 #include "tree-stdarg.h"
60 #include "tm-constrs.h"
66 /* Specify which cpu to schedule for. */
67 enum processor_type alpha_tune
;
69 /* Which cpu we're generating code for. */
70 enum processor_type alpha_cpu
;
72 static const char * const alpha_cpu_name
[] =
77 /* Specify how accurate floating-point traps need to be. */
79 enum alpha_trap_precision alpha_tp
;
81 /* Specify the floating-point rounding mode. */
83 enum alpha_fp_rounding_mode alpha_fprm
;
85 /* Specify which things cause traps. */
87 enum alpha_fp_trap_mode alpha_fptm
;
89 /* Nonzero if inside of a function, because the Alpha asm can't
90 handle .files inside of functions. */
92 static int inside_function
= FALSE
;
94 /* The number of cycles of latency we should assume on memory reads. */
96 int alpha_memory_latency
= 3;
98 /* Whether the function needs the GP. */
100 static int alpha_function_needs_gp
;
102 /* The assembler name of the current function. */
104 static const char *alpha_fnname
;
106 /* The next explicit relocation sequence number. */
107 extern GTY(()) int alpha_next_sequence_number
;
108 int alpha_next_sequence_number
= 1;
110 /* The literal and gpdisp sequence numbers for this insn, as printed
111 by %# and %* respectively. */
112 extern GTY(()) int alpha_this_literal_sequence_number
;
113 extern GTY(()) int alpha_this_gpdisp_sequence_number
;
114 int alpha_this_literal_sequence_number
;
115 int alpha_this_gpdisp_sequence_number
;
117 /* Costs of various operations on the different architectures. */
119 struct alpha_rtx_cost_data
121 unsigned char fp_add
;
122 unsigned char fp_mult
;
123 unsigned char fp_div_sf
;
124 unsigned char fp_div_df
;
125 unsigned char int_mult_si
;
126 unsigned char int_mult_di
;
127 unsigned char int_shift
;
128 unsigned char int_cmov
;
129 unsigned short int_div
;
132 static struct alpha_rtx_cost_data
const alpha_rtx_cost_data
[PROCESSOR_MAX
] =
135 COSTS_N_INSNS (6), /* fp_add */
136 COSTS_N_INSNS (6), /* fp_mult */
137 COSTS_N_INSNS (34), /* fp_div_sf */
138 COSTS_N_INSNS (63), /* fp_div_df */
139 COSTS_N_INSNS (23), /* int_mult_si */
140 COSTS_N_INSNS (23), /* int_mult_di */
141 COSTS_N_INSNS (2), /* int_shift */
142 COSTS_N_INSNS (2), /* int_cmov */
143 COSTS_N_INSNS (97), /* int_div */
146 COSTS_N_INSNS (4), /* fp_add */
147 COSTS_N_INSNS (4), /* fp_mult */
148 COSTS_N_INSNS (15), /* fp_div_sf */
149 COSTS_N_INSNS (22), /* fp_div_df */
150 COSTS_N_INSNS (8), /* int_mult_si */
151 COSTS_N_INSNS (12), /* int_mult_di */
152 COSTS_N_INSNS (1) + 1, /* int_shift */
153 COSTS_N_INSNS (1), /* int_cmov */
154 COSTS_N_INSNS (83), /* int_div */
157 COSTS_N_INSNS (4), /* fp_add */
158 COSTS_N_INSNS (4), /* fp_mult */
159 COSTS_N_INSNS (12), /* fp_div_sf */
160 COSTS_N_INSNS (15), /* fp_div_df */
161 COSTS_N_INSNS (7), /* int_mult_si */
162 COSTS_N_INSNS (7), /* int_mult_di */
163 COSTS_N_INSNS (1), /* int_shift */
164 COSTS_N_INSNS (2), /* int_cmov */
165 COSTS_N_INSNS (86), /* int_div */
169 /* Similar but tuned for code size instead of execution latency. The
170 extra +N is fractional cost tuning based on latency. It's used to
171 encourage use of cheaper insns like shift, but only if there's just
174 static struct alpha_rtx_cost_data
const alpha_rtx_cost_size
=
176 COSTS_N_INSNS (1), /* fp_add */
177 COSTS_N_INSNS (1), /* fp_mult */
178 COSTS_N_INSNS (1), /* fp_div_sf */
179 COSTS_N_INSNS (1) + 1, /* fp_div_df */
180 COSTS_N_INSNS (1) + 1, /* int_mult_si */
181 COSTS_N_INSNS (1) + 2, /* int_mult_di */
182 COSTS_N_INSNS (1), /* int_shift */
183 COSTS_N_INSNS (1), /* int_cmov */
184 COSTS_N_INSNS (6), /* int_div */
187 /* Get the number of args of a function in one of two ways. */
188 #if TARGET_ABI_OPEN_VMS
189 #define NUM_ARGS crtl->args.info.num_args
191 #define NUM_ARGS crtl->args.info
197 /* Declarations of static functions. */
198 static struct machine_function
*alpha_init_machine_status (void);
199 static rtx
alpha_emit_xfloating_compare (enum rtx_code
*, rtx
, rtx
);
201 #if TARGET_ABI_OPEN_VMS
202 static void alpha_write_linkage (FILE *, const char *);
203 static bool vms_valid_pointer_mode (enum machine_mode
);
205 #define vms_patch_builtins() gcc_unreachable()
208 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
209 /* Implement TARGET_MANGLE_TYPE. */
212 alpha_mangle_type (const_tree type
)
214 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
215 && TARGET_LONG_DOUBLE_128
)
218 /* For all other types, use normal C++ mangling. */
223 /* Parse target option strings. */
226 alpha_option_override (void)
228 static const struct cpu_table
{
229 const char *const name
;
230 const enum processor_type processor
;
232 const unsigned short line_size
; /* in bytes */
233 const unsigned short l1_size
; /* in kb. */
234 const unsigned short l2_size
; /* in kb. */
236 /* EV4/LCA45 had 8k L1 caches; EV45 had 16k L1 caches.
237 EV4/EV45 had 128k to 16M 32-byte direct Bcache. LCA45
238 had 64k to 8M 8-byte direct Bcache. */
239 { "ev4", PROCESSOR_EV4
, 0, 32, 8, 8*1024 },
240 { "21064", PROCESSOR_EV4
, 0, 32, 8, 8*1024 },
241 { "ev45", PROCESSOR_EV4
, 0, 32, 16, 16*1024 },
243 /* EV5 or EV56 had 8k 32 byte L1, 96k 32 or 64 byte L2,
244 and 1M to 16M 64 byte L3 (not modeled).
245 PCA56 had 16k 64-byte cache; PCA57 had 32k Icache.
246 PCA56 had 8k 64-byte cache; PCA57 had 16k Dcache. */
247 { "ev5", PROCESSOR_EV5
, 0, 32, 8, 96 },
248 { "21164", PROCESSOR_EV5
, 0, 32, 8, 96 },
249 { "ev56", PROCESSOR_EV5
, MASK_BWX
, 32, 8, 96 },
250 { "21164a", PROCESSOR_EV5
, MASK_BWX
, 32, 8, 96 },
251 { "pca56", PROCESSOR_EV5
, MASK_BWX
|MASK_MAX
, 64, 16, 4*1024 },
252 { "21164PC",PROCESSOR_EV5
, MASK_BWX
|MASK_MAX
, 64, 16, 4*1024 },
253 { "21164pc",PROCESSOR_EV5
, MASK_BWX
|MASK_MAX
, 64, 16, 4*1024 },
255 /* EV6 had 64k 64 byte L1, 1M to 16M Bcache. */
256 { "ev6", PROCESSOR_EV6
, MASK_BWX
|MASK_MAX
|MASK_FIX
, 64, 64, 16*1024 },
257 { "21264", PROCESSOR_EV6
, MASK_BWX
|MASK_MAX
|MASK_FIX
, 64, 64, 16*1024 },
258 { "ev67", PROCESSOR_EV6
, MASK_BWX
|MASK_MAX
|MASK_FIX
|MASK_CIX
,
260 { "21264a", PROCESSOR_EV6
, MASK_BWX
|MASK_MAX
|MASK_FIX
|MASK_CIX
,
264 int const ct_size
= ARRAY_SIZE (cpu_table
);
265 int line_size
= 0, l1_size
= 0, l2_size
= 0;
268 #ifdef SUBTARGET_OVERRIDE_OPTIONS
269 SUBTARGET_OVERRIDE_OPTIONS
;
272 /* Default to full IEEE compliance mode for Go language. */
273 if (strcmp (lang_hooks
.name
, "GNU Go") == 0
274 && !(target_flags_explicit
& MASK_IEEE
))
275 target_flags
|= MASK_IEEE
;
277 alpha_fprm
= ALPHA_FPRM_NORM
;
278 alpha_tp
= ALPHA_TP_PROG
;
279 alpha_fptm
= ALPHA_FPTM_N
;
283 alpha_tp
= ALPHA_TP_INSN
;
284 alpha_fptm
= ALPHA_FPTM_SU
;
286 if (TARGET_IEEE_WITH_INEXACT
)
288 alpha_tp
= ALPHA_TP_INSN
;
289 alpha_fptm
= ALPHA_FPTM_SUI
;
294 if (! strcmp (alpha_tp_string
, "p"))
295 alpha_tp
= ALPHA_TP_PROG
;
296 else if (! strcmp (alpha_tp_string
, "f"))
297 alpha_tp
= ALPHA_TP_FUNC
;
298 else if (! strcmp (alpha_tp_string
, "i"))
299 alpha_tp
= ALPHA_TP_INSN
;
301 error ("bad value %qs for -mtrap-precision switch", alpha_tp_string
);
304 if (alpha_fprm_string
)
306 if (! strcmp (alpha_fprm_string
, "n"))
307 alpha_fprm
= ALPHA_FPRM_NORM
;
308 else if (! strcmp (alpha_fprm_string
, "m"))
309 alpha_fprm
= ALPHA_FPRM_MINF
;
310 else if (! strcmp (alpha_fprm_string
, "c"))
311 alpha_fprm
= ALPHA_FPRM_CHOP
;
312 else if (! strcmp (alpha_fprm_string
,"d"))
313 alpha_fprm
= ALPHA_FPRM_DYN
;
315 error ("bad value %qs for -mfp-rounding-mode switch",
319 if (alpha_fptm_string
)
321 if (strcmp (alpha_fptm_string
, "n") == 0)
322 alpha_fptm
= ALPHA_FPTM_N
;
323 else if (strcmp (alpha_fptm_string
, "u") == 0)
324 alpha_fptm
= ALPHA_FPTM_U
;
325 else if (strcmp (alpha_fptm_string
, "su") == 0)
326 alpha_fptm
= ALPHA_FPTM_SU
;
327 else if (strcmp (alpha_fptm_string
, "sui") == 0)
328 alpha_fptm
= ALPHA_FPTM_SUI
;
330 error ("bad value %qs for -mfp-trap-mode switch", alpha_fptm_string
);
333 if (alpha_cpu_string
)
335 for (i
= 0; i
< ct_size
; i
++)
336 if (! strcmp (alpha_cpu_string
, cpu_table
[i
].name
))
338 alpha_tune
= alpha_cpu
= cpu_table
[i
].processor
;
339 line_size
= cpu_table
[i
].line_size
;
340 l1_size
= cpu_table
[i
].l1_size
;
341 l2_size
= cpu_table
[i
].l2_size
;
342 target_flags
&= ~ (MASK_BWX
| MASK_MAX
| MASK_FIX
| MASK_CIX
);
343 target_flags
|= cpu_table
[i
].flags
;
347 error ("bad value %qs for -mcpu switch", alpha_cpu_string
);
350 if (alpha_tune_string
)
352 for (i
= 0; i
< ct_size
; i
++)
353 if (! strcmp (alpha_tune_string
, cpu_table
[i
].name
))
355 alpha_tune
= cpu_table
[i
].processor
;
356 line_size
= cpu_table
[i
].line_size
;
357 l1_size
= cpu_table
[i
].l1_size
;
358 l2_size
= cpu_table
[i
].l2_size
;
362 error ("bad value %qs for -mtune switch", alpha_tune_string
);
366 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE
, line_size
,
367 global_options
.x_param_values
,
368 global_options_set
.x_param_values
);
370 maybe_set_param_value (PARAM_L1_CACHE_SIZE
, l1_size
,
371 global_options
.x_param_values
,
372 global_options_set
.x_param_values
);
374 maybe_set_param_value (PARAM_L2_CACHE_SIZE
, l2_size
,
375 global_options
.x_param_values
,
376 global_options_set
.x_param_values
);
378 /* Do some sanity checks on the above options. */
380 if ((alpha_fptm
== ALPHA_FPTM_SU
|| alpha_fptm
== ALPHA_FPTM_SUI
)
381 && alpha_tp
!= ALPHA_TP_INSN
&& alpha_cpu
!= PROCESSOR_EV6
)
383 warning (0, "fp software completion requires -mtrap-precision=i");
384 alpha_tp
= ALPHA_TP_INSN
;
387 if (alpha_cpu
== PROCESSOR_EV6
)
389 /* Except for EV6 pass 1 (not released), we always have precise
390 arithmetic traps. Which means we can do software completion
391 without minding trap shadows. */
392 alpha_tp
= ALPHA_TP_PROG
;
395 if (TARGET_FLOAT_VAX
)
397 if (alpha_fprm
== ALPHA_FPRM_MINF
|| alpha_fprm
== ALPHA_FPRM_DYN
)
399 warning (0, "rounding mode not supported for VAX floats");
400 alpha_fprm
= ALPHA_FPRM_NORM
;
402 if (alpha_fptm
== ALPHA_FPTM_SUI
)
404 warning (0, "trap mode not supported for VAX floats");
405 alpha_fptm
= ALPHA_FPTM_SU
;
407 if (target_flags_explicit
& MASK_LONG_DOUBLE_128
)
408 warning (0, "128-bit long double not supported for VAX floats");
409 target_flags
&= ~MASK_LONG_DOUBLE_128
;
416 if (!alpha_mlat_string
)
417 alpha_mlat_string
= "L1";
419 if (ISDIGIT ((unsigned char)alpha_mlat_string
[0])
420 && (lat
= strtol (alpha_mlat_string
, &end
, 10), *end
== '\0'))
422 else if ((alpha_mlat_string
[0] == 'L' || alpha_mlat_string
[0] == 'l')
423 && ISDIGIT ((unsigned char)alpha_mlat_string
[1])
424 && alpha_mlat_string
[2] == '\0')
426 static int const cache_latency
[][4] =
428 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
429 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
430 { 3, 12, 30 }, /* ev6 -- Bcache from DS20 LMbench. */
433 lat
= alpha_mlat_string
[1] - '0';
434 if (lat
<= 0 || lat
> 3 || cache_latency
[alpha_tune
][lat
-1] == -1)
436 warning (0, "L%d cache latency unknown for %s",
437 lat
, alpha_cpu_name
[alpha_tune
]);
441 lat
= cache_latency
[alpha_tune
][lat
-1];
443 else if (! strcmp (alpha_mlat_string
, "main"))
445 /* Most current memories have about 370ns latency. This is
446 a reasonable guess for a fast cpu. */
451 warning (0, "bad value %qs for -mmemory-latency", alpha_mlat_string
);
455 alpha_memory_latency
= lat
;
458 /* Default the definition of "small data" to 8 bytes. */
459 if (!global_options_set
.x_g_switch_value
)
462 /* Infer TARGET_SMALL_DATA from -fpic/-fPIC. */
464 target_flags
|= MASK_SMALL_DATA
;
465 else if (flag_pic
== 2)
466 target_flags
&= ~MASK_SMALL_DATA
;
468 /* Align labels and loops for optimal branching. */
469 /* ??? Kludge these by not doing anything if we don't optimize. */
472 if (align_loops
<= 0)
474 if (align_jumps
<= 0)
477 if (align_functions
<= 0)
478 align_functions
= 16;
480 /* Register variables and functions with the garbage collector. */
482 /* Set up function hooks. */
483 init_machine_status
= alpha_init_machine_status
;
485 /* Tell the compiler when we're using VAX floating point. */
486 if (TARGET_FLOAT_VAX
)
488 REAL_MODE_FORMAT (SFmode
) = &vax_f_format
;
489 REAL_MODE_FORMAT (DFmode
) = &vax_g_format
;
490 REAL_MODE_FORMAT (TFmode
) = NULL
;
493 #ifdef TARGET_DEFAULT_LONG_DOUBLE_128
494 if (!(target_flags_explicit
& MASK_LONG_DOUBLE_128
))
495 target_flags
|= MASK_LONG_DOUBLE_128
;
499 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
502 zap_mask (HOST_WIDE_INT value
)
506 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
508 if ((value
& 0xff) != 0 && (value
& 0xff) != 0xff)
514 /* Return true if OP is valid for a particular TLS relocation.
515 We are already guaranteed that OP is a CONST. */
518 tls_symbolic_operand_1 (rtx op
, int size
, int unspec
)
522 if (GET_CODE (op
) != UNSPEC
|| XINT (op
, 1) != unspec
)
524 op
= XVECEXP (op
, 0, 0);
526 if (GET_CODE (op
) != SYMBOL_REF
)
529 switch (SYMBOL_REF_TLS_MODEL (op
))
531 case TLS_MODEL_LOCAL_DYNAMIC
:
532 return unspec
== UNSPEC_DTPREL
&& size
== alpha_tls_size
;
533 case TLS_MODEL_INITIAL_EXEC
:
534 return unspec
== UNSPEC_TPREL
&& size
== 64;
535 case TLS_MODEL_LOCAL_EXEC
:
536 return unspec
== UNSPEC_TPREL
&& size
== alpha_tls_size
;
542 /* Used by aligned_memory_operand and unaligned_memory_operand to
543 resolve what reload is going to do with OP if it's a register. */
546 resolve_reload_operand (rtx op
)
548 if (reload_in_progress
)
551 if (GET_CODE (tmp
) == SUBREG
)
552 tmp
= SUBREG_REG (tmp
);
554 && REGNO (tmp
) >= FIRST_PSEUDO_REGISTER
)
556 op
= reg_equiv_memory_loc (REGNO (tmp
));
564 /* The scalar modes supported differs from the default check-what-c-supports
565 version in that sometimes TFmode is available even when long double
566 indicates only DFmode. */
569 alpha_scalar_mode_supported_p (enum machine_mode mode
)
577 case TImode
: /* via optabs.c */
585 return TARGET_HAS_XFLOATING_LIBS
;
592 /* Alpha implements a couple of integer vector mode operations when
593 TARGET_MAX is enabled. We do not check TARGET_MAX here, however,
594 which allows the vectorizer to operate on e.g. move instructions,
595 or when expand_vector_operations can do something useful. */
598 alpha_vector_mode_supported_p (enum machine_mode mode
)
600 return mode
== V8QImode
|| mode
== V4HImode
|| mode
== V2SImode
;
603 /* Return 1 if this function can directly return via $26. */
608 return (TARGET_ABI_OSF
610 && alpha_sa_size () == 0
611 && get_frame_size () == 0
612 && crtl
->outgoing_args_size
== 0
613 && crtl
->args
.pretend_args_size
== 0);
616 /* Return the TLS model to use for SYMBOL. */
618 static enum tls_model
619 tls_symbolic_operand_type (rtx symbol
)
621 enum tls_model model
;
623 if (GET_CODE (symbol
) != SYMBOL_REF
)
624 return TLS_MODEL_NONE
;
625 model
= SYMBOL_REF_TLS_MODEL (symbol
);
627 /* Local-exec with a 64-bit size is the same code as initial-exec. */
628 if (model
== TLS_MODEL_LOCAL_EXEC
&& alpha_tls_size
== 64)
629 model
= TLS_MODEL_INITIAL_EXEC
;
634 /* Return true if the function DECL will share the same GP as any
635 function in the current unit of translation. */
638 decl_has_samegp (const_tree decl
)
640 /* Functions that are not local can be overridden, and thus may
641 not share the same gp. */
642 if (!(*targetm
.binds_local_p
) (decl
))
645 /* If -msmall-data is in effect, assume that there is only one GP
646 for the module, and so any local symbol has this property. We
647 need explicit relocations to be able to enforce this for symbols
648 not defined in this unit of translation, however. */
649 if (TARGET_EXPLICIT_RELOCS
&& TARGET_SMALL_DATA
)
652 /* Functions that are not external are defined in this UoT. */
653 /* ??? Irritatingly, static functions not yet emitted are still
654 marked "external". Apply this to non-static functions only. */
655 return !TREE_PUBLIC (decl
) || !DECL_EXTERNAL (decl
);
658 /* Return true if EXP should be placed in the small data section. */
661 alpha_in_small_data_p (const_tree exp
)
663 /* We want to merge strings, so we never consider them small data. */
664 if (TREE_CODE (exp
) == STRING_CST
)
667 /* Functions are never in the small data area. Duh. */
668 if (TREE_CODE (exp
) == FUNCTION_DECL
)
671 if (TREE_CODE (exp
) == VAR_DECL
&& DECL_SECTION_NAME (exp
))
673 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (exp
));
674 if (strcmp (section
, ".sdata") == 0
675 || strcmp (section
, ".sbss") == 0)
680 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (exp
));
682 /* If this is an incomplete type with size 0, then we can't put it
683 in sdata because it might be too big when completed. */
684 if (size
> 0 && size
<= g_switch_value
)
691 #if TARGET_ABI_OPEN_VMS
693 vms_valid_pointer_mode (enum machine_mode mode
)
695 return (mode
== SImode
|| mode
== DImode
);
699 alpha_linkage_symbol_p (const char *symname
)
701 int symlen
= strlen (symname
);
704 return strcmp (&symname
[symlen
- 4], "..lk") == 0;
709 #define LINKAGE_SYMBOL_REF_P(X) \
710 ((GET_CODE (X) == SYMBOL_REF \
711 && alpha_linkage_symbol_p (XSTR (X, 0))) \
712 || (GET_CODE (X) == CONST \
713 && GET_CODE (XEXP (X, 0)) == PLUS \
714 && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \
715 && alpha_linkage_symbol_p (XSTR (XEXP (XEXP (X, 0), 0), 0))))
718 /* legitimate_address_p recognizes an RTL expression that is a valid
719 memory address for an instruction. The MODE argument is the
720 machine mode for the MEM expression that wants to use this address.
722 For Alpha, we have either a constant address or the sum of a
723 register and a constant address, or just a register. For DImode,
724 any of those forms can be surrounded with an AND that clear the
725 low-order three bits; this is an "unaligned" access. */
728 alpha_legitimate_address_p (enum machine_mode mode
, rtx x
, bool strict
)
730 /* If this is an ldq_u type address, discard the outer AND. */
732 && GET_CODE (x
) == AND
733 && CONST_INT_P (XEXP (x
, 1))
734 && INTVAL (XEXP (x
, 1)) == -8)
737 /* Discard non-paradoxical subregs. */
738 if (GET_CODE (x
) == SUBREG
739 && (GET_MODE_SIZE (GET_MODE (x
))
740 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x
)))))
743 /* Unadorned general registers are valid. */
746 ? STRICT_REG_OK_FOR_BASE_P (x
)
747 : NONSTRICT_REG_OK_FOR_BASE_P (x
)))
750 /* Constant addresses (i.e. +/- 32k) are valid. */
751 if (CONSTANT_ADDRESS_P (x
))
754 #if TARGET_ABI_OPEN_VMS
755 if (LINKAGE_SYMBOL_REF_P (x
))
759 /* Register plus a small constant offset is valid. */
760 if (GET_CODE (x
) == PLUS
)
762 rtx ofs
= XEXP (x
, 1);
765 /* Discard non-paradoxical subregs. */
766 if (GET_CODE (x
) == SUBREG
767 && (GET_MODE_SIZE (GET_MODE (x
))
768 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x
)))))
774 && NONSTRICT_REG_OK_FP_BASE_P (x
)
775 && CONST_INT_P (ofs
))
778 ? STRICT_REG_OK_FOR_BASE_P (x
)
779 : NONSTRICT_REG_OK_FOR_BASE_P (x
))
780 && CONSTANT_ADDRESS_P (ofs
))
785 /* If we're managing explicit relocations, LO_SUM is valid, as are small
786 data symbols. Avoid explicit relocations of modes larger than word
787 mode since i.e. $LC0+8($1) can fold around +/- 32k offset. */
788 else if (TARGET_EXPLICIT_RELOCS
789 && GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
791 if (small_symbolic_operand (x
, Pmode
))
794 if (GET_CODE (x
) == LO_SUM
)
796 rtx ofs
= XEXP (x
, 1);
799 /* Discard non-paradoxical subregs. */
800 if (GET_CODE (x
) == SUBREG
801 && (GET_MODE_SIZE (GET_MODE (x
))
802 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x
)))))
805 /* Must have a valid base register. */
808 ? STRICT_REG_OK_FOR_BASE_P (x
)
809 : NONSTRICT_REG_OK_FOR_BASE_P (x
))))
812 /* The symbol must be local. */
813 if (local_symbolic_operand (ofs
, Pmode
)
814 || dtp32_symbolic_operand (ofs
, Pmode
)
815 || tp32_symbolic_operand (ofs
, Pmode
))
823 /* Build the SYMBOL_REF for __tls_get_addr. */
825 static GTY(()) rtx tls_get_addr_libfunc
;
828 get_tls_get_addr (void)
830 if (!tls_get_addr_libfunc
)
831 tls_get_addr_libfunc
= init_one_libfunc ("__tls_get_addr");
832 return tls_get_addr_libfunc
;
835 /* Try machine-dependent ways of modifying an illegitimate address
836 to be legitimate. If we find one, return the new, valid address. */
839 alpha_legitimize_address_1 (rtx x
, rtx scratch
, enum machine_mode mode
)
841 HOST_WIDE_INT addend
;
843 /* If the address is (plus reg const_int) and the CONST_INT is not a
844 valid offset, compute the high part of the constant and add it to
845 the register. Then our address is (plus temp low-part-const). */
846 if (GET_CODE (x
) == PLUS
847 && REG_P (XEXP (x
, 0))
848 && CONST_INT_P (XEXP (x
, 1))
849 && ! CONSTANT_ADDRESS_P (XEXP (x
, 1)))
851 addend
= INTVAL (XEXP (x
, 1));
856 /* If the address is (const (plus FOO const_int)), find the low-order
857 part of the CONST_INT. Then load FOO plus any high-order part of the
858 CONST_INT into a register. Our address is (plus reg low-part-const).
859 This is done to reduce the number of GOT entries. */
860 if (can_create_pseudo_p ()
861 && GET_CODE (x
) == CONST
862 && GET_CODE (XEXP (x
, 0)) == PLUS
863 && CONST_INT_P (XEXP (XEXP (x
, 0), 1)))
865 addend
= INTVAL (XEXP (XEXP (x
, 0), 1));
866 x
= force_reg (Pmode
, XEXP (XEXP (x
, 0), 0));
870 /* If we have a (plus reg const), emit the load as in (2), then add
871 the two registers, and finally generate (plus reg low-part-const) as
873 if (can_create_pseudo_p ()
874 && GET_CODE (x
) == PLUS
875 && REG_P (XEXP (x
, 0))
876 && GET_CODE (XEXP (x
, 1)) == CONST
877 && GET_CODE (XEXP (XEXP (x
, 1), 0)) == PLUS
878 && CONST_INT_P (XEXP (XEXP (XEXP (x
, 1), 0), 1)))
880 addend
= INTVAL (XEXP (XEXP (XEXP (x
, 1), 0), 1));
881 x
= expand_simple_binop (Pmode
, PLUS
, XEXP (x
, 0),
882 XEXP (XEXP (XEXP (x
, 1), 0), 0),
883 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
887 /* If this is a local symbol, split the address into HIGH/LO_SUM parts.
888 Avoid modes larger than word mode since i.e. $LC0+8($1) can fold
889 around +/- 32k offset. */
890 if (TARGET_EXPLICIT_RELOCS
891 && GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
892 && symbolic_operand (x
, Pmode
))
894 rtx r0
, r16
, eqv
, tga
, tp
, insn
, dest
, seq
;
896 switch (tls_symbolic_operand_type (x
))
901 case TLS_MODEL_GLOBAL_DYNAMIC
:
904 r0
= gen_rtx_REG (Pmode
, 0);
905 r16
= gen_rtx_REG (Pmode
, 16);
906 tga
= get_tls_get_addr ();
907 dest
= gen_reg_rtx (Pmode
);
908 seq
= GEN_INT (alpha_next_sequence_number
++);
910 emit_insn (gen_movdi_er_tlsgd (r16
, pic_offset_table_rtx
, x
, seq
));
911 insn
= gen_call_value_osf_tlsgd (r0
, tga
, seq
);
912 insn
= emit_call_insn (insn
);
913 RTL_CONST_CALL_P (insn
) = 1;
914 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r16
);
919 emit_libcall_block (insn
, dest
, r0
, x
);
922 case TLS_MODEL_LOCAL_DYNAMIC
:
925 r0
= gen_rtx_REG (Pmode
, 0);
926 r16
= gen_rtx_REG (Pmode
, 16);
927 tga
= get_tls_get_addr ();
928 scratch
= gen_reg_rtx (Pmode
);
929 seq
= GEN_INT (alpha_next_sequence_number
++);
931 emit_insn (gen_movdi_er_tlsldm (r16
, pic_offset_table_rtx
, seq
));
932 insn
= gen_call_value_osf_tlsldm (r0
, tga
, seq
);
933 insn
= emit_call_insn (insn
);
934 RTL_CONST_CALL_P (insn
) = 1;
935 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r16
);
940 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
),
942 emit_libcall_block (insn
, scratch
, r0
, eqv
);
944 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, x
), UNSPEC_DTPREL
);
945 eqv
= gen_rtx_CONST (Pmode
, eqv
);
947 if (alpha_tls_size
== 64)
949 dest
= gen_reg_rtx (Pmode
);
950 emit_insn (gen_rtx_SET (VOIDmode
, dest
, eqv
));
951 emit_insn (gen_adddi3 (dest
, dest
, scratch
));
954 if (alpha_tls_size
== 32)
956 insn
= gen_rtx_HIGH (Pmode
, eqv
);
957 insn
= gen_rtx_PLUS (Pmode
, scratch
, insn
);
958 scratch
= gen_reg_rtx (Pmode
);
959 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, insn
));
961 return gen_rtx_LO_SUM (Pmode
, scratch
, eqv
);
963 case TLS_MODEL_INITIAL_EXEC
:
964 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, x
), UNSPEC_TPREL
);
965 eqv
= gen_rtx_CONST (Pmode
, eqv
);
966 tp
= gen_reg_rtx (Pmode
);
967 scratch
= gen_reg_rtx (Pmode
);
968 dest
= gen_reg_rtx (Pmode
);
970 emit_insn (gen_get_thread_pointerdi (tp
));
971 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, eqv
));
972 emit_insn (gen_adddi3 (dest
, tp
, scratch
));
975 case TLS_MODEL_LOCAL_EXEC
:
976 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, x
), UNSPEC_TPREL
);
977 eqv
= gen_rtx_CONST (Pmode
, eqv
);
978 tp
= gen_reg_rtx (Pmode
);
980 emit_insn (gen_get_thread_pointerdi (tp
));
981 if (alpha_tls_size
== 32)
983 insn
= gen_rtx_HIGH (Pmode
, eqv
);
984 insn
= gen_rtx_PLUS (Pmode
, tp
, insn
);
985 tp
= gen_reg_rtx (Pmode
);
986 emit_insn (gen_rtx_SET (VOIDmode
, tp
, insn
));
988 return gen_rtx_LO_SUM (Pmode
, tp
, eqv
);
994 if (local_symbolic_operand (x
, Pmode
))
996 if (small_symbolic_operand (x
, Pmode
))
1000 if (can_create_pseudo_p ())
1001 scratch
= gen_reg_rtx (Pmode
);
1002 emit_insn (gen_rtx_SET (VOIDmode
, scratch
,
1003 gen_rtx_HIGH (Pmode
, x
)));
1004 return gen_rtx_LO_SUM (Pmode
, scratch
, x
);
1013 HOST_WIDE_INT low
, high
;
1015 low
= ((addend
& 0xffff) ^ 0x8000) - 0x8000;
1017 high
= ((addend
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1021 x
= expand_simple_binop (Pmode
, PLUS
, x
, GEN_INT (addend
),
1022 (!can_create_pseudo_p () ? scratch
: NULL_RTX
),
1023 1, OPTAB_LIB_WIDEN
);
1025 x
= expand_simple_binop (Pmode
, PLUS
, x
, GEN_INT (high
),
1026 (!can_create_pseudo_p () ? scratch
: NULL_RTX
),
1027 1, OPTAB_LIB_WIDEN
);
1029 return plus_constant (Pmode
, x
, low
);
1034 /* Try machine-dependent ways of modifying an illegitimate address
1035 to be legitimate. Return X or the new, valid address. */
1038 alpha_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
1039 enum machine_mode mode
)
1041 rtx new_x
= alpha_legitimize_address_1 (x
, NULL_RTX
, mode
);
1042 return new_x
? new_x
: x
;
1045 /* Return true if ADDR has an effect that depends on the machine mode it
1046 is used for. On the Alpha this is true only for the unaligned modes.
1047 We can simplify the test since we know that the address must be valid. */
1050 alpha_mode_dependent_address_p (const_rtx addr
,
1051 addr_space_t as ATTRIBUTE_UNUSED
)
1053 return GET_CODE (addr
) == AND
;
1056 /* Primarily this is required for TLS symbols, but given that our move
1057 patterns *ought* to be able to handle any symbol at any time, we
1058 should never be spilling symbolic operands to the constant pool, ever. */
1061 alpha_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
1063 enum rtx_code code
= GET_CODE (x
);
1064 return code
== SYMBOL_REF
|| code
== LABEL_REF
|| code
== CONST
;
1067 /* We do not allow indirect calls to be optimized into sibling calls, nor
1068 can we allow a call to a function with a different GP to be optimized
1072 alpha_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
1074 /* Can't do indirect tail calls, since we don't know if the target
1075 uses the same GP. */
1079 /* Otherwise, we can make a tail call if the target function shares
1081 return decl_has_samegp (decl
);
1085 some_small_symbolic_operand_int (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
1089 /* Don't re-split. */
1090 if (GET_CODE (x
) == LO_SUM
)
1093 return small_symbolic_operand (x
, Pmode
) != 0;
1097 split_small_symbolic_operand_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
1101 /* Don't re-split. */
1102 if (GET_CODE (x
) == LO_SUM
)
1105 if (small_symbolic_operand (x
, Pmode
))
1107 x
= gen_rtx_LO_SUM (Pmode
, pic_offset_table_rtx
, x
);
1116 split_small_symbolic_operand (rtx x
)
1119 for_each_rtx (&x
, split_small_symbolic_operand_1
, NULL
);
1123 /* Indicate that INSN cannot be duplicated. This is true for any insn
1124 that we've marked with gpdisp relocs, since those have to stay in
1125 1-1 correspondence with one another.
1127 Technically we could copy them if we could set up a mapping from one
1128 sequence number to another, across the set of insns to be duplicated.
1129 This seems overly complicated and error-prone since interblock motion
1130 from sched-ebb could move one of the pair of insns to a different block.
1132 Also cannot allow jsr insns to be duplicated. If they throw exceptions,
1133 then they'll be in a different block from their ldgp. Which could lead
1134 the bb reorder code to think that it would be ok to copy just the block
1135 containing the call and branch to the block containing the ldgp. */
1138 alpha_cannot_copy_insn_p (rtx insn
)
1140 if (!reload_completed
|| !TARGET_EXPLICIT_RELOCS
)
1142 if (recog_memoized (insn
) >= 0)
1143 return get_attr_cannot_copy (insn
);
1149 /* Try a machine-dependent way of reloading an illegitimate address
1150 operand. If we find one, push the reload and return the new rtx. */
1153 alpha_legitimize_reload_address (rtx x
,
1154 enum machine_mode mode ATTRIBUTE_UNUSED
,
1155 int opnum
, int type
,
1156 int ind_levels ATTRIBUTE_UNUSED
)
1158 /* We must recognize output that we have already generated ourselves. */
1159 if (GET_CODE (x
) == PLUS
1160 && GET_CODE (XEXP (x
, 0)) == PLUS
1161 && REG_P (XEXP (XEXP (x
, 0), 0))
1162 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
1163 && CONST_INT_P (XEXP (x
, 1)))
1165 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
1166 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
1167 opnum
, (enum reload_type
) type
);
1171 /* We wish to handle large displacements off a base register by
1172 splitting the addend across an ldah and the mem insn. This
1173 cuts number of extra insns needed from 3 to 1. */
1174 if (GET_CODE (x
) == PLUS
1175 && REG_P (XEXP (x
, 0))
1176 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
1177 && REGNO_OK_FOR_BASE_P (REGNO (XEXP (x
, 0)))
1178 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
1180 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
1181 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
1183 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
1185 /* Check for 32-bit overflow. */
1186 if (high
+ low
!= val
)
1189 /* Reload the high part into a base reg; leave the low part
1190 in the mem directly. */
1191 x
= gen_rtx_PLUS (GET_MODE (x
),
1192 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
1196 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
1197 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
1198 opnum
, (enum reload_type
) type
);
1205 /* Compute a (partial) cost for rtx X. Return true if the complete
1206 cost has been computed, and false if subexpressions should be
1207 scanned. In either case, *TOTAL contains the cost result. */
1210 alpha_rtx_costs (rtx x
, int code
, int outer_code
, int opno
, int *total
,
1213 enum machine_mode mode
= GET_MODE (x
);
1214 bool float_mode_p
= FLOAT_MODE_P (mode
);
1215 const struct alpha_rtx_cost_data
*cost_data
;
1218 cost_data
= &alpha_rtx_cost_size
;
1220 cost_data
= &alpha_rtx_cost_data
[alpha_tune
];
1225 /* If this is an 8-bit constant, return zero since it can be used
1226 nearly anywhere with no cost. If it is a valid operand for an
1227 ADD or AND, likewise return 0 if we know it will be used in that
1228 context. Otherwise, return 2 since it might be used there later.
1229 All other constants take at least two insns. */
1230 if (INTVAL (x
) >= 0 && INTVAL (x
) < 256)
1238 if (x
== CONST0_RTX (mode
))
1240 else if ((outer_code
== PLUS
&& add_operand (x
, VOIDmode
))
1241 || (outer_code
== AND
&& and_operand (x
, VOIDmode
)))
1243 else if (add_operand (x
, VOIDmode
) || and_operand (x
, VOIDmode
))
1246 *total
= COSTS_N_INSNS (2);
1252 if (TARGET_EXPLICIT_RELOCS
&& small_symbolic_operand (x
, VOIDmode
))
1253 *total
= COSTS_N_INSNS (outer_code
!= MEM
);
1254 else if (TARGET_EXPLICIT_RELOCS
&& local_symbolic_operand (x
, VOIDmode
))
1255 *total
= COSTS_N_INSNS (1 + (outer_code
!= MEM
));
1256 else if (tls_symbolic_operand_type (x
))
1257 /* Estimate of cost for call_pal rduniq. */
1258 /* ??? How many insns do we emit here? More than one... */
1259 *total
= COSTS_N_INSNS (15);
1261 /* Otherwise we do a load from the GOT. */
1262 *total
= COSTS_N_INSNS (!speed
? 1 : alpha_memory_latency
);
1266 /* This is effectively an add_operand. */
1273 *total
= cost_data
->fp_add
;
1274 else if (GET_CODE (XEXP (x
, 0)) == MULT
1275 && const48_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
))
1277 *total
= (rtx_cost (XEXP (XEXP (x
, 0), 0),
1278 (enum rtx_code
) outer_code
, opno
, speed
)
1279 + rtx_cost (XEXP (x
, 1),
1280 (enum rtx_code
) outer_code
, opno
, speed
)
1281 + COSTS_N_INSNS (1));
1288 *total
= cost_data
->fp_mult
;
1289 else if (mode
== DImode
)
1290 *total
= cost_data
->int_mult_di
;
1292 *total
= cost_data
->int_mult_si
;
1296 if (CONST_INT_P (XEXP (x
, 1))
1297 && INTVAL (XEXP (x
, 1)) <= 3)
1299 *total
= COSTS_N_INSNS (1);
1306 *total
= cost_data
->int_shift
;
1311 *total
= cost_data
->fp_add
;
1313 *total
= cost_data
->int_cmov
;
1321 *total
= cost_data
->int_div
;
1322 else if (mode
== SFmode
)
1323 *total
= cost_data
->fp_div_sf
;
1325 *total
= cost_data
->fp_div_df
;
1329 *total
= COSTS_N_INSNS (!speed
? 1 : alpha_memory_latency
);
1335 *total
= COSTS_N_INSNS (1);
1343 *total
= COSTS_N_INSNS (1) + cost_data
->int_cmov
;
1349 case UNSIGNED_FLOAT
:
1352 case FLOAT_TRUNCATE
:
1353 *total
= cost_data
->fp_add
;
1357 if (MEM_P (XEXP (x
, 0)))
1360 *total
= cost_data
->fp_add
;
1368 /* REF is an alignable memory location. Place an aligned SImode
1369 reference into *PALIGNED_MEM and the number of bits to shift into
1370 *PBITNUM. SCRATCH is a free register for use in reloading out
1371 of range stack slots. */
1374 get_aligned_mem (rtx ref
, rtx
*paligned_mem
, rtx
*pbitnum
)
1377 HOST_WIDE_INT disp
, offset
;
1379 gcc_assert (MEM_P (ref
));
1381 if (reload_in_progress
1382 && ! memory_address_p (GET_MODE (ref
), XEXP (ref
, 0)))
1384 base
= find_replacement (&XEXP (ref
, 0));
1385 gcc_assert (memory_address_p (GET_MODE (ref
), base
));
1388 base
= XEXP (ref
, 0);
1390 if (GET_CODE (base
) == PLUS
)
1391 disp
= INTVAL (XEXP (base
, 1)), base
= XEXP (base
, 0);
1395 /* Find the byte offset within an aligned word. If the memory itself is
1396 claimed to be aligned, believe it. Otherwise, aligned_memory_operand
1397 will have examined the base register and determined it is aligned, and
1398 thus displacements from it are naturally alignable. */
1399 if (MEM_ALIGN (ref
) >= 32)
1404 /* The location should not cross aligned word boundary. */
1405 gcc_assert (offset
+ GET_MODE_SIZE (GET_MODE (ref
))
1406 <= GET_MODE_SIZE (SImode
));
1408 /* Access the entire aligned word. */
1409 *paligned_mem
= widen_memory_access (ref
, SImode
, -offset
);
1411 /* Convert the byte offset within the word to a bit offset. */
1412 offset
*= BITS_PER_UNIT
;
1413 *pbitnum
= GEN_INT (offset
);
1416 /* Similar, but just get the address. Handle the two reload cases.
1417 Add EXTRA_OFFSET to the address we return. */
1420 get_unaligned_address (rtx ref
)
1423 HOST_WIDE_INT offset
= 0;
1425 gcc_assert (MEM_P (ref
));
1427 if (reload_in_progress
1428 && ! memory_address_p (GET_MODE (ref
), XEXP (ref
, 0)))
1430 base
= find_replacement (&XEXP (ref
, 0));
1432 gcc_assert (memory_address_p (GET_MODE (ref
), base
));
1435 base
= XEXP (ref
, 0);
1437 if (GET_CODE (base
) == PLUS
)
1438 offset
+= INTVAL (XEXP (base
, 1)), base
= XEXP (base
, 0);
1440 return plus_constant (Pmode
, base
, offset
);
1443 /* Compute a value X, such that X & 7 == (ADDR + OFS) & 7.
1444 X is always returned in a register. */
1447 get_unaligned_offset (rtx addr
, HOST_WIDE_INT ofs
)
1449 if (GET_CODE (addr
) == PLUS
)
1451 ofs
+= INTVAL (XEXP (addr
, 1));
1452 addr
= XEXP (addr
, 0);
1455 return expand_simple_binop (Pmode
, PLUS
, addr
, GEN_INT (ofs
& 7),
1456 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
1459 /* On the Alpha, all (non-symbolic) constants except zero go into
1460 a floating-point register via memory. Note that we cannot
1461 return anything that is not a subset of RCLASS, and that some
1462 symbolic constants cannot be dropped to memory. */
1465 alpha_preferred_reload_class(rtx x
, enum reg_class rclass
)
1467 /* Zero is present in any register class. */
1468 if (x
== CONST0_RTX (GET_MODE (x
)))
1471 /* These sorts of constants we can easily drop to memory. */
1473 || GET_CODE (x
) == CONST_DOUBLE
1474 || GET_CODE (x
) == CONST_VECTOR
)
1476 if (rclass
== FLOAT_REGS
)
1478 if (rclass
== ALL_REGS
)
1479 return GENERAL_REGS
;
1483 /* All other kinds of constants should not (and in the case of HIGH
1484 cannot) be dropped to memory -- instead we use a GENERAL_REGS
1485 secondary reload. */
1487 return (rclass
== ALL_REGS
? GENERAL_REGS
: rclass
);
1492 /* Inform reload about cases where moving X with a mode MODE to a register in
1493 RCLASS requires an extra scratch or immediate register. Return the class
1494 needed for the immediate register. */
1497 alpha_secondary_reload (bool in_p
, rtx x
, reg_class_t rclass_i
,
1498 enum machine_mode mode
, secondary_reload_info
*sri
)
1500 enum reg_class rclass
= (enum reg_class
) rclass_i
;
1502 /* Loading and storing HImode or QImode values to and from memory
1503 usually requires a scratch register. */
1504 if (!TARGET_BWX
&& (mode
== QImode
|| mode
== HImode
|| mode
== CQImode
))
1506 if (any_memory_operand (x
, mode
))
1510 if (!aligned_memory_operand (x
, mode
))
1511 sri
->icode
= direct_optab_handler (reload_in_optab
, mode
);
1514 sri
->icode
= direct_optab_handler (reload_out_optab
, mode
);
1519 /* We also cannot do integral arithmetic into FP regs, as might result
1520 from register elimination into a DImode fp register. */
1521 if (rclass
== FLOAT_REGS
)
1523 if (MEM_P (x
) && GET_CODE (XEXP (x
, 0)) == AND
)
1524 return GENERAL_REGS
;
1525 if (in_p
&& INTEGRAL_MODE_P (mode
)
1526 && !MEM_P (x
) && !REG_P (x
) && !CONST_INT_P (x
))
1527 return GENERAL_REGS
;
1533 /* Subfunction of the following function. Update the flags of any MEM
1534 found in part of X. */
1537 alpha_set_memflags_1 (rtx
*xp
, void *data
)
1539 rtx x
= *xp
, orig
= (rtx
) data
;
1544 MEM_VOLATILE_P (x
) = MEM_VOLATILE_P (orig
);
1545 MEM_NOTRAP_P (x
) = MEM_NOTRAP_P (orig
);
1546 MEM_READONLY_P (x
) = MEM_READONLY_P (orig
);
1548 /* Sadly, we cannot use alias sets because the extra aliasing
1549 produced by the AND interferes. Given that two-byte quantities
1550 are the only thing we would be able to differentiate anyway,
1551 there does not seem to be any point in convoluting the early
1552 out of the alias check. */
1557 /* Given SEQ, which is an INSN list, look for any MEMs in either
1558 a SET_DEST or a SET_SRC and copy the in-struct, unchanging, and
1559 volatile flags from REF into each of the MEMs found. If REF is not
1560 a MEM, don't do anything. */
1563 alpha_set_memflags (rtx seq
, rtx ref
)
1570 /* This is only called from alpha.md, after having had something
1571 generated from one of the insn patterns. So if everything is
1572 zero, the pattern is already up-to-date. */
1573 if (!MEM_VOLATILE_P (ref
)
1574 && !MEM_NOTRAP_P (ref
)
1575 && !MEM_READONLY_P (ref
))
1578 for (insn
= seq
; insn
; insn
= NEXT_INSN (insn
))
1580 for_each_rtx (&PATTERN (insn
), alpha_set_memflags_1
, (void *) ref
);
1585 static rtx
alpha_emit_set_const (rtx
, enum machine_mode
, HOST_WIDE_INT
,
1588 /* Internal routine for alpha_emit_set_const to check for N or below insns.
1589 If NO_OUTPUT is true, then we only check to see if N insns are possible,
1590 and return pc_rtx if successful. */
1593 alpha_emit_set_const_1 (rtx target
, enum machine_mode mode
,
1594 HOST_WIDE_INT c
, int n
, bool no_output
)
1596 HOST_WIDE_INT new_const
;
1598 /* Use a pseudo if highly optimizing and still generating RTL. */
1600 = (flag_expensive_optimizations
&& can_create_pseudo_p () ? 0 : target
);
1603 /* If this is a sign-extended 32-bit constant, we can do this in at most
1604 three insns, so do it if we have enough insns left. We always have
1605 a sign-extended 32-bit constant when compiling on a narrow machine. */
1607 if (HOST_BITS_PER_WIDE_INT
!= 64
1608 || c
>> 31 == -1 || c
>> 31 == 0)
1610 HOST_WIDE_INT low
= ((c
& 0xffff) ^ 0x8000) - 0x8000;
1611 HOST_WIDE_INT tmp1
= c
- low
;
1612 HOST_WIDE_INT high
= (((tmp1
>> 16) & 0xffff) ^ 0x8000) - 0x8000;
1613 HOST_WIDE_INT extra
= 0;
1615 /* If HIGH will be interpreted as negative but the constant is
1616 positive, we must adjust it to do two ldha insns. */
1618 if ((high
& 0x8000) != 0 && c
>= 0)
1622 high
= ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
1625 if (c
== low
|| (low
== 0 && extra
== 0))
1627 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1628 but that meant that we can't handle INT_MIN on 32-bit machines
1629 (like NT/Alpha), because we recurse indefinitely through
1630 emit_move_insn to gen_movdi. So instead, since we know exactly
1631 what we want, create it explicitly. */
1636 target
= gen_reg_rtx (mode
);
1637 emit_insn (gen_rtx_SET (VOIDmode
, target
, GEN_INT (c
)));
1640 else if (n
>= 2 + (extra
!= 0))
1644 if (!can_create_pseudo_p ())
1646 emit_insn (gen_rtx_SET (VOIDmode
, target
, GEN_INT (high
<< 16)));
1650 temp
= copy_to_suggested_reg (GEN_INT (high
<< 16),
1653 /* As of 2002-02-23, addsi3 is only available when not optimizing.
1654 This means that if we go through expand_binop, we'll try to
1655 generate extensions, etc, which will require new pseudos, which
1656 will fail during some split phases. The SImode add patterns
1657 still exist, but are not named. So build the insns by hand. */
1662 subtarget
= gen_reg_rtx (mode
);
1663 insn
= gen_rtx_PLUS (mode
, temp
, GEN_INT (extra
<< 16));
1664 insn
= gen_rtx_SET (VOIDmode
, subtarget
, insn
);
1670 target
= gen_reg_rtx (mode
);
1671 insn
= gen_rtx_PLUS (mode
, temp
, GEN_INT (low
));
1672 insn
= gen_rtx_SET (VOIDmode
, target
, insn
);
1678 /* If we couldn't do it that way, try some other methods. But if we have
1679 no instructions left, don't bother. Likewise, if this is SImode and
1680 we can't make pseudos, we can't do anything since the expand_binop
1681 and expand_unop calls will widen and try to make pseudos. */
1683 if (n
== 1 || (mode
== SImode
&& !can_create_pseudo_p ()))
1686 /* Next, see if we can load a related constant and then shift and possibly
1687 negate it to get the constant we want. Try this once each increasing
1688 numbers of insns. */
1690 for (i
= 1; i
< n
; i
++)
1692 /* First, see if minus some low bits, we've an easy load of
1695 new_const
= ((c
& 0xffff) ^ 0x8000) - 0x8000;
1698 temp
= alpha_emit_set_const (subtarget
, mode
, c
- new_const
, i
, no_output
);
1703 return expand_binop (mode
, add_optab
, temp
, GEN_INT (new_const
),
1704 target
, 0, OPTAB_WIDEN
);
1708 /* Next try complementing. */
1709 temp
= alpha_emit_set_const (subtarget
, mode
, ~c
, i
, no_output
);
1714 return expand_unop (mode
, one_cmpl_optab
, temp
, target
, 0);
1717 /* Next try to form a constant and do a left shift. We can do this
1718 if some low-order bits are zero; the exact_log2 call below tells
1719 us that information. The bits we are shifting out could be any
1720 value, but here we'll just try the 0- and sign-extended forms of
1721 the constant. To try to increase the chance of having the same
1722 constant in more than one insn, start at the highest number of
1723 bits to shift, but try all possibilities in case a ZAPNOT will
1726 bits
= exact_log2 (c
& -c
);
1728 for (; bits
> 0; bits
--)
1730 new_const
= c
>> bits
;
1731 temp
= alpha_emit_set_const (subtarget
, mode
, new_const
, i
, no_output
);
1734 new_const
= (unsigned HOST_WIDE_INT
)c
>> bits
;
1735 temp
= alpha_emit_set_const (subtarget
, mode
, new_const
,
1742 return expand_binop (mode
, ashl_optab
, temp
, GEN_INT (bits
),
1743 target
, 0, OPTAB_WIDEN
);
1747 /* Now try high-order zero bits. Here we try the shifted-in bits as
1748 all zero and all ones. Be careful to avoid shifting outside the
1749 mode and to avoid shifting outside the host wide int size. */
1750 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1751 confuse the recursive call and set all of the high 32 bits. */
1753 bits
= (MIN (HOST_BITS_PER_WIDE_INT
, GET_MODE_SIZE (mode
) * 8)
1754 - floor_log2 (c
) - 1 - (HOST_BITS_PER_WIDE_INT
< 64));
1756 for (; bits
> 0; bits
--)
1758 new_const
= c
<< bits
;
1759 temp
= alpha_emit_set_const (subtarget
, mode
, new_const
, i
, no_output
);
1762 new_const
= (c
<< bits
) | (((HOST_WIDE_INT
) 1 << bits
) - 1);
1763 temp
= alpha_emit_set_const (subtarget
, mode
, new_const
,
1770 return expand_binop (mode
, lshr_optab
, temp
, GEN_INT (bits
),
1771 target
, 1, OPTAB_WIDEN
);
1775 /* Now try high-order 1 bits. We get that with a sign-extension.
1776 But one bit isn't enough here. Be careful to avoid shifting outside
1777 the mode and to avoid shifting outside the host wide int size. */
1779 bits
= (MIN (HOST_BITS_PER_WIDE_INT
, GET_MODE_SIZE (mode
) * 8)
1780 - floor_log2 (~ c
) - 2);
1782 for (; bits
> 0; bits
--)
1784 new_const
= c
<< bits
;
1785 temp
= alpha_emit_set_const (subtarget
, mode
, new_const
, i
, no_output
);
1788 new_const
= (c
<< bits
) | (((HOST_WIDE_INT
) 1 << bits
) - 1);
1789 temp
= alpha_emit_set_const (subtarget
, mode
, new_const
,
1796 return expand_binop (mode
, ashr_optab
, temp
, GEN_INT (bits
),
1797 target
, 0, OPTAB_WIDEN
);
1802 #if HOST_BITS_PER_WIDE_INT == 64
1803 /* Finally, see if can load a value into the target that is the same as the
1804 constant except that all bytes that are 0 are changed to be 0xff. If we
1805 can, then we can do a ZAPNOT to obtain the desired constant. */
1808 for (i
= 0; i
< 64; i
+= 8)
1809 if ((new_const
& ((HOST_WIDE_INT
) 0xff << i
)) == 0)
1810 new_const
|= (HOST_WIDE_INT
) 0xff << i
;
1812 /* We are only called for SImode and DImode. If this is SImode, ensure that
1813 we are sign extended to a full word. */
1816 new_const
= ((new_const
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1820 temp
= alpha_emit_set_const (subtarget
, mode
, new_const
, n
- 1, no_output
);
1825 return expand_binop (mode
, and_optab
, temp
, GEN_INT (c
| ~ new_const
),
1826 target
, 0, OPTAB_WIDEN
);
1834 /* Try to output insns to set TARGET equal to the constant C if it can be
1835 done in less than N insns. Do all computations in MODE. Returns the place
1836 where the output has been placed if it can be done and the insns have been
1837 emitted. If it would take more than N insns, zero is returned and no
1838 insns and emitted. */
1841 alpha_emit_set_const (rtx target
, enum machine_mode mode
,
1842 HOST_WIDE_INT c
, int n
, bool no_output
)
1844 enum machine_mode orig_mode
= mode
;
1845 rtx orig_target
= target
;
1849 /* If we can't make any pseudos, TARGET is an SImode hard register, we
1850 can't load this constant in one insn, do this in DImode. */
1851 if (!can_create_pseudo_p () && mode
== SImode
1852 && REG_P (target
) && REGNO (target
) < FIRST_PSEUDO_REGISTER
)
1854 result
= alpha_emit_set_const_1 (target
, mode
, c
, 1, no_output
);
1858 target
= no_output
? NULL
: gen_lowpart (DImode
, target
);
1861 else if (mode
== V8QImode
|| mode
== V4HImode
|| mode
== V2SImode
)
1863 target
= no_output
? NULL
: gen_lowpart (DImode
, target
);
1867 /* Try 1 insn, then 2, then up to N. */
1868 for (i
= 1; i
<= n
; i
++)
1870 result
= alpha_emit_set_const_1 (target
, mode
, c
, i
, no_output
);
1878 insn
= get_last_insn ();
1879 set
= single_set (insn
);
1880 if (! CONSTANT_P (SET_SRC (set
)))
1881 set_unique_reg_note (get_last_insn (), REG_EQUAL
, GEN_INT (c
));
1886 /* Allow for the case where we changed the mode of TARGET. */
1889 if (result
== target
)
1890 result
= orig_target
;
1891 else if (mode
!= orig_mode
)
1892 result
= gen_lowpart (orig_mode
, result
);
1898 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1899 fall back to a straight forward decomposition. We do this to avoid
1900 exponential run times encountered when looking for longer sequences
1901 with alpha_emit_set_const. */
1904 alpha_emit_set_long_const (rtx target
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
1906 HOST_WIDE_INT d1
, d2
, d3
, d4
;
1908 /* Decompose the entire word */
1909 #if HOST_BITS_PER_WIDE_INT >= 64
1910 gcc_assert (c2
== -(c1
< 0));
1911 d1
= ((c1
& 0xffff) ^ 0x8000) - 0x8000;
1913 d2
= ((c1
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1914 c1
= (c1
- d2
) >> 32;
1915 d3
= ((c1
& 0xffff) ^ 0x8000) - 0x8000;
1917 d4
= ((c1
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1918 gcc_assert (c1
== d4
);
1920 d1
= ((c1
& 0xffff) ^ 0x8000) - 0x8000;
1922 d2
= ((c1
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1923 gcc_assert (c1
== d2
);
1925 d3
= ((c2
& 0xffff) ^ 0x8000) - 0x8000;
1927 d4
= ((c2
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1928 gcc_assert (c2
== d4
);
1931 /* Construct the high word */
1934 emit_move_insn (target
, GEN_INT (d4
));
1936 emit_move_insn (target
, gen_rtx_PLUS (DImode
, target
, GEN_INT (d3
)));
1939 emit_move_insn (target
, GEN_INT (d3
));
1941 /* Shift it into place */
1942 emit_move_insn (target
, gen_rtx_ASHIFT (DImode
, target
, GEN_INT (32)));
1944 /* Add in the low bits. */
1946 emit_move_insn (target
, gen_rtx_PLUS (DImode
, target
, GEN_INT (d2
)));
1948 emit_move_insn (target
, gen_rtx_PLUS (DImode
, target
, GEN_INT (d1
)));
1953 /* Given an integral CONST_INT, CONST_DOUBLE, or CONST_VECTOR, return
1957 alpha_extract_integer (rtx x
, HOST_WIDE_INT
*p0
, HOST_WIDE_INT
*p1
)
1959 HOST_WIDE_INT i0
, i1
;
1961 if (GET_CODE (x
) == CONST_VECTOR
)
1962 x
= simplify_subreg (DImode
, x
, GET_MODE (x
), 0);
1965 if (CONST_INT_P (x
))
1970 else if (HOST_BITS_PER_WIDE_INT
>= 64)
1972 i0
= CONST_DOUBLE_LOW (x
);
1977 i0
= CONST_DOUBLE_LOW (x
);
1978 i1
= CONST_DOUBLE_HIGH (x
);
1985 /* Implement TARGET_LEGITIMATE_CONSTANT_P. This is all constants for which
1986 we are willing to load the value into a register via a move pattern.
1987 Normally this is all symbolic constants, integral constants that
1988 take three or fewer instructions, and floating-point zero. */
1991 alpha_legitimate_constant_p (enum machine_mode mode
, rtx x
)
1993 HOST_WIDE_INT i0
, i1
;
1995 switch (GET_CODE (x
))
2002 if (GET_CODE (XEXP (x
, 0)) == PLUS
2003 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
)
2004 x
= XEXP (XEXP (x
, 0), 0);
2008 if (GET_CODE (x
) != SYMBOL_REF
)
2014 /* TLS symbols are never valid. */
2015 return SYMBOL_REF_TLS_MODEL (x
) == 0;
2018 if (x
== CONST0_RTX (mode
))
2020 if (FLOAT_MODE_P (mode
))
2025 if (x
== CONST0_RTX (mode
))
2027 if (GET_MODE_CLASS (mode
) != MODE_VECTOR_INT
)
2029 if (GET_MODE_SIZE (mode
) != 8)
2035 if (TARGET_BUILD_CONSTANTS
)
2037 alpha_extract_integer (x
, &i0
, &i1
);
2038 if (HOST_BITS_PER_WIDE_INT
>= 64 || i1
== (-i0
< 0))
2039 return alpha_emit_set_const_1 (x
, mode
, i0
, 3, true) != NULL
;
2047 /* Operand 1 is known to be a constant, and should require more than one
2048 instruction to load. Emit that multi-part load. */
2051 alpha_split_const_mov (enum machine_mode mode
, rtx
*operands
)
2053 HOST_WIDE_INT i0
, i1
;
2054 rtx temp
= NULL_RTX
;
2056 alpha_extract_integer (operands
[1], &i0
, &i1
);
2058 if (HOST_BITS_PER_WIDE_INT
>= 64 || i1
== -(i0
< 0))
2059 temp
= alpha_emit_set_const (operands
[0], mode
, i0
, 3, false);
2061 if (!temp
&& TARGET_BUILD_CONSTANTS
)
2062 temp
= alpha_emit_set_long_const (operands
[0], i0
, i1
);
2066 if (!rtx_equal_p (operands
[0], temp
))
2067 emit_move_insn (operands
[0], temp
);
2074 /* Expand a move instruction; return true if all work is done.
2075 We don't handle non-bwx subword loads here. */
2078 alpha_expand_mov (enum machine_mode mode
, rtx
*operands
)
2082 /* If the output is not a register, the input must be. */
2083 if (MEM_P (operands
[0])
2084 && ! reg_or_0_operand (operands
[1], mode
))
2085 operands
[1] = force_reg (mode
, operands
[1]);
2087 /* Allow legitimize_address to perform some simplifications. */
2088 if (mode
== Pmode
&& symbolic_operand (operands
[1], mode
))
2090 tmp
= alpha_legitimize_address_1 (operands
[1], operands
[0], mode
);
2093 if (tmp
== operands
[0])
2100 /* Early out for non-constants and valid constants. */
2101 if (! CONSTANT_P (operands
[1]) || input_operand (operands
[1], mode
))
2104 /* Split large integers. */
2105 if (CONST_INT_P (operands
[1])
2106 || GET_CODE (operands
[1]) == CONST_DOUBLE
2107 || GET_CODE (operands
[1]) == CONST_VECTOR
)
2109 if (alpha_split_const_mov (mode
, operands
))
2113 /* Otherwise we've nothing left but to drop the thing to memory. */
2114 tmp
= force_const_mem (mode
, operands
[1]);
2116 if (tmp
== NULL_RTX
)
2119 if (reload_in_progress
)
2121 emit_move_insn (operands
[0], XEXP (tmp
, 0));
2122 operands
[1] = replace_equiv_address (tmp
, operands
[0]);
2125 operands
[1] = validize_mem (tmp
);
2129 /* Expand a non-bwx QImode or HImode move instruction;
2130 return true if all work is done. */
2133 alpha_expand_mov_nobwx (enum machine_mode mode
, rtx
*operands
)
2137 /* If the output is not a register, the input must be. */
2138 if (MEM_P (operands
[0]))
2139 operands
[1] = force_reg (mode
, operands
[1]);
2141 /* Handle four memory cases, unaligned and aligned for either the input
2142 or the output. The only case where we can be called during reload is
2143 for aligned loads; all other cases require temporaries. */
2145 if (any_memory_operand (operands
[1], mode
))
2147 if (aligned_memory_operand (operands
[1], mode
))
2149 if (reload_in_progress
)
2152 seq
= gen_reload_inqi_aligned (operands
[0], operands
[1]);
2154 seq
= gen_reload_inhi_aligned (operands
[0], operands
[1]);
2159 rtx aligned_mem
, bitnum
;
2160 rtx scratch
= gen_reg_rtx (SImode
);
2164 get_aligned_mem (operands
[1], &aligned_mem
, &bitnum
);
2166 subtarget
= operands
[0];
2167 if (REG_P (subtarget
))
2168 subtarget
= gen_lowpart (DImode
, subtarget
), copyout
= false;
2170 subtarget
= gen_reg_rtx (DImode
), copyout
= true;
2173 seq
= gen_aligned_loadqi (subtarget
, aligned_mem
,
2176 seq
= gen_aligned_loadhi (subtarget
, aligned_mem
,
2181 emit_move_insn (operands
[0], gen_lowpart (mode
, subtarget
));
2186 /* Don't pass these as parameters since that makes the generated
2187 code depend on parameter evaluation order which will cause
2188 bootstrap failures. */
2190 rtx temp1
, temp2
, subtarget
, ua
;
2193 temp1
= gen_reg_rtx (DImode
);
2194 temp2
= gen_reg_rtx (DImode
);
2196 subtarget
= operands
[0];
2197 if (REG_P (subtarget
))
2198 subtarget
= gen_lowpart (DImode
, subtarget
), copyout
= false;
2200 subtarget
= gen_reg_rtx (DImode
), copyout
= true;
2202 ua
= get_unaligned_address (operands
[1]);
2204 seq
= gen_unaligned_loadqi (subtarget
, ua
, temp1
, temp2
);
2206 seq
= gen_unaligned_loadhi (subtarget
, ua
, temp1
, temp2
);
2208 alpha_set_memflags (seq
, operands
[1]);
2212 emit_move_insn (operands
[0], gen_lowpart (mode
, subtarget
));
2217 if (any_memory_operand (operands
[0], mode
))
2219 if (aligned_memory_operand (operands
[0], mode
))
2221 rtx aligned_mem
, bitnum
;
2222 rtx temp1
= gen_reg_rtx (SImode
);
2223 rtx temp2
= gen_reg_rtx (SImode
);
2225 get_aligned_mem (operands
[0], &aligned_mem
, &bitnum
);
2227 emit_insn (gen_aligned_store (aligned_mem
, operands
[1], bitnum
,
2232 rtx temp1
= gen_reg_rtx (DImode
);
2233 rtx temp2
= gen_reg_rtx (DImode
);
2234 rtx temp3
= gen_reg_rtx (DImode
);
2235 rtx ua
= get_unaligned_address (operands
[0]);
2238 seq
= gen_unaligned_storeqi (ua
, operands
[1], temp1
, temp2
, temp3
);
2240 seq
= gen_unaligned_storehi (ua
, operands
[1], temp1
, temp2
, temp3
);
2242 alpha_set_memflags (seq
, operands
[0]);
2251 /* Implement the movmisalign patterns. One of the operands is a memory
2252 that is not naturally aligned. Emit instructions to load it. */
2255 alpha_expand_movmisalign (enum machine_mode mode
, rtx
*operands
)
2257 /* Honor misaligned loads, for those we promised to do so. */
2258 if (MEM_P (operands
[1]))
2262 if (register_operand (operands
[0], mode
))
2265 tmp
= gen_reg_rtx (mode
);
2267 alpha_expand_unaligned_load (tmp
, operands
[1], 8, 0, 0);
2268 if (tmp
!= operands
[0])
2269 emit_move_insn (operands
[0], tmp
);
2271 else if (MEM_P (operands
[0]))
2273 if (!reg_or_0_operand (operands
[1], mode
))
2274 operands
[1] = force_reg (mode
, operands
[1]);
2275 alpha_expand_unaligned_store (operands
[0], operands
[1], 8, 0);
2281 /* Generate an unsigned DImode to FP conversion. This is the same code
2282 optabs would emit if we didn't have TFmode patterns.
2284 For SFmode, this is the only construction I've found that can pass
2285 gcc.c-torture/execute/ieee/rbug.c. No scenario that uses DFmode
2286 intermediates will work, because you'll get intermediate rounding
2287 that ruins the end result. Some of this could be fixed by turning
2288 on round-to-positive-infinity, but that requires diddling the fpsr,
2289 which kills performance. I tried turning this around and converting
2290 to a negative number, so that I could turn on /m, but either I did
2291 it wrong or there's something else cause I wound up with the exact
2292 same single-bit error. There is a branch-less form of this same code:
2303 fcmoveq $f10,$f11,$f0
2305 I'm not using it because it's the same number of instructions as
2306 this branch-full form, and it has more serialized long latency
2307 instructions on the critical path.
2309 For DFmode, we can avoid rounding errors by breaking up the word
2310 into two pieces, converting them separately, and adding them back:
2312 LC0: .long 0,0x5f800000
2317 cpyse $f11,$f31,$f10
2318 cpyse $f31,$f11,$f11
2326 This doesn't seem to be a clear-cut win over the optabs form.
2327 It probably all depends on the distribution of numbers being
2328 converted -- in the optabs form, all but high-bit-set has a
2329 much lower minimum execution time. */
2332 alpha_emit_floatuns (rtx operands
[2])
2334 rtx neglab
, donelab
, i0
, i1
, f0
, in
, out
;
2335 enum machine_mode mode
;
2338 in
= force_reg (DImode
, operands
[1]);
2339 mode
= GET_MODE (out
);
2340 neglab
= gen_label_rtx ();
2341 donelab
= gen_label_rtx ();
2342 i0
= gen_reg_rtx (DImode
);
2343 i1
= gen_reg_rtx (DImode
);
2344 f0
= gen_reg_rtx (mode
);
2346 emit_cmp_and_jump_insns (in
, const0_rtx
, LT
, const0_rtx
, DImode
, 0, neglab
);
2348 emit_insn (gen_rtx_SET (VOIDmode
, out
, gen_rtx_FLOAT (mode
, in
)));
2349 emit_jump_insn (gen_jump (donelab
));
2352 emit_label (neglab
);
2354 emit_insn (gen_lshrdi3 (i0
, in
, const1_rtx
));
2355 emit_insn (gen_anddi3 (i1
, in
, const1_rtx
));
2356 emit_insn (gen_iordi3 (i0
, i0
, i1
));
2357 emit_insn (gen_rtx_SET (VOIDmode
, f0
, gen_rtx_FLOAT (mode
, i0
)));
2358 emit_insn (gen_rtx_SET (VOIDmode
, out
, gen_rtx_PLUS (mode
, f0
, f0
)));
2360 emit_label (donelab
);
2363 /* Generate the comparison for a conditional branch. */
2366 alpha_emit_conditional_branch (rtx operands
[], enum machine_mode cmp_mode
)
2368 enum rtx_code cmp_code
, branch_code
;
2369 enum machine_mode branch_mode
= VOIDmode
;
2370 enum rtx_code code
= GET_CODE (operands
[0]);
2371 rtx op0
= operands
[1], op1
= operands
[2];
2374 if (cmp_mode
== TFmode
)
2376 op0
= alpha_emit_xfloating_compare (&code
, op0
, op1
);
2381 /* The general case: fold the comparison code to the types of compares
2382 that we have, choosing the branch as necessary. */
2385 case EQ
: case LE
: case LT
: case LEU
: case LTU
:
2387 /* We have these compares. */
2388 cmp_code
= code
, branch_code
= NE
;
2393 /* These must be reversed. */
2394 cmp_code
= reverse_condition (code
), branch_code
= EQ
;
2397 case GE
: case GT
: case GEU
: case GTU
:
2398 /* For FP, we swap them, for INT, we reverse them. */
2399 if (cmp_mode
== DFmode
)
2401 cmp_code
= swap_condition (code
);
2403 tem
= op0
, op0
= op1
, op1
= tem
;
2407 cmp_code
= reverse_condition (code
);
2416 if (cmp_mode
== DFmode
)
2418 if (flag_unsafe_math_optimizations
&& cmp_code
!= UNORDERED
)
2420 /* When we are not as concerned about non-finite values, and we
2421 are comparing against zero, we can branch directly. */
2422 if (op1
== CONST0_RTX (DFmode
))
2423 cmp_code
= UNKNOWN
, branch_code
= code
;
2424 else if (op0
== CONST0_RTX (DFmode
))
2426 /* Undo the swap we probably did just above. */
2427 tem
= op0
, op0
= op1
, op1
= tem
;
2428 branch_code
= swap_condition (cmp_code
);
2434 /* ??? We mark the branch mode to be CCmode to prevent the
2435 compare and branch from being combined, since the compare
2436 insn follows IEEE rules that the branch does not. */
2437 branch_mode
= CCmode
;
2442 /* The following optimizations are only for signed compares. */
2443 if (code
!= LEU
&& code
!= LTU
&& code
!= GEU
&& code
!= GTU
)
2445 /* Whee. Compare and branch against 0 directly. */
2446 if (op1
== const0_rtx
)
2447 cmp_code
= UNKNOWN
, branch_code
= code
;
2449 /* If the constants doesn't fit into an immediate, but can
2450 be generated by lda/ldah, we adjust the argument and
2451 compare against zero, so we can use beq/bne directly. */
2452 /* ??? Don't do this when comparing against symbols, otherwise
2453 we'll reduce (&x == 0x1234) to (&x-0x1234 == 0), which will
2454 be declared false out of hand (at least for non-weak). */
2455 else if (CONST_INT_P (op1
)
2456 && (code
== EQ
|| code
== NE
)
2457 && !(symbolic_operand (op0
, VOIDmode
)
2458 || (REG_P (op0
) && REG_POINTER (op0
))))
2460 rtx n_op1
= GEN_INT (-INTVAL (op1
));
2462 if (! satisfies_constraint_I (op1
)
2463 && (satisfies_constraint_K (n_op1
)
2464 || satisfies_constraint_L (n_op1
)))
2465 cmp_code
= PLUS
, branch_code
= code
, op1
= n_op1
;
2469 if (!reg_or_0_operand (op0
, DImode
))
2470 op0
= force_reg (DImode
, op0
);
2471 if (cmp_code
!= PLUS
&& !reg_or_8bit_operand (op1
, DImode
))
2472 op1
= force_reg (DImode
, op1
);
2475 /* Emit an initial compare instruction, if necessary. */
2477 if (cmp_code
!= UNKNOWN
)
2479 tem
= gen_reg_rtx (cmp_mode
);
2480 emit_move_insn (tem
, gen_rtx_fmt_ee (cmp_code
, cmp_mode
, op0
, op1
));
2483 /* Emit the branch instruction. */
2484 tem
= gen_rtx_SET (VOIDmode
, pc_rtx
,
2485 gen_rtx_IF_THEN_ELSE (VOIDmode
,
2486 gen_rtx_fmt_ee (branch_code
,
2488 CONST0_RTX (cmp_mode
)),
2489 gen_rtx_LABEL_REF (VOIDmode
,
2492 emit_jump_insn (tem
);
2495 /* Certain simplifications can be done to make invalid setcc operations
2496 valid. Return the final comparison, or NULL if we can't work. */
2499 alpha_emit_setcc (rtx operands
[], enum machine_mode cmp_mode
)
2501 enum rtx_code cmp_code
;
2502 enum rtx_code code
= GET_CODE (operands
[1]);
2503 rtx op0
= operands
[2], op1
= operands
[3];
2506 if (cmp_mode
== TFmode
)
2508 op0
= alpha_emit_xfloating_compare (&code
, op0
, op1
);
2513 if (cmp_mode
== DFmode
&& !TARGET_FIX
)
2516 /* The general case: fold the comparison code to the types of compares
2517 that we have, choosing the branch as necessary. */
2522 case EQ
: case LE
: case LT
: case LEU
: case LTU
:
2524 /* We have these compares. */
2525 if (cmp_mode
== DFmode
)
2526 cmp_code
= code
, code
= NE
;
2530 if (cmp_mode
== DImode
&& op1
== const0_rtx
)
2535 cmp_code
= reverse_condition (code
);
2539 case GE
: case GT
: case GEU
: case GTU
:
2540 /* These normally need swapping, but for integer zero we have
2541 special patterns that recognize swapped operands. */
2542 if (cmp_mode
== DImode
&& op1
== const0_rtx
)
2544 code
= swap_condition (code
);
2545 if (cmp_mode
== DFmode
)
2546 cmp_code
= code
, code
= NE
;
2547 tmp
= op0
, op0
= op1
, op1
= tmp
;
2554 if (cmp_mode
== DImode
)
2556 if (!register_operand (op0
, DImode
))
2557 op0
= force_reg (DImode
, op0
);
2558 if (!reg_or_8bit_operand (op1
, DImode
))
2559 op1
= force_reg (DImode
, op1
);
2562 /* Emit an initial compare instruction, if necessary. */
2563 if (cmp_code
!= UNKNOWN
)
2565 tmp
= gen_reg_rtx (cmp_mode
);
2566 emit_insn (gen_rtx_SET (VOIDmode
, tmp
,
2567 gen_rtx_fmt_ee (cmp_code
, cmp_mode
, op0
, op1
)));
2569 op0
= cmp_mode
!= DImode
? gen_lowpart (DImode
, tmp
) : tmp
;
2573 /* Emit the setcc instruction. */
2574 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0],
2575 gen_rtx_fmt_ee (code
, DImode
, op0
, op1
)));
2580 /* Rewrite a comparison against zero CMP of the form
2581 (CODE (cc0) (const_int 0)) so it can be written validly in
2582 a conditional move (if_then_else CMP ...).
2583 If both of the operands that set cc0 are nonzero we must emit
2584 an insn to perform the compare (it can't be done within
2585 the conditional move). */
2588 alpha_emit_conditional_move (rtx cmp
, enum machine_mode mode
)
2590 enum rtx_code code
= GET_CODE (cmp
);
2591 enum rtx_code cmov_code
= NE
;
2592 rtx op0
= XEXP (cmp
, 0);
2593 rtx op1
= XEXP (cmp
, 1);
2594 enum machine_mode cmp_mode
2595 = (GET_MODE (op0
) == VOIDmode
? DImode
: GET_MODE (op0
));
2596 enum machine_mode cmov_mode
= VOIDmode
;
2597 int local_fast_math
= flag_unsafe_math_optimizations
;
2600 if (cmp_mode
== TFmode
)
2602 op0
= alpha_emit_xfloating_compare (&code
, op0
, op1
);
2607 gcc_assert (cmp_mode
== DFmode
|| cmp_mode
== DImode
);
2609 if (FLOAT_MODE_P (cmp_mode
) != FLOAT_MODE_P (mode
))
2611 enum rtx_code cmp_code
;
2616 /* If we have fp<->int register move instructions, do a cmov by
2617 performing the comparison in fp registers, and move the
2618 zero/nonzero value to integer registers, where we can then
2619 use a normal cmov, or vice-versa. */
2623 case EQ
: case LE
: case LT
: case LEU
: case LTU
:
2625 /* We have these compares. */
2626 cmp_code
= code
, code
= NE
;
2631 /* These must be reversed. */
2632 cmp_code
= reverse_condition (code
), code
= EQ
;
2635 case GE
: case GT
: case GEU
: case GTU
:
2636 /* These normally need swapping, but for integer zero we have
2637 special patterns that recognize swapped operands. */
2638 if (cmp_mode
== DImode
&& op1
== const0_rtx
)
2639 cmp_code
= code
, code
= NE
;
2642 cmp_code
= swap_condition (code
);
2644 tem
= op0
, op0
= op1
, op1
= tem
;
2652 if (cmp_mode
== DImode
)
2654 if (!reg_or_0_operand (op0
, DImode
))
2655 op0
= force_reg (DImode
, op0
);
2656 if (!reg_or_8bit_operand (op1
, DImode
))
2657 op1
= force_reg (DImode
, op1
);
2660 tem
= gen_reg_rtx (cmp_mode
);
2661 emit_insn (gen_rtx_SET (VOIDmode
, tem
,
2662 gen_rtx_fmt_ee (cmp_code
, cmp_mode
,
2665 cmp_mode
= cmp_mode
== DImode
? DFmode
: DImode
;
2666 op0
= gen_lowpart (cmp_mode
, tem
);
2667 op1
= CONST0_RTX (cmp_mode
);
2668 cmp
= gen_rtx_fmt_ee (code
, VOIDmode
, op0
, op1
);
2669 local_fast_math
= 1;
2672 if (cmp_mode
== DImode
)
2674 if (!reg_or_0_operand (op0
, DImode
))
2675 op0
= force_reg (DImode
, op0
);
2676 if (!reg_or_8bit_operand (op1
, DImode
))
2677 op1
= force_reg (DImode
, op1
);
2680 /* We may be able to use a conditional move directly.
2681 This avoids emitting spurious compares. */
2682 if (signed_comparison_operator (cmp
, VOIDmode
)
2683 && (cmp_mode
== DImode
|| local_fast_math
)
2684 && (op0
== CONST0_RTX (cmp_mode
) || op1
== CONST0_RTX (cmp_mode
)))
2685 return gen_rtx_fmt_ee (code
, VOIDmode
, op0
, op1
);
2687 /* We can't put the comparison inside the conditional move;
2688 emit a compare instruction and put that inside the
2689 conditional move. Make sure we emit only comparisons we have;
2690 swap or reverse as necessary. */
2692 if (!can_create_pseudo_p ())
2697 case EQ
: case LE
: case LT
: case LEU
: case LTU
:
2699 /* We have these compares: */
2704 /* These must be reversed. */
2705 code
= reverse_condition (code
);
2709 case GE
: case GT
: case GEU
: case GTU
:
2710 /* These normally need swapping, but for integer zero we have
2711 special patterns that recognize swapped operands. */
2712 if (cmp_mode
== DImode
&& op1
== const0_rtx
)
2714 code
= swap_condition (code
);
2715 tem
= op0
, op0
= op1
, op1
= tem
;
2722 if (cmp_mode
== DImode
)
2724 if (!reg_or_0_operand (op0
, DImode
))
2725 op0
= force_reg (DImode
, op0
);
2726 if (!reg_or_8bit_operand (op1
, DImode
))
2727 op1
= force_reg (DImode
, op1
);
2730 /* ??? We mark the branch mode to be CCmode to prevent the compare
2731 and cmov from being combined, since the compare insn follows IEEE
2732 rules that the cmov does not. */
2733 if (cmp_mode
== DFmode
&& !local_fast_math
)
2736 tem
= gen_reg_rtx (cmp_mode
);
2737 emit_move_insn (tem
, gen_rtx_fmt_ee (code
, cmp_mode
, op0
, op1
));
2738 return gen_rtx_fmt_ee (cmov_code
, cmov_mode
, tem
, CONST0_RTX (cmp_mode
));
2741 /* Simplify a conditional move of two constants into a setcc with
2742 arithmetic. This is done with a splitter since combine would
2743 just undo the work if done during code generation. It also catches
2744 cases we wouldn't have before cse. */
2747 alpha_split_conditional_move (enum rtx_code code
, rtx dest
, rtx cond
,
2748 rtx t_rtx
, rtx f_rtx
)
2750 HOST_WIDE_INT t
, f
, diff
;
2751 enum machine_mode mode
;
2752 rtx target
, subtarget
, tmp
;
2754 mode
= GET_MODE (dest
);
2759 if (((code
== NE
|| code
== EQ
) && diff
< 0)
2760 || (code
== GE
|| code
== GT
))
2762 code
= reverse_condition (code
);
2763 diff
= t
, t
= f
, f
= diff
;
2767 subtarget
= target
= dest
;
2770 target
= gen_lowpart (DImode
, dest
);
2771 if (can_create_pseudo_p ())
2772 subtarget
= gen_reg_rtx (DImode
);
2776 /* Below, we must be careful to use copy_rtx on target and subtarget
2777 in intermediate insns, as they may be a subreg rtx, which may not
2780 if (f
== 0 && exact_log2 (diff
) > 0
2781 /* On EV6, we've got enough shifters to make non-arithmetic shifts
2782 viable over a longer latency cmove. On EV5, the E0 slot is a
2783 scarce resource, and on EV4 shift has the same latency as a cmove. */
2784 && (diff
<= 8 || alpha_tune
== PROCESSOR_EV6
))
2786 tmp
= gen_rtx_fmt_ee (code
, DImode
, cond
, const0_rtx
);
2787 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (subtarget
), tmp
));
2789 tmp
= gen_rtx_ASHIFT (DImode
, copy_rtx (subtarget
),
2790 GEN_INT (exact_log2 (t
)));
2791 emit_insn (gen_rtx_SET (VOIDmode
, target
, tmp
));
2793 else if (f
== 0 && t
== -1)
2795 tmp
= gen_rtx_fmt_ee (code
, DImode
, cond
, const0_rtx
);
2796 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (subtarget
), tmp
));
2798 emit_insn (gen_negdi2 (target
, copy_rtx (subtarget
)));
2800 else if (diff
== 1 || diff
== 4 || diff
== 8)
2804 tmp
= gen_rtx_fmt_ee (code
, DImode
, cond
, const0_rtx
);
2805 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (subtarget
), tmp
));
2808 emit_insn (gen_adddi3 (target
, copy_rtx (subtarget
), GEN_INT (f
)));
2811 add_op
= GEN_INT (f
);
2812 if (sext_add_operand (add_op
, mode
))
2814 tmp
= gen_rtx_MULT (DImode
, copy_rtx (subtarget
),
2816 tmp
= gen_rtx_PLUS (DImode
, tmp
, add_op
);
2817 emit_insn (gen_rtx_SET (VOIDmode
, target
, tmp
));
2829 /* Look up the function X_floating library function name for the
2832 struct GTY(()) xfloating_op
2834 const enum rtx_code code
;
2835 const char *const GTY((skip
)) osf_func
;
2836 const char *const GTY((skip
)) vms_func
;
2840 static GTY(()) struct xfloating_op xfloating_ops
[] =
2842 { PLUS
, "_OtsAddX", "OTS$ADD_X", 0 },
2843 { MINUS
, "_OtsSubX", "OTS$SUB_X", 0 },
2844 { MULT
, "_OtsMulX", "OTS$MUL_X", 0 },
2845 { DIV
, "_OtsDivX", "OTS$DIV_X", 0 },
2846 { EQ
, "_OtsEqlX", "OTS$EQL_X", 0 },
2847 { NE
, "_OtsNeqX", "OTS$NEQ_X", 0 },
2848 { LT
, "_OtsLssX", "OTS$LSS_X", 0 },
2849 { LE
, "_OtsLeqX", "OTS$LEQ_X", 0 },
2850 { GT
, "_OtsGtrX", "OTS$GTR_X", 0 },
2851 { GE
, "_OtsGeqX", "OTS$GEQ_X", 0 },
2852 { FIX
, "_OtsCvtXQ", "OTS$CVTXQ", 0 },
2853 { FLOAT
, "_OtsCvtQX", "OTS$CVTQX", 0 },
2854 { UNSIGNED_FLOAT
, "_OtsCvtQUX", "OTS$CVTQUX", 0 },
2855 { FLOAT_EXTEND
, "_OtsConvertFloatTX", "OTS$CVT_FLOAT_T_X", 0 },
2856 { FLOAT_TRUNCATE
, "_OtsConvertFloatXT", "OTS$CVT_FLOAT_X_T", 0 }
2859 static GTY(()) struct xfloating_op vax_cvt_ops
[] =
2861 { FLOAT_EXTEND
, "_OtsConvertFloatGX", "OTS$CVT_FLOAT_G_X", 0 },
2862 { FLOAT_TRUNCATE
, "_OtsConvertFloatXG", "OTS$CVT_FLOAT_X_G", 0 }
2866 alpha_lookup_xfloating_lib_func (enum rtx_code code
)
2868 struct xfloating_op
*ops
= xfloating_ops
;
2869 long n
= ARRAY_SIZE (xfloating_ops
);
2872 gcc_assert (TARGET_HAS_XFLOATING_LIBS
);
2874 /* How irritating. Nothing to key off for the main table. */
2875 if (TARGET_FLOAT_VAX
&& (code
== FLOAT_EXTEND
|| code
== FLOAT_TRUNCATE
))
2878 n
= ARRAY_SIZE (vax_cvt_ops
);
2881 for (i
= 0; i
< n
; ++i
, ++ops
)
2882 if (ops
->code
== code
)
2884 rtx func
= ops
->libcall
;
2887 func
= init_one_libfunc (TARGET_ABI_OPEN_VMS
2888 ? ops
->vms_func
: ops
->osf_func
);
2889 ops
->libcall
= func
;
2897 /* Most X_floating operations take the rounding mode as an argument.
2898 Compute that here. */
2901 alpha_compute_xfloating_mode_arg (enum rtx_code code
,
2902 enum alpha_fp_rounding_mode round
)
2908 case ALPHA_FPRM_NORM
:
2911 case ALPHA_FPRM_MINF
:
2914 case ALPHA_FPRM_CHOP
:
2917 case ALPHA_FPRM_DYN
:
2923 /* XXX For reference, round to +inf is mode = 3. */
2926 if (code
== FLOAT_TRUNCATE
&& alpha_fptm
== ALPHA_FPTM_N
)
2932 /* Emit an X_floating library function call.
2934 Note that these functions do not follow normal calling conventions:
2935 TFmode arguments are passed in two integer registers (as opposed to
2936 indirect); TFmode return values appear in R16+R17.
2938 FUNC is the function to call.
2939 TARGET is where the output belongs.
2940 OPERANDS are the inputs.
2941 NOPERANDS is the count of inputs.
2942 EQUIV is the expression equivalent for the function.
2946 alpha_emit_xfloating_libcall (rtx func
, rtx target
, rtx operands
[],
2947 int noperands
, rtx equiv
)
2949 rtx usage
= NULL_RTX
, tmp
, reg
;
2954 for (i
= 0; i
< noperands
; ++i
)
2956 switch (GET_MODE (operands
[i
]))
2959 reg
= gen_rtx_REG (TFmode
, regno
);
2964 reg
= gen_rtx_REG (DFmode
, regno
+ 32);
2969 gcc_assert (CONST_INT_P (operands
[i
]));
2972 reg
= gen_rtx_REG (DImode
, regno
);
2980 emit_move_insn (reg
, operands
[i
]);
2981 use_reg (&usage
, reg
);
2984 switch (GET_MODE (target
))
2987 reg
= gen_rtx_REG (TFmode
, 16);
2990 reg
= gen_rtx_REG (DFmode
, 32);
2993 reg
= gen_rtx_REG (DImode
, 0);
2999 tmp
= gen_rtx_MEM (QImode
, func
);
3000 tmp
= emit_call_insn (GEN_CALL_VALUE (reg
, tmp
, const0_rtx
,
3001 const0_rtx
, const0_rtx
));
3002 CALL_INSN_FUNCTION_USAGE (tmp
) = usage
;
3003 RTL_CONST_CALL_P (tmp
) = 1;
3008 emit_libcall_block (tmp
, target
, reg
, equiv
);
3011 /* Emit an X_floating library function call for arithmetic (+,-,*,/). */
3014 alpha_emit_xfloating_arith (enum rtx_code code
, rtx operands
[])
3018 rtx out_operands
[3];
3020 func
= alpha_lookup_xfloating_lib_func (code
);
3021 mode
= alpha_compute_xfloating_mode_arg (code
, alpha_fprm
);
3023 out_operands
[0] = operands
[1];
3024 out_operands
[1] = operands
[2];
3025 out_operands
[2] = GEN_INT (mode
);
3026 alpha_emit_xfloating_libcall (func
, operands
[0], out_operands
, 3,
3027 gen_rtx_fmt_ee (code
, TFmode
, operands
[1],
3031 /* Emit an X_floating library function call for a comparison. */
3034 alpha_emit_xfloating_compare (enum rtx_code
*pcode
, rtx op0
, rtx op1
)
3036 enum rtx_code cmp_code
, res_code
;
3037 rtx func
, out
, operands
[2], note
;
3039 /* X_floating library comparison functions return
3043 Convert the compare against the raw return value. */
3071 func
= alpha_lookup_xfloating_lib_func (cmp_code
);
3075 out
= gen_reg_rtx (DImode
);
3077 /* What's actually returned is -1,0,1, not a proper boolean value. */
3078 note
= gen_rtx_fmt_ee (cmp_code
, VOIDmode
, op0
, op1
);
3079 note
= gen_rtx_UNSPEC (DImode
, gen_rtvec (1, note
), UNSPEC_XFLT_COMPARE
);
3080 alpha_emit_xfloating_libcall (func
, out
, operands
, 2, note
);
3085 /* Emit an X_floating library function call for a conversion. */
3088 alpha_emit_xfloating_cvt (enum rtx_code orig_code
, rtx operands
[])
3090 int noperands
= 1, mode
;
3091 rtx out_operands
[2];
3093 enum rtx_code code
= orig_code
;
3095 if (code
== UNSIGNED_FIX
)
3098 func
= alpha_lookup_xfloating_lib_func (code
);
3100 out_operands
[0] = operands
[1];
3105 mode
= alpha_compute_xfloating_mode_arg (code
, ALPHA_FPRM_CHOP
);
3106 out_operands
[1] = GEN_INT (mode
);
3109 case FLOAT_TRUNCATE
:
3110 mode
= alpha_compute_xfloating_mode_arg (code
, alpha_fprm
);
3111 out_operands
[1] = GEN_INT (mode
);
3118 alpha_emit_xfloating_libcall (func
, operands
[0], out_operands
, noperands
,
3119 gen_rtx_fmt_e (orig_code
,
3120 GET_MODE (operands
[0]),
3124 /* Split a TImode or TFmode move from OP[1] to OP[0] into a pair of
3125 DImode moves from OP[2,3] to OP[0,1]. If FIXUP_OVERLAP is true,
3126 guarantee that the sequence
3129 is valid. Naturally, output operand ordering is little-endian.
3130 This is used by *movtf_internal and *movti_internal. */
3133 alpha_split_tmode_pair (rtx operands
[4], enum machine_mode mode
,
3136 switch (GET_CODE (operands
[1]))
3139 operands
[3] = gen_rtx_REG (DImode
, REGNO (operands
[1]) + 1);
3140 operands
[2] = gen_rtx_REG (DImode
, REGNO (operands
[1]));
3144 operands
[3] = adjust_address (operands
[1], DImode
, 8);
3145 operands
[2] = adjust_address (operands
[1], DImode
, 0);
3150 gcc_assert (operands
[1] == CONST0_RTX (mode
));
3151 operands
[2] = operands
[3] = const0_rtx
;
3158 switch (GET_CODE (operands
[0]))
3161 operands
[1] = gen_rtx_REG (DImode
, REGNO (operands
[0]) + 1);
3162 operands
[0] = gen_rtx_REG (DImode
, REGNO (operands
[0]));
3166 operands
[1] = adjust_address (operands
[0], DImode
, 8);
3167 operands
[0] = adjust_address (operands
[0], DImode
, 0);
3174 if (fixup_overlap
&& reg_overlap_mentioned_p (operands
[0], operands
[3]))
3177 tmp
= operands
[0], operands
[0] = operands
[1], operands
[1] = tmp
;
3178 tmp
= operands
[2], operands
[2] = operands
[3], operands
[3] = tmp
;
3182 /* Implement negtf2 or abstf2. Op0 is destination, op1 is source,
3183 op2 is a register containing the sign bit, operation is the
3184 logical operation to be performed. */
3187 alpha_split_tfmode_frobsign (rtx operands
[3], rtx (*operation
) (rtx
, rtx
, rtx
))
3189 rtx high_bit
= operands
[2];
3193 alpha_split_tmode_pair (operands
, TFmode
, false);
3195 /* Detect three flavors of operand overlap. */
3197 if (rtx_equal_p (operands
[0], operands
[2]))
3199 else if (rtx_equal_p (operands
[1], operands
[2]))
3201 if (rtx_equal_p (operands
[0], high_bit
))
3208 emit_move_insn (operands
[0], operands
[2]);
3210 /* ??? If the destination overlaps both source tf and high_bit, then
3211 assume source tf is dead in its entirety and use the other half
3212 for a scratch register. Otherwise "scratch" is just the proper
3213 destination register. */
3214 scratch
= operands
[move
< 2 ? 1 : 3];
3216 emit_insn ((*operation
) (scratch
, high_bit
, operands
[3]));
3220 emit_move_insn (operands
[0], operands
[2]);
3222 emit_move_insn (operands
[1], scratch
);
3226 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
3230 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
3231 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
3232 lda r3,X(r11) lda r3,X+2(r11)
3233 extwl r1,r3,r1 extql r1,r3,r1
3234 extwh r2,r3,r2 extqh r2,r3,r2
3235 or r1.r2.r1 or r1,r2,r1
3238 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
3239 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
3240 lda r3,X(r11) lda r3,X(r11)
3241 extll r1,r3,r1 extll r1,r3,r1
3242 extlh r2,r3,r2 extlh r2,r3,r2
3243 or r1.r2.r1 addl r1,r2,r1
3245 quad: ldq_u r1,X(r11)
3254 alpha_expand_unaligned_load (rtx tgt
, rtx mem
, HOST_WIDE_INT size
,
3255 HOST_WIDE_INT ofs
, int sign
)
3257 rtx meml
, memh
, addr
, extl
, exth
, tmp
, mema
;
3258 enum machine_mode mode
;
3260 if (TARGET_BWX
&& size
== 2)
3262 meml
= adjust_address (mem
, QImode
, ofs
);
3263 memh
= adjust_address (mem
, QImode
, ofs
+1);
3264 extl
= gen_reg_rtx (DImode
);
3265 exth
= gen_reg_rtx (DImode
);
3266 emit_insn (gen_zero_extendqidi2 (extl
, meml
));
3267 emit_insn (gen_zero_extendqidi2 (exth
, memh
));
3268 exth
= expand_simple_binop (DImode
, ASHIFT
, exth
, GEN_INT (8),
3269 NULL
, 1, OPTAB_LIB_WIDEN
);
3270 addr
= expand_simple_binop (DImode
, IOR
, extl
, exth
,
3271 NULL
, 1, OPTAB_LIB_WIDEN
);
3273 if (sign
&& GET_MODE (tgt
) != HImode
)
3275 addr
= gen_lowpart (HImode
, addr
);
3276 emit_insn (gen_extend_insn (tgt
, addr
, GET_MODE (tgt
), HImode
, 0));
3280 if (GET_MODE (tgt
) != DImode
)
3281 addr
= gen_lowpart (GET_MODE (tgt
), addr
);
3282 emit_move_insn (tgt
, addr
);
3287 meml
= gen_reg_rtx (DImode
);
3288 memh
= gen_reg_rtx (DImode
);
3289 addr
= gen_reg_rtx (DImode
);
3290 extl
= gen_reg_rtx (DImode
);
3291 exth
= gen_reg_rtx (DImode
);
3293 mema
= XEXP (mem
, 0);
3294 if (GET_CODE (mema
) == LO_SUM
)
3295 mema
= force_reg (Pmode
, mema
);
3297 /* AND addresses cannot be in any alias set, since they may implicitly
3298 alias surrounding code. Ideally we'd have some alias set that
3299 covered all types except those with alignment 8 or higher. */
3301 tmp
= change_address (mem
, DImode
,
3302 gen_rtx_AND (DImode
,
3303 plus_constant (DImode
, mema
, ofs
),
3305 set_mem_alias_set (tmp
, 0);
3306 emit_move_insn (meml
, tmp
);
3308 tmp
= change_address (mem
, DImode
,
3309 gen_rtx_AND (DImode
,
3310 plus_constant (DImode
, mema
,
3313 set_mem_alias_set (tmp
, 0);
3314 emit_move_insn (memh
, tmp
);
3316 if (sign
&& size
== 2)
3318 emit_move_insn (addr
, plus_constant (Pmode
, mema
, ofs
+2));
3320 emit_insn (gen_extql (extl
, meml
, addr
));
3321 emit_insn (gen_extqh (exth
, memh
, addr
));
3323 /* We must use tgt here for the target. Alpha-vms port fails if we use
3324 addr for the target, because addr is marked as a pointer and combine
3325 knows that pointers are always sign-extended 32-bit values. */
3326 addr
= expand_binop (DImode
, ior_optab
, extl
, exth
, tgt
, 1, OPTAB_WIDEN
);
3327 addr
= expand_binop (DImode
, ashr_optab
, addr
, GEN_INT (48),
3328 addr
, 1, OPTAB_WIDEN
);
3332 emit_move_insn (addr
, plus_constant (Pmode
, mema
, ofs
));
3333 emit_insn (gen_extxl (extl
, meml
, GEN_INT (size
*8), addr
));
3337 emit_insn (gen_extwh (exth
, memh
, addr
));
3341 emit_insn (gen_extlh (exth
, memh
, addr
));
3345 emit_insn (gen_extqh (exth
, memh
, addr
));
3352 addr
= expand_binop (mode
, ior_optab
, gen_lowpart (mode
, extl
),
3353 gen_lowpart (mode
, exth
), gen_lowpart (mode
, tgt
),
3358 emit_move_insn (tgt
, gen_lowpart (GET_MODE (tgt
), addr
));
3361 /* Similarly, use ins and msk instructions to perform unaligned stores. */
3364 alpha_expand_unaligned_store (rtx dst
, rtx src
,
3365 HOST_WIDE_INT size
, HOST_WIDE_INT ofs
)
3367 rtx dstl
, dsth
, addr
, insl
, insh
, meml
, memh
, dsta
;
3369 if (TARGET_BWX
&& size
== 2)
3371 if (src
!= const0_rtx
)
3373 dstl
= gen_lowpart (QImode
, src
);
3374 dsth
= expand_simple_binop (DImode
, LSHIFTRT
, src
, GEN_INT (8),
3375 NULL
, 1, OPTAB_LIB_WIDEN
);
3376 dsth
= gen_lowpart (QImode
, dsth
);
3379 dstl
= dsth
= const0_rtx
;
3381 meml
= adjust_address (dst
, QImode
, ofs
);
3382 memh
= adjust_address (dst
, QImode
, ofs
+1);
3384 emit_move_insn (meml
, dstl
);
3385 emit_move_insn (memh
, dsth
);
3389 dstl
= gen_reg_rtx (DImode
);
3390 dsth
= gen_reg_rtx (DImode
);
3391 insl
= gen_reg_rtx (DImode
);
3392 insh
= gen_reg_rtx (DImode
);
3394 dsta
= XEXP (dst
, 0);
3395 if (GET_CODE (dsta
) == LO_SUM
)
3396 dsta
= force_reg (Pmode
, dsta
);
3398 /* AND addresses cannot be in any alias set, since they may implicitly
3399 alias surrounding code. Ideally we'd have some alias set that
3400 covered all types except those with alignment 8 or higher. */
3402 meml
= change_address (dst
, DImode
,
3403 gen_rtx_AND (DImode
,
3404 plus_constant (DImode
, dsta
, ofs
),
3406 set_mem_alias_set (meml
, 0);
3408 memh
= change_address (dst
, DImode
,
3409 gen_rtx_AND (DImode
,
3410 plus_constant (DImode
, dsta
,
3413 set_mem_alias_set (memh
, 0);
3415 emit_move_insn (dsth
, memh
);
3416 emit_move_insn (dstl
, meml
);
3418 addr
= copy_addr_to_reg (plus_constant (Pmode
, dsta
, ofs
));
3420 if (src
!= CONST0_RTX (GET_MODE (src
)))
3422 emit_insn (gen_insxh (insh
, gen_lowpart (DImode
, src
),
3423 GEN_INT (size
*8), addr
));
3428 emit_insn (gen_inswl (insl
, gen_lowpart (HImode
, src
), addr
));
3431 emit_insn (gen_insll (insl
, gen_lowpart (SImode
, src
), addr
));
3434 emit_insn (gen_insql (insl
, gen_lowpart (DImode
, src
), addr
));
3441 emit_insn (gen_mskxh (dsth
, dsth
, GEN_INT (size
*8), addr
));
3446 emit_insn (gen_mskwl (dstl
, dstl
, addr
));
3449 emit_insn (gen_mskll (dstl
, dstl
, addr
));
3452 emit_insn (gen_mskql (dstl
, dstl
, addr
));
3458 if (src
!= CONST0_RTX (GET_MODE (src
)))
3460 dsth
= expand_binop (DImode
, ior_optab
, insh
, dsth
, dsth
, 0, OPTAB_WIDEN
);
3461 dstl
= expand_binop (DImode
, ior_optab
, insl
, dstl
, dstl
, 0, OPTAB_WIDEN
);
3464 /* Must store high before low for degenerate case of aligned. */
3465 emit_move_insn (memh
, dsth
);
3466 emit_move_insn (meml
, dstl
);
3469 /* The block move code tries to maximize speed by separating loads and
3470 stores at the expense of register pressure: we load all of the data
3471 before we store it back out. There are two secondary effects worth
3472 mentioning, that this speeds copying to/from aligned and unaligned
3473 buffers, and that it makes the code significantly easier to write. */
3475 #define MAX_MOVE_WORDS 8
3477 /* Load an integral number of consecutive unaligned quadwords. */
3480 alpha_expand_unaligned_load_words (rtx
*out_regs
, rtx smem
,
3481 HOST_WIDE_INT words
, HOST_WIDE_INT ofs
)
3483 rtx
const im8
= GEN_INT (-8);
3484 rtx ext_tmps
[MAX_MOVE_WORDS
], data_regs
[MAX_MOVE_WORDS
+1];
3485 rtx sreg
, areg
, tmp
, smema
;
3488 smema
= XEXP (smem
, 0);
3489 if (GET_CODE (smema
) == LO_SUM
)
3490 smema
= force_reg (Pmode
, smema
);
3492 /* Generate all the tmp registers we need. */
3493 for (i
= 0; i
< words
; ++i
)
3495 data_regs
[i
] = out_regs
[i
];
3496 ext_tmps
[i
] = gen_reg_rtx (DImode
);
3498 data_regs
[words
] = gen_reg_rtx (DImode
);
3501 smem
= adjust_address (smem
, GET_MODE (smem
), ofs
);
3503 /* Load up all of the source data. */
3504 for (i
= 0; i
< words
; ++i
)
3506 tmp
= change_address (smem
, DImode
,
3507 gen_rtx_AND (DImode
,
3508 plus_constant (DImode
, smema
, 8*i
),
3510 set_mem_alias_set (tmp
, 0);
3511 emit_move_insn (data_regs
[i
], tmp
);
3514 tmp
= change_address (smem
, DImode
,
3515 gen_rtx_AND (DImode
,
3516 plus_constant (DImode
, smema
,
3519 set_mem_alias_set (tmp
, 0);
3520 emit_move_insn (data_regs
[words
], tmp
);
3522 /* Extract the half-word fragments. Unfortunately DEC decided to make
3523 extxh with offset zero a noop instead of zeroing the register, so
3524 we must take care of that edge condition ourselves with cmov. */
3526 sreg
= copy_addr_to_reg (smema
);
3527 areg
= expand_binop (DImode
, and_optab
, sreg
, GEN_INT (7), NULL
,
3529 for (i
= 0; i
< words
; ++i
)
3531 emit_insn (gen_extql (data_regs
[i
], data_regs
[i
], sreg
));
3532 emit_insn (gen_extqh (ext_tmps
[i
], data_regs
[i
+1], sreg
));
3533 emit_insn (gen_rtx_SET (VOIDmode
, ext_tmps
[i
],
3534 gen_rtx_IF_THEN_ELSE (DImode
,
3535 gen_rtx_EQ (DImode
, areg
,
3537 const0_rtx
, ext_tmps
[i
])));
3540 /* Merge the half-words into whole words. */
3541 for (i
= 0; i
< words
; ++i
)
3543 out_regs
[i
] = expand_binop (DImode
, ior_optab
, data_regs
[i
],
3544 ext_tmps
[i
], data_regs
[i
], 1, OPTAB_WIDEN
);
3548 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
3549 may be NULL to store zeros. */
3552 alpha_expand_unaligned_store_words (rtx
*data_regs
, rtx dmem
,
3553 HOST_WIDE_INT words
, HOST_WIDE_INT ofs
)
3555 rtx
const im8
= GEN_INT (-8);
3556 rtx ins_tmps
[MAX_MOVE_WORDS
];
3557 rtx st_tmp_1
, st_tmp_2
, dreg
;
3558 rtx st_addr_1
, st_addr_2
, dmema
;
3561 dmema
= XEXP (dmem
, 0);
3562 if (GET_CODE (dmema
) == LO_SUM
)
3563 dmema
= force_reg (Pmode
, dmema
);
3565 /* Generate all the tmp registers we need. */
3566 if (data_regs
!= NULL
)
3567 for (i
= 0; i
< words
; ++i
)
3568 ins_tmps
[i
] = gen_reg_rtx(DImode
);
3569 st_tmp_1
= gen_reg_rtx(DImode
);
3570 st_tmp_2
= gen_reg_rtx(DImode
);
3573 dmem
= adjust_address (dmem
, GET_MODE (dmem
), ofs
);
3575 st_addr_2
= change_address (dmem
, DImode
,
3576 gen_rtx_AND (DImode
,
3577 plus_constant (DImode
, dmema
,
3580 set_mem_alias_set (st_addr_2
, 0);
3582 st_addr_1
= change_address (dmem
, DImode
,
3583 gen_rtx_AND (DImode
, dmema
, im8
));
3584 set_mem_alias_set (st_addr_1
, 0);
3586 /* Load up the destination end bits. */
3587 emit_move_insn (st_tmp_2
, st_addr_2
);
3588 emit_move_insn (st_tmp_1
, st_addr_1
);
3590 /* Shift the input data into place. */
3591 dreg
= copy_addr_to_reg (dmema
);
3592 if (data_regs
!= NULL
)
3594 for (i
= words
-1; i
>= 0; --i
)
3596 emit_insn (gen_insqh (ins_tmps
[i
], data_regs
[i
], dreg
));
3597 emit_insn (gen_insql (data_regs
[i
], data_regs
[i
], dreg
));
3599 for (i
= words
-1; i
> 0; --i
)
3601 ins_tmps
[i
-1] = expand_binop (DImode
, ior_optab
, data_regs
[i
],
3602 ins_tmps
[i
-1], ins_tmps
[i
-1], 1,
3607 /* Split and merge the ends with the destination data. */
3608 emit_insn (gen_mskqh (st_tmp_2
, st_tmp_2
, dreg
));
3609 emit_insn (gen_mskql (st_tmp_1
, st_tmp_1
, dreg
));
3611 if (data_regs
!= NULL
)
3613 st_tmp_2
= expand_binop (DImode
, ior_optab
, st_tmp_2
, ins_tmps
[words
-1],
3614 st_tmp_2
, 1, OPTAB_WIDEN
);
3615 st_tmp_1
= expand_binop (DImode
, ior_optab
, st_tmp_1
, data_regs
[0],
3616 st_tmp_1
, 1, OPTAB_WIDEN
);
3620 emit_move_insn (st_addr_2
, st_tmp_2
);
3621 for (i
= words
-1; i
> 0; --i
)
3623 rtx tmp
= change_address (dmem
, DImode
,
3624 gen_rtx_AND (DImode
,
3625 plus_constant (DImode
,
3628 set_mem_alias_set (tmp
, 0);
3629 emit_move_insn (tmp
, data_regs
? ins_tmps
[i
-1] : const0_rtx
);
3631 emit_move_insn (st_addr_1
, st_tmp_1
);
3635 /* Expand string/block move operations.
3637 operands[0] is the pointer to the destination.
3638 operands[1] is the pointer to the source.
3639 operands[2] is the number of bytes to move.
3640 operands[3] is the alignment. */
3643 alpha_expand_block_move (rtx operands
[])
3645 rtx bytes_rtx
= operands
[2];
3646 rtx align_rtx
= operands
[3];
3647 HOST_WIDE_INT orig_bytes
= INTVAL (bytes_rtx
);
3648 HOST_WIDE_INT bytes
= orig_bytes
;
3649 HOST_WIDE_INT src_align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
3650 HOST_WIDE_INT dst_align
= src_align
;
3651 rtx orig_src
= operands
[1];
3652 rtx orig_dst
= operands
[0];
3653 rtx data_regs
[2 * MAX_MOVE_WORDS
+ 16];
3655 unsigned int i
, words
, ofs
, nregs
= 0;
3657 if (orig_bytes
<= 0)
3659 else if (orig_bytes
> MAX_MOVE_WORDS
* UNITS_PER_WORD
)
3662 /* Look for additional alignment information from recorded register info. */
3664 tmp
= XEXP (orig_src
, 0);
3666 src_align
= MAX (src_align
, REGNO_POINTER_ALIGN (REGNO (tmp
)));
3667 else if (GET_CODE (tmp
) == PLUS
3668 && REG_P (XEXP (tmp
, 0))
3669 && CONST_INT_P (XEXP (tmp
, 1)))
3671 unsigned HOST_WIDE_INT c
= INTVAL (XEXP (tmp
, 1));
3672 unsigned int a
= REGNO_POINTER_ALIGN (REGNO (XEXP (tmp
, 0)));
3676 if (a
>= 64 && c
% 8 == 0)
3678 else if (a
>= 32 && c
% 4 == 0)
3680 else if (a
>= 16 && c
% 2 == 0)
3685 tmp
= XEXP (orig_dst
, 0);
3687 dst_align
= MAX (dst_align
, REGNO_POINTER_ALIGN (REGNO (tmp
)));
3688 else if (GET_CODE (tmp
) == PLUS
3689 && REG_P (XEXP (tmp
, 0))
3690 && CONST_INT_P (XEXP (tmp
, 1)))
3692 unsigned HOST_WIDE_INT c
= INTVAL (XEXP (tmp
, 1));
3693 unsigned int a
= REGNO_POINTER_ALIGN (REGNO (XEXP (tmp
, 0)));
3697 if (a
>= 64 && c
% 8 == 0)
3699 else if (a
>= 32 && c
% 4 == 0)
3701 else if (a
>= 16 && c
% 2 == 0)
3707 if (src_align
>= 64 && bytes
>= 8)
3711 for (i
= 0; i
< words
; ++i
)
3712 data_regs
[nregs
+ i
] = gen_reg_rtx (DImode
);
3714 for (i
= 0; i
< words
; ++i
)
3715 emit_move_insn (data_regs
[nregs
+ i
],
3716 adjust_address (orig_src
, DImode
, ofs
+ i
* 8));
3723 if (src_align
>= 32 && bytes
>= 4)
3727 for (i
= 0; i
< words
; ++i
)
3728 data_regs
[nregs
+ i
] = gen_reg_rtx (SImode
);
3730 for (i
= 0; i
< words
; ++i
)
3731 emit_move_insn (data_regs
[nregs
+ i
],
3732 adjust_address (orig_src
, SImode
, ofs
+ i
* 4));
3743 for (i
= 0; i
< words
+1; ++i
)
3744 data_regs
[nregs
+ i
] = gen_reg_rtx (DImode
);
3746 alpha_expand_unaligned_load_words (data_regs
+ nregs
, orig_src
,
3754 if (! TARGET_BWX
&& bytes
>= 4)
3756 data_regs
[nregs
++] = tmp
= gen_reg_rtx (SImode
);
3757 alpha_expand_unaligned_load (tmp
, orig_src
, 4, ofs
, 0);
3764 if (src_align
>= 16)
3767 data_regs
[nregs
++] = tmp
= gen_reg_rtx (HImode
);
3768 emit_move_insn (tmp
, adjust_address (orig_src
, HImode
, ofs
));
3771 } while (bytes
>= 2);
3773 else if (! TARGET_BWX
)
3775 data_regs
[nregs
++] = tmp
= gen_reg_rtx (HImode
);
3776 alpha_expand_unaligned_load (tmp
, orig_src
, 2, ofs
, 0);
3784 data_regs
[nregs
++] = tmp
= gen_reg_rtx (QImode
);
3785 emit_move_insn (tmp
, adjust_address (orig_src
, QImode
, ofs
));
3790 gcc_assert (nregs
<= ARRAY_SIZE (data_regs
));
3792 /* Now save it back out again. */
3796 /* Write out the data in whatever chunks reading the source allowed. */
3797 if (dst_align
>= 64)
3799 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == DImode
)
3801 emit_move_insn (adjust_address (orig_dst
, DImode
, ofs
),
3808 if (dst_align
>= 32)
3810 /* If the source has remaining DImode regs, write them out in
3812 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == DImode
)
3814 tmp
= expand_binop (DImode
, lshr_optab
, data_regs
[i
], GEN_INT (32),
3815 NULL_RTX
, 1, OPTAB_WIDEN
);
3817 emit_move_insn (adjust_address (orig_dst
, SImode
, ofs
),
3818 gen_lowpart (SImode
, data_regs
[i
]));
3819 emit_move_insn (adjust_address (orig_dst
, SImode
, ofs
+ 4),
3820 gen_lowpart (SImode
, tmp
));
3825 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == SImode
)
3827 emit_move_insn (adjust_address (orig_dst
, SImode
, ofs
),
3834 if (i
< nregs
&& GET_MODE (data_regs
[i
]) == DImode
)
3836 /* Write out a remaining block of words using unaligned methods. */
3838 for (words
= 1; i
+ words
< nregs
; words
++)
3839 if (GET_MODE (data_regs
[i
+ words
]) != DImode
)
3843 alpha_expand_unaligned_store (orig_dst
, data_regs
[i
], 8, ofs
);
3845 alpha_expand_unaligned_store_words (data_regs
+ i
, orig_dst
,
3852 /* Due to the above, this won't be aligned. */
3853 /* ??? If we have more than one of these, consider constructing full
3854 words in registers and using alpha_expand_unaligned_store_words. */
3855 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == SImode
)
3857 alpha_expand_unaligned_store (orig_dst
, data_regs
[i
], 4, ofs
);
3862 if (dst_align
>= 16)
3863 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == HImode
)
3865 emit_move_insn (adjust_address (orig_dst
, HImode
, ofs
), data_regs
[i
]);
3870 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == HImode
)
3872 alpha_expand_unaligned_store (orig_dst
, data_regs
[i
], 2, ofs
);
3877 /* The remainder must be byte copies. */
3880 gcc_assert (GET_MODE (data_regs
[i
]) == QImode
);
3881 emit_move_insn (adjust_address (orig_dst
, QImode
, ofs
), data_regs
[i
]);
3890 alpha_expand_block_clear (rtx operands
[])
3892 rtx bytes_rtx
= operands
[1];
3893 rtx align_rtx
= operands
[3];
3894 HOST_WIDE_INT orig_bytes
= INTVAL (bytes_rtx
);
3895 HOST_WIDE_INT bytes
= orig_bytes
;
3896 HOST_WIDE_INT align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
3897 HOST_WIDE_INT alignofs
= 0;
3898 rtx orig_dst
= operands
[0];
3900 int i
, words
, ofs
= 0;
3902 if (orig_bytes
<= 0)
3904 if (orig_bytes
> MAX_MOVE_WORDS
* UNITS_PER_WORD
)
3907 /* Look for stricter alignment. */
3908 tmp
= XEXP (orig_dst
, 0);
3910 align
= MAX (align
, REGNO_POINTER_ALIGN (REGNO (tmp
)));
3911 else if (GET_CODE (tmp
) == PLUS
3912 && REG_P (XEXP (tmp
, 0))
3913 && CONST_INT_P (XEXP (tmp
, 1)))
3915 HOST_WIDE_INT c
= INTVAL (XEXP (tmp
, 1));
3916 int a
= REGNO_POINTER_ALIGN (REGNO (XEXP (tmp
, 0)));
3921 align
= a
, alignofs
= 8 - c
% 8;
3923 align
= a
, alignofs
= 4 - c
% 4;
3925 align
= a
, alignofs
= 2 - c
% 2;
3929 /* Handle an unaligned prefix first. */
3933 #if HOST_BITS_PER_WIDE_INT >= 64
3934 /* Given that alignofs is bounded by align, the only time BWX could
3935 generate three stores is for a 7 byte fill. Prefer two individual
3936 stores over a load/mask/store sequence. */
3937 if ((!TARGET_BWX
|| alignofs
== 7)
3939 && !(alignofs
== 4 && bytes
>= 4))
3941 enum machine_mode mode
= (align
>= 64 ? DImode
: SImode
);
3942 int inv_alignofs
= (align
>= 64 ? 8 : 4) - alignofs
;
3946 mem
= adjust_address (orig_dst
, mode
, ofs
- inv_alignofs
);
3947 set_mem_alias_set (mem
, 0);
3949 mask
= ~(~(HOST_WIDE_INT
)0 << (inv_alignofs
* 8));
3950 if (bytes
< alignofs
)
3952 mask
|= ~(HOST_WIDE_INT
)0 << ((inv_alignofs
+ bytes
) * 8);
3963 tmp
= expand_binop (mode
, and_optab
, mem
, GEN_INT (mask
),
3964 NULL_RTX
, 1, OPTAB_WIDEN
);
3966 emit_move_insn (mem
, tmp
);
3970 if (TARGET_BWX
&& (alignofs
& 1) && bytes
>= 1)
3972 emit_move_insn (adjust_address (orig_dst
, QImode
, ofs
), const0_rtx
);
3977 if (TARGET_BWX
&& align
>= 16 && (alignofs
& 3) == 2 && bytes
>= 2)
3979 emit_move_insn (adjust_address (orig_dst
, HImode
, ofs
), const0_rtx
);
3984 if (alignofs
== 4 && bytes
>= 4)
3986 emit_move_insn (adjust_address (orig_dst
, SImode
, ofs
), const0_rtx
);
3992 /* If we've not used the extra lead alignment information by now,
3993 we won't be able to. Downgrade align to match what's left over. */
3996 alignofs
= alignofs
& -alignofs
;
3997 align
= MIN (align
, alignofs
* BITS_PER_UNIT
);
4001 /* Handle a block of contiguous long-words. */
4003 if (align
>= 64 && bytes
>= 8)
4007 for (i
= 0; i
< words
; ++i
)
4008 emit_move_insn (adjust_address (orig_dst
, DImode
, ofs
+ i
* 8),
4015 /* If the block is large and appropriately aligned, emit a single
4016 store followed by a sequence of stq_u insns. */
4018 if (align
>= 32 && bytes
> 16)
4022 emit_move_insn (adjust_address (orig_dst
, SImode
, ofs
), const0_rtx
);
4026 orig_dsta
= XEXP (orig_dst
, 0);
4027 if (GET_CODE (orig_dsta
) == LO_SUM
)
4028 orig_dsta
= force_reg (Pmode
, orig_dsta
);
4031 for (i
= 0; i
< words
; ++i
)
4034 = change_address (orig_dst
, DImode
,
4035 gen_rtx_AND (DImode
,
4036 plus_constant (DImode
, orig_dsta
,
4039 set_mem_alias_set (mem
, 0);
4040 emit_move_insn (mem
, const0_rtx
);
4043 /* Depending on the alignment, the first stq_u may have overlapped
4044 with the initial stl, which means that the last stq_u didn't
4045 write as much as it would appear. Leave those questionable bytes
4047 bytes
-= words
* 8 - 4;
4048 ofs
+= words
* 8 - 4;
4051 /* Handle a smaller block of aligned words. */
4053 if ((align
>= 64 && bytes
== 4)
4054 || (align
== 32 && bytes
>= 4))
4058 for (i
= 0; i
< words
; ++i
)
4059 emit_move_insn (adjust_address (orig_dst
, SImode
, ofs
+ i
* 4),
4066 /* An unaligned block uses stq_u stores for as many as possible. */
4072 alpha_expand_unaligned_store_words (NULL
, orig_dst
, words
, ofs
);
4078 /* Next clean up any trailing pieces. */
4080 #if HOST_BITS_PER_WIDE_INT >= 64
4081 /* Count the number of bits in BYTES for which aligned stores could
4084 for (i
= (TARGET_BWX
? 1 : 4); i
* BITS_PER_UNIT
<= align
; i
<<= 1)
4088 /* If we have appropriate alignment (and it wouldn't take too many
4089 instructions otherwise), mask out the bytes we need. */
4090 if (TARGET_BWX
? words
> 2 : bytes
> 0)
4097 mem
= adjust_address (orig_dst
, DImode
, ofs
);
4098 set_mem_alias_set (mem
, 0);
4100 mask
= ~(HOST_WIDE_INT
)0 << (bytes
* 8);
4102 tmp
= expand_binop (DImode
, and_optab
, mem
, GEN_INT (mask
),
4103 NULL_RTX
, 1, OPTAB_WIDEN
);
4105 emit_move_insn (mem
, tmp
);
4108 else if (align
>= 32 && bytes
< 4)
4113 mem
= adjust_address (orig_dst
, SImode
, ofs
);
4114 set_mem_alias_set (mem
, 0);
4116 mask
= ~(HOST_WIDE_INT
)0 << (bytes
* 8);
4118 tmp
= expand_binop (SImode
, and_optab
, mem
, GEN_INT (mask
),
4119 NULL_RTX
, 1, OPTAB_WIDEN
);
4121 emit_move_insn (mem
, tmp
);
4127 if (!TARGET_BWX
&& bytes
>= 4)
4129 alpha_expand_unaligned_store (orig_dst
, const0_rtx
, 4, ofs
);
4139 emit_move_insn (adjust_address (orig_dst
, HImode
, ofs
),
4143 } while (bytes
>= 2);
4145 else if (! TARGET_BWX
)
4147 alpha_expand_unaligned_store (orig_dst
, const0_rtx
, 2, ofs
);
4155 emit_move_insn (adjust_address (orig_dst
, QImode
, ofs
), const0_rtx
);
4163 /* Returns a mask so that zap(x, value) == x & mask. */
4166 alpha_expand_zap_mask (HOST_WIDE_INT value
)
4171 if (HOST_BITS_PER_WIDE_INT
>= 64)
4173 HOST_WIDE_INT mask
= 0;
4175 for (i
= 7; i
>= 0; --i
)
4178 if (!((value
>> i
) & 1))
4182 result
= gen_int_mode (mask
, DImode
);
4186 HOST_WIDE_INT mask_lo
= 0, mask_hi
= 0;
4188 gcc_assert (HOST_BITS_PER_WIDE_INT
== 32);
4190 for (i
= 7; i
>= 4; --i
)
4193 if (!((value
>> i
) & 1))
4197 for (i
= 3; i
>= 0; --i
)
4200 if (!((value
>> i
) & 1))
4204 result
= immed_double_const (mask_lo
, mask_hi
, DImode
);
4211 alpha_expand_builtin_vector_binop (rtx (*gen
) (rtx
, rtx
, rtx
),
4212 enum machine_mode mode
,
4213 rtx op0
, rtx op1
, rtx op2
)
4215 op0
= gen_lowpart (mode
, op0
);
4217 if (op1
== const0_rtx
)
4218 op1
= CONST0_RTX (mode
);
4220 op1
= gen_lowpart (mode
, op1
);
4222 if (op2
== const0_rtx
)
4223 op2
= CONST0_RTX (mode
);
4225 op2
= gen_lowpart (mode
, op2
);
4227 emit_insn ((*gen
) (op0
, op1
, op2
));
4230 /* A subroutine of the atomic operation splitters. Jump to LABEL if
4231 COND is true. Mark the jump as unlikely to be taken. */
4234 emit_unlikely_jump (rtx cond
, rtx label
)
4236 int very_unlikely
= REG_BR_PROB_BASE
/ 100 - 1;
4239 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, label
, pc_rtx
);
4240 x
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, x
));
4241 add_int_reg_note (x
, REG_BR_PROB
, very_unlikely
);
4244 /* A subroutine of the atomic operation splitters. Emit a load-locked
4245 instruction in MODE. */
4248 emit_load_locked (enum machine_mode mode
, rtx reg
, rtx mem
)
4250 rtx (*fn
) (rtx
, rtx
) = NULL
;
4252 fn
= gen_load_locked_si
;
4253 else if (mode
== DImode
)
4254 fn
= gen_load_locked_di
;
4255 emit_insn (fn (reg
, mem
));
4258 /* A subroutine of the atomic operation splitters. Emit a store-conditional
4259 instruction in MODE. */
4262 emit_store_conditional (enum machine_mode mode
, rtx res
, rtx mem
, rtx val
)
4264 rtx (*fn
) (rtx
, rtx
, rtx
) = NULL
;
4266 fn
= gen_store_conditional_si
;
4267 else if (mode
== DImode
)
4268 fn
= gen_store_conditional_di
;
4269 emit_insn (fn (res
, mem
, val
));
4272 /* Subroutines of the atomic operation splitters. Emit barriers
4273 as needed for the memory MODEL. */
4276 alpha_pre_atomic_barrier (enum memmodel model
)
4278 if (need_atomic_barrier_p (model
, true))
4279 emit_insn (gen_memory_barrier ());
4283 alpha_post_atomic_barrier (enum memmodel model
)
4285 if (need_atomic_barrier_p (model
, false))
4286 emit_insn (gen_memory_barrier ());
4289 /* A subroutine of the atomic operation splitters. Emit an insxl
4290 instruction in MODE. */
4293 emit_insxl (enum machine_mode mode
, rtx op1
, rtx op2
)
4295 rtx ret
= gen_reg_rtx (DImode
);
4296 rtx (*fn
) (rtx
, rtx
, rtx
);
4316 op1
= force_reg (mode
, op1
);
4317 emit_insn (fn (ret
, op1
, op2
));
4322 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
4323 to perform. MEM is the memory on which to operate. VAL is the second
4324 operand of the binary operator. BEFORE and AFTER are optional locations to
4325 return the value of MEM either before of after the operation. SCRATCH is
4326 a scratch register. */
4329 alpha_split_atomic_op (enum rtx_code code
, rtx mem
, rtx val
, rtx before
,
4330 rtx after
, rtx scratch
, enum memmodel model
)
4332 enum machine_mode mode
= GET_MODE (mem
);
4333 rtx label
, x
, cond
= gen_rtx_REG (DImode
, REGNO (scratch
));
4335 alpha_pre_atomic_barrier (model
);
4337 label
= gen_label_rtx ();
4339 label
= gen_rtx_LABEL_REF (DImode
, label
);
4343 emit_load_locked (mode
, before
, mem
);
4347 x
= gen_rtx_AND (mode
, before
, val
);
4348 emit_insn (gen_rtx_SET (VOIDmode
, val
, x
));
4350 x
= gen_rtx_NOT (mode
, val
);
4353 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
4355 emit_insn (gen_rtx_SET (VOIDmode
, after
, copy_rtx (x
)));
4356 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, x
));
4358 emit_store_conditional (mode
, cond
, mem
, scratch
);
4360 x
= gen_rtx_EQ (DImode
, cond
, const0_rtx
);
4361 emit_unlikely_jump (x
, label
);
4363 alpha_post_atomic_barrier (model
);
4366 /* Expand a compare and swap operation. */
4369 alpha_split_compare_and_swap (rtx operands
[])
4371 rtx cond
, retval
, mem
, oldval
, newval
;
4373 enum memmodel mod_s
, mod_f
;
4374 enum machine_mode mode
;
4375 rtx label1
, label2
, x
;
4378 retval
= operands
[1];
4380 oldval
= operands
[3];
4381 newval
= operands
[4];
4382 is_weak
= (operands
[5] != const0_rtx
);
4383 mod_s
= (enum memmodel
) INTVAL (operands
[6]);
4384 mod_f
= (enum memmodel
) INTVAL (operands
[7]);
4385 mode
= GET_MODE (mem
);
4387 alpha_pre_atomic_barrier (mod_s
);
4392 label1
= gen_rtx_LABEL_REF (DImode
, gen_label_rtx ());
4393 emit_label (XEXP (label1
, 0));
4395 label2
= gen_rtx_LABEL_REF (DImode
, gen_label_rtx ());
4397 emit_load_locked (mode
, retval
, mem
);
4399 x
= gen_lowpart (DImode
, retval
);
4400 if (oldval
== const0_rtx
)
4402 emit_move_insn (cond
, const0_rtx
);
4403 x
= gen_rtx_NE (DImode
, x
, const0_rtx
);
4407 x
= gen_rtx_EQ (DImode
, x
, oldval
);
4408 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
4409 x
= gen_rtx_EQ (DImode
, cond
, const0_rtx
);
4411 emit_unlikely_jump (x
, label2
);
4413 emit_move_insn (cond
, newval
);
4414 emit_store_conditional (mode
, cond
, mem
, gen_lowpart (mode
, cond
));
4418 x
= gen_rtx_EQ (DImode
, cond
, const0_rtx
);
4419 emit_unlikely_jump (x
, label1
);
4422 if (mod_f
!= MEMMODEL_RELAXED
)
4423 emit_label (XEXP (label2
, 0));
4425 alpha_post_atomic_barrier (mod_s
);
4427 if (mod_f
== MEMMODEL_RELAXED
)
4428 emit_label (XEXP (label2
, 0));
4432 alpha_expand_compare_and_swap_12 (rtx operands
[])
4434 rtx cond
, dst
, mem
, oldval
, newval
, is_weak
, mod_s
, mod_f
;
4435 enum machine_mode mode
;
4436 rtx addr
, align
, wdst
;
4437 rtx (*gen
) (rtx
, rtx
, rtx
, rtx
, rtx
, rtx
, rtx
, rtx
, rtx
);
4442 oldval
= operands
[3];
4443 newval
= operands
[4];
4444 is_weak
= operands
[5];
4445 mod_s
= operands
[6];
4446 mod_f
= operands
[7];
4447 mode
= GET_MODE (mem
);
4449 /* We forced the address into a register via mem_noofs_operand. */
4450 addr
= XEXP (mem
, 0);
4451 gcc_assert (register_operand (addr
, DImode
));
4453 align
= expand_simple_binop (Pmode
, AND
, addr
, GEN_INT (-8),
4454 NULL_RTX
, 1, OPTAB_DIRECT
);
4456 oldval
= convert_modes (DImode
, mode
, oldval
, 1);
4458 if (newval
!= const0_rtx
)
4459 newval
= emit_insxl (mode
, newval
, addr
);
4461 wdst
= gen_reg_rtx (DImode
);
4463 gen
= gen_atomic_compare_and_swapqi_1
;
4465 gen
= gen_atomic_compare_and_swaphi_1
;
4466 emit_insn (gen (cond
, wdst
, mem
, oldval
, newval
, align
,
4467 is_weak
, mod_s
, mod_f
));
4469 emit_move_insn (dst
, gen_lowpart (mode
, wdst
));
4473 alpha_split_compare_and_swap_12 (rtx operands
[])
4475 rtx cond
, dest
, orig_mem
, oldval
, newval
, align
, scratch
;
4476 enum machine_mode mode
;
4478 enum memmodel mod_s
, mod_f
;
4479 rtx label1
, label2
, mem
, addr
, width
, mask
, x
;
4483 orig_mem
= operands
[2];
4484 oldval
= operands
[3];
4485 newval
= operands
[4];
4486 align
= operands
[5];
4487 is_weak
= (operands
[6] != const0_rtx
);
4488 mod_s
= (enum memmodel
) INTVAL (operands
[7]);
4489 mod_f
= (enum memmodel
) INTVAL (operands
[8]);
4490 scratch
= operands
[9];
4491 mode
= GET_MODE (orig_mem
);
4492 addr
= XEXP (orig_mem
, 0);
4494 mem
= gen_rtx_MEM (DImode
, align
);
4495 MEM_VOLATILE_P (mem
) = MEM_VOLATILE_P (orig_mem
);
4496 if (MEM_ALIAS_SET (orig_mem
) == ALIAS_SET_MEMORY_BARRIER
)
4497 set_mem_alias_set (mem
, ALIAS_SET_MEMORY_BARRIER
);
4499 alpha_pre_atomic_barrier (mod_s
);
4504 label1
= gen_rtx_LABEL_REF (DImode
, gen_label_rtx ());
4505 emit_label (XEXP (label1
, 0));
4507 label2
= gen_rtx_LABEL_REF (DImode
, gen_label_rtx ());
4509 emit_load_locked (DImode
, scratch
, mem
);
4511 width
= GEN_INT (GET_MODE_BITSIZE (mode
));
4512 mask
= GEN_INT (mode
== QImode
? 0xff : 0xffff);
4513 emit_insn (gen_extxl (dest
, scratch
, width
, addr
));
4515 if (oldval
== const0_rtx
)
4517 emit_move_insn (cond
, const0_rtx
);
4518 x
= gen_rtx_NE (DImode
, dest
, const0_rtx
);
4522 x
= gen_rtx_EQ (DImode
, dest
, oldval
);
4523 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
4524 x
= gen_rtx_EQ (DImode
, cond
, const0_rtx
);
4526 emit_unlikely_jump (x
, label2
);
4528 emit_insn (gen_mskxl (cond
, scratch
, mask
, addr
));
4530 if (newval
!= const0_rtx
)
4531 emit_insn (gen_iordi3 (cond
, cond
, newval
));
4533 emit_store_conditional (DImode
, cond
, mem
, cond
);
4537 x
= gen_rtx_EQ (DImode
, cond
, const0_rtx
);
4538 emit_unlikely_jump (x
, label1
);
4541 if (mod_f
!= MEMMODEL_RELAXED
)
4542 emit_label (XEXP (label2
, 0));
4544 alpha_post_atomic_barrier (mod_s
);
4546 if (mod_f
== MEMMODEL_RELAXED
)
4547 emit_label (XEXP (label2
, 0));
4550 /* Expand an atomic exchange operation. */
4553 alpha_split_atomic_exchange (rtx operands
[])
4555 rtx retval
, mem
, val
, scratch
;
4556 enum memmodel model
;
4557 enum machine_mode mode
;
4560 retval
= operands
[0];
4563 model
= (enum memmodel
) INTVAL (operands
[3]);
4564 scratch
= operands
[4];
4565 mode
= GET_MODE (mem
);
4566 cond
= gen_lowpart (DImode
, scratch
);
4568 alpha_pre_atomic_barrier (model
);
4570 label
= gen_rtx_LABEL_REF (DImode
, gen_label_rtx ());
4571 emit_label (XEXP (label
, 0));
4573 emit_load_locked (mode
, retval
, mem
);
4574 emit_move_insn (scratch
, val
);
4575 emit_store_conditional (mode
, cond
, mem
, scratch
);
4577 x
= gen_rtx_EQ (DImode
, cond
, const0_rtx
);
4578 emit_unlikely_jump (x
, label
);
4580 alpha_post_atomic_barrier (model
);
4584 alpha_expand_atomic_exchange_12 (rtx operands
[])
4586 rtx dst
, mem
, val
, model
;
4587 enum machine_mode mode
;
4588 rtx addr
, align
, wdst
;
4589 rtx (*gen
) (rtx
, rtx
, rtx
, rtx
, rtx
);
4594 model
= operands
[3];
4595 mode
= GET_MODE (mem
);
4597 /* We forced the address into a register via mem_noofs_operand. */
4598 addr
= XEXP (mem
, 0);
4599 gcc_assert (register_operand (addr
, DImode
));
4601 align
= expand_simple_binop (Pmode
, AND
, addr
, GEN_INT (-8),
4602 NULL_RTX
, 1, OPTAB_DIRECT
);
4604 /* Insert val into the correct byte location within the word. */
4605 if (val
!= const0_rtx
)
4606 val
= emit_insxl (mode
, val
, addr
);
4608 wdst
= gen_reg_rtx (DImode
);
4610 gen
= gen_atomic_exchangeqi_1
;
4612 gen
= gen_atomic_exchangehi_1
;
4613 emit_insn (gen (wdst
, mem
, val
, align
, model
));
4615 emit_move_insn (dst
, gen_lowpart (mode
, wdst
));
4619 alpha_split_atomic_exchange_12 (rtx operands
[])
4621 rtx dest
, orig_mem
, addr
, val
, align
, scratch
;
4622 rtx label
, mem
, width
, mask
, x
;
4623 enum machine_mode mode
;
4624 enum memmodel model
;
4627 orig_mem
= operands
[1];
4629 align
= operands
[3];
4630 model
= (enum memmodel
) INTVAL (operands
[4]);
4631 scratch
= operands
[5];
4632 mode
= GET_MODE (orig_mem
);
4633 addr
= XEXP (orig_mem
, 0);
4635 mem
= gen_rtx_MEM (DImode
, align
);
4636 MEM_VOLATILE_P (mem
) = MEM_VOLATILE_P (orig_mem
);
4637 if (MEM_ALIAS_SET (orig_mem
) == ALIAS_SET_MEMORY_BARRIER
)
4638 set_mem_alias_set (mem
, ALIAS_SET_MEMORY_BARRIER
);
4640 alpha_pre_atomic_barrier (model
);
4642 label
= gen_rtx_LABEL_REF (DImode
, gen_label_rtx ());
4643 emit_label (XEXP (label
, 0));
4645 emit_load_locked (DImode
, scratch
, mem
);
4647 width
= GEN_INT (GET_MODE_BITSIZE (mode
));
4648 mask
= GEN_INT (mode
== QImode
? 0xff : 0xffff);
4649 emit_insn (gen_extxl (dest
, scratch
, width
, addr
));
4650 emit_insn (gen_mskxl (scratch
, scratch
, mask
, addr
));
4651 if (val
!= const0_rtx
)
4652 emit_insn (gen_iordi3 (scratch
, scratch
, val
));
4654 emit_store_conditional (DImode
, scratch
, mem
, scratch
);
4656 x
= gen_rtx_EQ (DImode
, scratch
, const0_rtx
);
4657 emit_unlikely_jump (x
, label
);
4659 alpha_post_atomic_barrier (model
);
4662 /* Adjust the cost of a scheduling dependency. Return the new cost of
4663 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
4666 alpha_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
4668 enum attr_type dep_insn_type
;
4670 /* If the dependence is an anti-dependence, there is no cost. For an
4671 output dependence, there is sometimes a cost, but it doesn't seem
4672 worth handling those few cases. */
4673 if (REG_NOTE_KIND (link
) != 0)
4676 /* If we can't recognize the insns, we can't really do anything. */
4677 if (recog_memoized (insn
) < 0 || recog_memoized (dep_insn
) < 0)
4680 dep_insn_type
= get_attr_type (dep_insn
);
4682 /* Bring in the user-defined memory latency. */
4683 if (dep_insn_type
== TYPE_ILD
4684 || dep_insn_type
== TYPE_FLD
4685 || dep_insn_type
== TYPE_LDSYM
)
4686 cost
+= alpha_memory_latency
-1;
4688 /* Everything else handled in DFA bypasses now. */
4693 /* The number of instructions that can be issued per cycle. */
4696 alpha_issue_rate (void)
4698 return (alpha_tune
== PROCESSOR_EV4
? 2 : 4);
4701 /* How many alternative schedules to try. This should be as wide as the
4702 scheduling freedom in the DFA, but no wider. Making this value too
4703 large results extra work for the scheduler.
4705 For EV4, loads can be issued to either IB0 or IB1, thus we have 2
4706 alternative schedules. For EV5, we can choose between E0/E1 and
4707 FA/FM. For EV6, an arithmetic insn can be issued to U0/U1/L0/L1. */
4710 alpha_multipass_dfa_lookahead (void)
4712 return (alpha_tune
== PROCESSOR_EV6
? 4 : 2);
4715 /* Machine-specific function data. */
4717 struct GTY(()) alpha_links
;
4719 struct GTY(()) machine_function
4722 const char *some_ld_name
;
4724 /* For flag_reorder_blocks_and_partition. */
4727 /* For VMS condition handlers. */
4728 bool uses_condition_handler
;
4730 /* Linkage entries. */
4731 splay_tree
GTY ((param1_is (char *), param2_is (struct alpha_links
*)))
4735 /* How to allocate a 'struct machine_function'. */
4737 static struct machine_function
*
4738 alpha_init_machine_status (void)
4740 return ggc_alloc_cleared_machine_function ();
4743 /* Support for frame based VMS condition handlers. */
4745 /* A VMS condition handler may be established for a function with a call to
4746 __builtin_establish_vms_condition_handler, and cancelled with a call to
4747 __builtin_revert_vms_condition_handler.
4749 The VMS Condition Handling Facility knows about the existence of a handler
4750 from the procedure descriptor .handler field. As the VMS native compilers,
4751 we store the user specified handler's address at a fixed location in the
4752 stack frame and point the procedure descriptor at a common wrapper which
4753 fetches the real handler's address and issues an indirect call.
4755 The indirection wrapper is "__gcc_shell_handler", provided by libgcc.
4757 We force the procedure kind to PT_STACK, and the fixed frame location is
4758 fp+8, just before the register save area. We use the handler_data field in
4759 the procedure descriptor to state the fp offset at which the installed
4760 handler address can be found. */
4762 #define VMS_COND_HANDLER_FP_OFFSET 8
4764 /* Expand code to store the currently installed user VMS condition handler
4765 into TARGET and install HANDLER as the new condition handler. */
4768 alpha_expand_builtin_establish_vms_condition_handler (rtx target
, rtx handler
)
4770 rtx handler_slot_address
= plus_constant (Pmode
, hard_frame_pointer_rtx
,
4771 VMS_COND_HANDLER_FP_OFFSET
);
4774 = gen_rtx_MEM (DImode
, handler_slot_address
);
4776 emit_move_insn (target
, handler_slot
);
4777 emit_move_insn (handler_slot
, handler
);
4779 /* Notify the start/prologue/epilogue emitters that the condition handler
4780 slot is needed. In addition to reserving the slot space, this will force
4781 the procedure kind to PT_STACK so ensure that the hard_frame_pointer_rtx
4782 use above is correct. */
4783 cfun
->machine
->uses_condition_handler
= true;
4786 /* Expand code to store the current VMS condition handler into TARGET and
4790 alpha_expand_builtin_revert_vms_condition_handler (rtx target
)
4792 /* We implement this by establishing a null condition handler, with the tiny
4793 side effect of setting uses_condition_handler. This is a little bit
4794 pessimistic if no actual builtin_establish call is ever issued, which is
4795 not a real problem and expected never to happen anyway. */
4797 alpha_expand_builtin_establish_vms_condition_handler (target
, const0_rtx
);
4800 /* Functions to save and restore alpha_return_addr_rtx. */
4802 /* Start the ball rolling with RETURN_ADDR_RTX. */
4805 alpha_return_addr (int count
, rtx frame ATTRIBUTE_UNUSED
)
4810 return get_hard_reg_initial_val (Pmode
, REG_RA
);
4813 /* Return or create a memory slot containing the gp value for the current
4814 function. Needed only if TARGET_LD_BUGGY_LDGP. */
4817 alpha_gp_save_rtx (void)
4819 rtx seq
, m
= cfun
->machine
->gp_save_rtx
;
4825 m
= assign_stack_local (DImode
, UNITS_PER_WORD
, BITS_PER_WORD
);
4826 m
= validize_mem (m
);
4827 emit_move_insn (m
, pic_offset_table_rtx
);
4832 /* We used to simply emit the sequence after entry_of_function.
4833 However this breaks the CFG if the first instruction in the
4834 first block is not the NOTE_INSN_BASIC_BLOCK, for example a
4835 label. Emit the sequence properly on the edge. We are only
4836 invoked from dw2_build_landing_pads and finish_eh_generation
4837 will call commit_edge_insertions thanks to a kludge. */
4838 insert_insn_on_edge (seq
,
4839 single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun
)));
4841 cfun
->machine
->gp_save_rtx
= m
;
4848 alpha_instantiate_decls (void)
4850 if (cfun
->machine
->gp_save_rtx
!= NULL_RTX
)
4851 instantiate_decl_rtl (cfun
->machine
->gp_save_rtx
);
4855 alpha_ra_ever_killed (void)
4859 if (!has_hard_reg_initial_val (Pmode
, REG_RA
))
4860 return (int)df_regs_ever_live_p (REG_RA
);
4862 push_topmost_sequence ();
4864 pop_topmost_sequence ();
4866 return reg_set_between_p (gen_rtx_REG (Pmode
, REG_RA
), top
, NULL_RTX
);
4870 /* Return the trap mode suffix applicable to the current
4871 instruction, or NULL. */
4874 get_trap_mode_suffix (void)
4876 enum attr_trap_suffix s
= get_attr_trap_suffix (current_output_insn
);
4880 case TRAP_SUFFIX_NONE
:
4883 case TRAP_SUFFIX_SU
:
4884 if (alpha_fptm
>= ALPHA_FPTM_SU
)
4888 case TRAP_SUFFIX_SUI
:
4889 if (alpha_fptm
>= ALPHA_FPTM_SUI
)
4893 case TRAP_SUFFIX_V_SV
:
4901 case ALPHA_FPTM_SUI
:
4907 case TRAP_SUFFIX_V_SV_SVI
:
4916 case ALPHA_FPTM_SUI
:
4923 case TRAP_SUFFIX_U_SU_SUI
:
4932 case ALPHA_FPTM_SUI
:
4945 /* Return the rounding mode suffix applicable to the current
4946 instruction, or NULL. */
4949 get_round_mode_suffix (void)
4951 enum attr_round_suffix s
= get_attr_round_suffix (current_output_insn
);
4955 case ROUND_SUFFIX_NONE
:
4957 case ROUND_SUFFIX_NORMAL
:
4960 case ALPHA_FPRM_NORM
:
4962 case ALPHA_FPRM_MINF
:
4964 case ALPHA_FPRM_CHOP
:
4966 case ALPHA_FPRM_DYN
:
4973 case ROUND_SUFFIX_C
:
4982 /* Locate some local-dynamic symbol still in use by this function
4983 so that we can print its name in some movdi_er_tlsldm pattern. */
4986 get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
4990 if (GET_CODE (x
) == SYMBOL_REF
4991 && SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
4993 cfun
->machine
->some_ld_name
= XSTR (x
, 0);
5001 get_some_local_dynamic_name (void)
5005 if (cfun
->machine
->some_ld_name
)
5006 return cfun
->machine
->some_ld_name
;
5008 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5010 && for_each_rtx (&PATTERN (insn
), get_some_local_dynamic_name_1
, 0))
5011 return cfun
->machine
->some_ld_name
;
5016 /* Print an operand. Recognize special options, documented below. */
5019 print_operand (FILE *file
, rtx x
, int code
)
5026 /* Print the assembler name of the current function. */
5027 assemble_name (file
, alpha_fnname
);
5031 assemble_name (file
, get_some_local_dynamic_name ());
5036 const char *trap
= get_trap_mode_suffix ();
5037 const char *round
= get_round_mode_suffix ();
5040 fprintf (file
, "/%s%s", (trap
? trap
: ""), (round
? round
: ""));
5045 /* Generates single precision instruction suffix. */
5046 fputc ((TARGET_FLOAT_VAX
? 'f' : 's'), file
);
5050 /* Generates double precision instruction suffix. */
5051 fputc ((TARGET_FLOAT_VAX
? 'g' : 't'), file
);
5055 if (alpha_this_literal_sequence_number
== 0)
5056 alpha_this_literal_sequence_number
= alpha_next_sequence_number
++;
5057 fprintf (file
, "%d", alpha_this_literal_sequence_number
);
5061 if (alpha_this_gpdisp_sequence_number
== 0)
5062 alpha_this_gpdisp_sequence_number
= alpha_next_sequence_number
++;
5063 fprintf (file
, "%d", alpha_this_gpdisp_sequence_number
);
5067 if (GET_CODE (x
) == HIGH
)
5068 output_addr_const (file
, XEXP (x
, 0));
5070 output_operand_lossage ("invalid %%H value");
5077 if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSGD_CALL
)
5079 x
= XVECEXP (x
, 0, 0);
5080 lituse
= "lituse_tlsgd";
5082 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSLDM_CALL
)
5084 x
= XVECEXP (x
, 0, 0);
5085 lituse
= "lituse_tlsldm";
5087 else if (CONST_INT_P (x
))
5088 lituse
= "lituse_jsr";
5091 output_operand_lossage ("invalid %%J value");
5095 if (x
!= const0_rtx
)
5096 fprintf (file
, "\t\t!%s!%d", lituse
, (int) INTVAL (x
));
5104 #ifdef HAVE_AS_JSRDIRECT_RELOCS
5105 lituse
= "lituse_jsrdirect";
5107 lituse
= "lituse_jsr";
5110 gcc_assert (INTVAL (x
) != 0);
5111 fprintf (file
, "\t\t!%s!%d", lituse
, (int) INTVAL (x
));
5115 /* If this operand is the constant zero, write it as "$31". */
5117 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
5118 else if (x
== CONST0_RTX (GET_MODE (x
)))
5119 fprintf (file
, "$31");
5121 output_operand_lossage ("invalid %%r value");
5125 /* Similar, but for floating-point. */
5127 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
5128 else if (x
== CONST0_RTX (GET_MODE (x
)))
5129 fprintf (file
, "$f31");
5131 output_operand_lossage ("invalid %%R value");
5135 /* Write the 1's complement of a constant. */
5136 if (!CONST_INT_P (x
))
5137 output_operand_lossage ("invalid %%N value");
5139 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INTVAL (x
));
5143 /* Write 1 << C, for a constant C. */
5144 if (!CONST_INT_P (x
))
5145 output_operand_lossage ("invalid %%P value");
5147 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (HOST_WIDE_INT
) 1 << INTVAL (x
));
5151 /* Write the high-order 16 bits of a constant, sign-extended. */
5152 if (!CONST_INT_P (x
))
5153 output_operand_lossage ("invalid %%h value");
5155 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) >> 16);
5159 /* Write the low-order 16 bits of a constant, sign-extended. */
5160 if (!CONST_INT_P (x
))
5161 output_operand_lossage ("invalid %%L value");
5163 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
5164 (INTVAL (x
) & 0xffff) - 2 * (INTVAL (x
) & 0x8000));
5168 /* Write mask for ZAP insn. */
5169 if (GET_CODE (x
) == CONST_DOUBLE
)
5171 HOST_WIDE_INT mask
= 0;
5172 HOST_WIDE_INT value
;
5174 value
= CONST_DOUBLE_LOW (x
);
5175 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
5180 value
= CONST_DOUBLE_HIGH (x
);
5181 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
5184 mask
|= (1 << (i
+ sizeof (int)));
5186 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, mask
& 0xff);
5189 else if (CONST_INT_P (x
))
5191 HOST_WIDE_INT mask
= 0, value
= INTVAL (x
);
5193 for (i
= 0; i
< 8; i
++, value
>>= 8)
5197 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, mask
);
5200 output_operand_lossage ("invalid %%m value");
5204 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
5205 if (!CONST_INT_P (x
)
5206 || (INTVAL (x
) != 8 && INTVAL (x
) != 16
5207 && INTVAL (x
) != 32 && INTVAL (x
) != 64))
5208 output_operand_lossage ("invalid %%M value");
5210 fprintf (file
, "%s",
5211 (INTVAL (x
) == 8 ? "b"
5212 : INTVAL (x
) == 16 ? "w"
5213 : INTVAL (x
) == 32 ? "l"
5218 /* Similar, except do it from the mask. */
5219 if (CONST_INT_P (x
))
5221 HOST_WIDE_INT value
= INTVAL (x
);
5228 if (value
== 0xffff)
5233 if (value
== 0xffffffff)
5244 else if (HOST_BITS_PER_WIDE_INT
== 32
5245 && GET_CODE (x
) == CONST_DOUBLE
5246 && CONST_DOUBLE_LOW (x
) == 0xffffffff
5247 && CONST_DOUBLE_HIGH (x
) == 0)
5252 output_operand_lossage ("invalid %%U value");
5256 /* Write the constant value divided by 8. */
5257 if (!CONST_INT_P (x
)
5258 || (unsigned HOST_WIDE_INT
) INTVAL (x
) >= 64
5259 || (INTVAL (x
) & 7) != 0)
5260 output_operand_lossage ("invalid %%s value");
5262 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) / 8);
5266 /* Same, except compute (64 - c) / 8 */
5268 if (!CONST_INT_P (x
)
5269 && (unsigned HOST_WIDE_INT
) INTVAL (x
) >= 64
5270 && (INTVAL (x
) & 7) != 8)
5271 output_operand_lossage ("invalid %%s value");
5273 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (64 - INTVAL (x
)) / 8);
5276 case 'C': case 'D': case 'c': case 'd':
5277 /* Write out comparison name. */
5279 enum rtx_code c
= GET_CODE (x
);
5281 if (!COMPARISON_P (x
))
5282 output_operand_lossage ("invalid %%C value");
5284 else if (code
== 'D')
5285 c
= reverse_condition (c
);
5286 else if (code
== 'c')
5287 c
= swap_condition (c
);
5288 else if (code
== 'd')
5289 c
= swap_condition (reverse_condition (c
));
5292 fprintf (file
, "ule");
5294 fprintf (file
, "ult");
5295 else if (c
== UNORDERED
)
5296 fprintf (file
, "un");
5298 fprintf (file
, "%s", GET_RTX_NAME (c
));
5303 /* Write the divide or modulus operator. */
5304 switch (GET_CODE (x
))
5307 fprintf (file
, "div%s", GET_MODE (x
) == SImode
? "l" : "q");
5310 fprintf (file
, "div%su", GET_MODE (x
) == SImode
? "l" : "q");
5313 fprintf (file
, "rem%s", GET_MODE (x
) == SImode
? "l" : "q");
5316 fprintf (file
, "rem%su", GET_MODE (x
) == SImode
? "l" : "q");
5319 output_operand_lossage ("invalid %%E value");
5325 /* Write "_u" for unaligned access. */
5326 if (MEM_P (x
) && GET_CODE (XEXP (x
, 0)) == AND
)
5327 fprintf (file
, "_u");
5332 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
5334 output_address (XEXP (x
, 0));
5335 else if (GET_CODE (x
) == CONST
&& GET_CODE (XEXP (x
, 0)) == UNSPEC
)
5337 switch (XINT (XEXP (x
, 0), 1))
5341 output_addr_const (file
, XVECEXP (XEXP (x
, 0), 0, 0));
5344 output_operand_lossage ("unknown relocation unspec");
5349 output_addr_const (file
, x
);
5353 output_operand_lossage ("invalid %%xn code");
5358 print_operand_address (FILE *file
, rtx addr
)
5361 HOST_WIDE_INT offset
= 0;
5363 if (GET_CODE (addr
) == AND
)
5364 addr
= XEXP (addr
, 0);
5366 if (GET_CODE (addr
) == PLUS
5367 && CONST_INT_P (XEXP (addr
, 1)))
5369 offset
= INTVAL (XEXP (addr
, 1));
5370 addr
= XEXP (addr
, 0);
5373 if (GET_CODE (addr
) == LO_SUM
)
5375 const char *reloc16
, *reloclo
;
5376 rtx op1
= XEXP (addr
, 1);
5378 if (GET_CODE (op1
) == CONST
&& GET_CODE (XEXP (op1
, 0)) == UNSPEC
)
5380 op1
= XEXP (op1
, 0);
5381 switch (XINT (op1
, 1))
5385 reloclo
= (alpha_tls_size
== 16 ? "dtprel" : "dtprello");
5389 reloclo
= (alpha_tls_size
== 16 ? "tprel" : "tprello");
5392 output_operand_lossage ("unknown relocation unspec");
5396 output_addr_const (file
, XVECEXP (op1
, 0, 0));
5401 reloclo
= "gprellow";
5402 output_addr_const (file
, op1
);
5406 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
5408 addr
= XEXP (addr
, 0);
5409 switch (GET_CODE (addr
))
5412 basereg
= REGNO (addr
);
5416 basereg
= subreg_regno (addr
);
5423 fprintf (file
, "($%d)\t\t!%s", basereg
,
5424 (basereg
== 29 ? reloc16
: reloclo
));
5428 switch (GET_CODE (addr
))
5431 basereg
= REGNO (addr
);
5435 basereg
= subreg_regno (addr
);
5439 offset
= INTVAL (addr
);
5442 #if TARGET_ABI_OPEN_VMS
5444 fprintf (file
, "%s", XSTR (addr
, 0));
5448 gcc_assert (GET_CODE (XEXP (addr
, 0)) == PLUS
5449 && GET_CODE (XEXP (XEXP (addr
, 0), 0)) == SYMBOL_REF
);
5450 fprintf (file
, "%s+" HOST_WIDE_INT_PRINT_DEC
,
5451 XSTR (XEXP (XEXP (addr
, 0), 0), 0),
5452 INTVAL (XEXP (XEXP (addr
, 0), 1)));
5460 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"($%d)", offset
, basereg
);
5463 /* Emit RTL insns to initialize the variable parts of a trampoline at
5464 M_TRAMP. FNDECL is target function's decl. CHAIN_VALUE is an rtx
5465 for the static chain value for the function. */
5468 alpha_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain_value
)
5470 rtx fnaddr
, mem
, word1
, word2
;
5472 fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
5474 #ifdef POINTERS_EXTEND_UNSIGNED
5475 fnaddr
= convert_memory_address (Pmode
, fnaddr
);
5476 chain_value
= convert_memory_address (Pmode
, chain_value
);
5479 if (TARGET_ABI_OPEN_VMS
)
5484 /* Construct the name of the trampoline entry point. */
5485 fnname
= XSTR (fnaddr
, 0);
5486 trname
= (char *) alloca (strlen (fnname
) + 5);
5487 strcpy (trname
, fnname
);
5488 strcat (trname
, "..tr");
5489 fnname
= ggc_alloc_string (trname
, strlen (trname
) + 1);
5490 word2
= gen_rtx_SYMBOL_REF (Pmode
, fnname
);
5492 /* Trampoline (or "bounded") procedure descriptor is constructed from
5493 the function's procedure descriptor with certain fields zeroed IAW
5494 the VMS calling standard. This is stored in the first quadword. */
5495 word1
= force_reg (DImode
, gen_const_mem (DImode
, fnaddr
));
5496 word1
= expand_and (DImode
, word1
,
5497 GEN_INT (HOST_WIDE_INT_C (0xffff0fff0000fff0)),
5502 /* These 4 instructions are:
5507 We don't bother setting the HINT field of the jump; the nop
5508 is merely there for padding. */
5509 word1
= GEN_INT (HOST_WIDE_INT_C (0xa77b0010a43b0018));
5510 word2
= GEN_INT (HOST_WIDE_INT_C (0x47ff041f6bfb0000));
5513 /* Store the first two words, as computed above. */
5514 mem
= adjust_address (m_tramp
, DImode
, 0);
5515 emit_move_insn (mem
, word1
);
5516 mem
= adjust_address (m_tramp
, DImode
, 8);
5517 emit_move_insn (mem
, word2
);
5519 /* Store function address and static chain value. */
5520 mem
= adjust_address (m_tramp
, Pmode
, 16);
5521 emit_move_insn (mem
, fnaddr
);
5522 mem
= adjust_address (m_tramp
, Pmode
, 24);
5523 emit_move_insn (mem
, chain_value
);
5527 emit_insn (gen_imb ());
5528 #ifdef HAVE_ENABLE_EXECUTE_STACK
5529 emit_library_call (init_one_libfunc ("__enable_execute_stack"),
5530 LCT_NORMAL
, VOIDmode
, 1, XEXP (m_tramp
, 0), Pmode
);
5535 /* Determine where to put an argument to a function.
5536 Value is zero to push the argument on the stack,
5537 or a hard register in which to store the argument.
5539 MODE is the argument's machine mode.
5540 TYPE is the data type of the argument (as a tree).
5541 This is null for libcalls where that information may
5543 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5544 the preceding args and about the function being called.
5545 NAMED is nonzero if this argument is a named parameter
5546 (otherwise it is an extra parameter matching an ellipsis).
5548 On Alpha the first 6 words of args are normally in registers
5549 and the rest are pushed. */
5552 alpha_function_arg (cumulative_args_t cum_v
, enum machine_mode mode
,
5553 const_tree type
, bool named ATTRIBUTE_UNUSED
)
5555 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5559 /* Don't get confused and pass small structures in FP registers. */
5560 if (type
&& AGGREGATE_TYPE_P (type
))
5564 #ifdef ENABLE_CHECKING
5565 /* With alpha_split_complex_arg, we shouldn't see any raw complex
5567 gcc_assert (!COMPLEX_MODE_P (mode
));
5570 /* Set up defaults for FP operands passed in FP registers, and
5571 integral operands passed in integer registers. */
5572 if (TARGET_FPREGS
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5578 /* ??? Irritatingly, the definition of CUMULATIVE_ARGS is different for
5579 the two platforms, so we can't avoid conditional compilation. */
5580 #if TARGET_ABI_OPEN_VMS
5582 if (mode
== VOIDmode
)
5583 return alpha_arg_info_reg_val (*cum
);
5585 num_args
= cum
->num_args
;
5587 || targetm
.calls
.must_pass_in_stack (mode
, type
))
5590 #elif TARGET_ABI_OSF
5596 /* VOID is passed as a special flag for "last argument". */
5597 if (type
== void_type_node
)
5599 else if (targetm
.calls
.must_pass_in_stack (mode
, type
))
5603 #error Unhandled ABI
5606 return gen_rtx_REG (mode
, num_args
+ basereg
);
5609 /* Update the data in CUM to advance over an argument
5610 of mode MODE and data type TYPE.
5611 (TYPE is null for libcalls where that information may not be available.) */
5614 alpha_function_arg_advance (cumulative_args_t cum_v
, enum machine_mode mode
,
5615 const_tree type
, bool named ATTRIBUTE_UNUSED
)
5617 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5618 bool onstack
= targetm
.calls
.must_pass_in_stack (mode
, type
);
5619 int increment
= onstack
? 6 : ALPHA_ARG_SIZE (mode
, type
, named
);
5624 if (!onstack
&& cum
->num_args
< 6)
5625 cum
->atypes
[cum
->num_args
] = alpha_arg_type (mode
);
5626 cum
->num_args
+= increment
;
5631 alpha_arg_partial_bytes (cumulative_args_t cum_v
,
5632 enum machine_mode mode ATTRIBUTE_UNUSED
,
5633 tree type ATTRIBUTE_UNUSED
,
5634 bool named ATTRIBUTE_UNUSED
)
5637 CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
= get_cumulative_args (cum_v
);
5639 #if TARGET_ABI_OPEN_VMS
5640 if (cum
->num_args
< 6
5641 && 6 < cum
->num_args
+ ALPHA_ARG_SIZE (mode
, type
, named
))
5642 words
= 6 - cum
->num_args
;
5643 #elif TARGET_ABI_OSF
5644 if (*cum
< 6 && 6 < *cum
+ ALPHA_ARG_SIZE (mode
, type
, named
))
5647 #error Unhandled ABI
5650 return words
* UNITS_PER_WORD
;
5654 /* Return true if TYPE must be returned in memory, instead of in registers. */
5657 alpha_return_in_memory (const_tree type
, const_tree fndecl ATTRIBUTE_UNUSED
)
5659 enum machine_mode mode
= VOIDmode
;
5664 mode
= TYPE_MODE (type
);
5666 /* All aggregates are returned in memory, except on OpenVMS where
5667 records that fit 64 bits should be returned by immediate value
5668 as required by section 3.8.7.1 of the OpenVMS Calling Standard. */
5669 if (TARGET_ABI_OPEN_VMS
5670 && TREE_CODE (type
) != ARRAY_TYPE
5671 && (unsigned HOST_WIDE_INT
) int_size_in_bytes(type
) <= 8)
5674 if (AGGREGATE_TYPE_P (type
))
5678 size
= GET_MODE_SIZE (mode
);
5679 switch (GET_MODE_CLASS (mode
))
5681 case MODE_VECTOR_FLOAT
:
5682 /* Pass all float vectors in memory, like an aggregate. */
5685 case MODE_COMPLEX_FLOAT
:
5686 /* We judge complex floats on the size of their element,
5687 not the size of the whole type. */
5688 size
= GET_MODE_UNIT_SIZE (mode
);
5693 case MODE_COMPLEX_INT
:
5694 case MODE_VECTOR_INT
:
5698 /* ??? We get called on all sorts of random stuff from
5699 aggregate_value_p. We must return something, but it's not
5700 clear what's safe to return. Pretend it's a struct I
5705 /* Otherwise types must fit in one register. */
5706 return size
> UNITS_PER_WORD
;
5709 /* Return true if TYPE should be passed by invisible reference. */
5712 alpha_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED
,
5713 enum machine_mode mode
,
5714 const_tree type ATTRIBUTE_UNUSED
,
5715 bool named ATTRIBUTE_UNUSED
)
5717 return mode
== TFmode
|| mode
== TCmode
;
5720 /* Define how to find the value returned by a function. VALTYPE is the
5721 data type of the value (as a tree). If the precise function being
5722 called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0.
5723 MODE is set instead of VALTYPE for libcalls.
5725 On Alpha the value is found in $0 for integer functions and
5726 $f0 for floating-point functions. */
5729 function_value (const_tree valtype
, const_tree func ATTRIBUTE_UNUSED
,
5730 enum machine_mode mode
)
5732 unsigned int regnum
, dummy ATTRIBUTE_UNUSED
;
5733 enum mode_class mclass
;
5735 gcc_assert (!valtype
|| !alpha_return_in_memory (valtype
, func
));
5738 mode
= TYPE_MODE (valtype
);
5740 mclass
= GET_MODE_CLASS (mode
);
5744 /* Do the same thing as PROMOTE_MODE except for libcalls on VMS,
5745 where we have them returning both SImode and DImode. */
5746 if (!(TARGET_ABI_OPEN_VMS
&& valtype
&& AGGREGATE_TYPE_P (valtype
)))
5747 PROMOTE_MODE (mode
, dummy
, valtype
);
5750 case MODE_COMPLEX_INT
:
5751 case MODE_VECTOR_INT
:
5759 case MODE_COMPLEX_FLOAT
:
5761 enum machine_mode cmode
= GET_MODE_INNER (mode
);
5763 return gen_rtx_PARALLEL
5766 gen_rtx_EXPR_LIST (VOIDmode
, gen_rtx_REG (cmode
, 32),
5768 gen_rtx_EXPR_LIST (VOIDmode
, gen_rtx_REG (cmode
, 33),
5769 GEN_INT (GET_MODE_SIZE (cmode
)))));
5773 /* We should only reach here for BLKmode on VMS. */
5774 gcc_assert (TARGET_ABI_OPEN_VMS
&& mode
== BLKmode
);
5782 return gen_rtx_REG (mode
, regnum
);
5785 /* TCmode complex values are passed by invisible reference. We
5786 should not split these values. */
5789 alpha_split_complex_arg (const_tree type
)
5791 return TYPE_MODE (type
) != TCmode
;
5795 alpha_build_builtin_va_list (void)
5797 tree base
, ofs
, space
, record
, type_decl
;
5799 if (TARGET_ABI_OPEN_VMS
)
5800 return ptr_type_node
;
5802 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
5803 type_decl
= build_decl (BUILTINS_LOCATION
,
5804 TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
5805 TYPE_STUB_DECL (record
) = type_decl
;
5806 TYPE_NAME (record
) = type_decl
;
5808 /* C++? SET_IS_AGGR_TYPE (record, 1); */
5810 /* Dummy field to prevent alignment warnings. */
5811 space
= build_decl (BUILTINS_LOCATION
,
5812 FIELD_DECL
, NULL_TREE
, integer_type_node
);
5813 DECL_FIELD_CONTEXT (space
) = record
;
5814 DECL_ARTIFICIAL (space
) = 1;
5815 DECL_IGNORED_P (space
) = 1;
5817 ofs
= build_decl (BUILTINS_LOCATION
,
5818 FIELD_DECL
, get_identifier ("__offset"),
5820 DECL_FIELD_CONTEXT (ofs
) = record
;
5821 DECL_CHAIN (ofs
) = space
;
5822 /* ??? This is a hack, __offset is marked volatile to prevent
5823 DCE that confuses stdarg optimization and results in
5824 gcc.c-torture/execute/stdarg-1.c failure. See PR 41089. */
5825 TREE_THIS_VOLATILE (ofs
) = 1;
5827 base
= build_decl (BUILTINS_LOCATION
,
5828 FIELD_DECL
, get_identifier ("__base"),
5830 DECL_FIELD_CONTEXT (base
) = record
;
5831 DECL_CHAIN (base
) = ofs
;
5833 TYPE_FIELDS (record
) = base
;
5834 layout_type (record
);
5836 va_list_gpr_counter_field
= ofs
;
5841 /* Helper function for alpha_stdarg_optimize_hook. Skip over casts
5842 and constant additions. */
5845 va_list_skip_additions (tree lhs
)
5851 enum tree_code code
;
5853 stmt
= SSA_NAME_DEF_STMT (lhs
);
5855 if (gimple_code (stmt
) == GIMPLE_PHI
)
5858 if (!is_gimple_assign (stmt
)
5859 || gimple_assign_lhs (stmt
) != lhs
)
5862 if (TREE_CODE (gimple_assign_rhs1 (stmt
)) != SSA_NAME
)
5864 code
= gimple_assign_rhs_code (stmt
);
5865 if (!CONVERT_EXPR_CODE_P (code
)
5866 && ((code
!= PLUS_EXPR
&& code
!= POINTER_PLUS_EXPR
)
5867 || TREE_CODE (gimple_assign_rhs2 (stmt
)) != INTEGER_CST
5868 || !tree_fits_uhwi_p (gimple_assign_rhs2 (stmt
))))
5871 lhs
= gimple_assign_rhs1 (stmt
);
5875 /* Check if LHS = RHS statement is
5876 LHS = *(ap.__base + ap.__offset + cst)
5879 + ((ap.__offset + cst <= 47)
5880 ? ap.__offset + cst - 48 : ap.__offset + cst) + cst2).
5881 If the former, indicate that GPR registers are needed,
5882 if the latter, indicate that FPR registers are needed.
5884 Also look for LHS = (*ptr).field, where ptr is one of the forms
5887 On alpha, cfun->va_list_gpr_size is used as size of the needed
5888 regs and cfun->va_list_fpr_size is a bitmask, bit 0 set if GPR
5889 registers are needed and bit 1 set if FPR registers are needed.
5890 Return true if va_list references should not be scanned for the
5891 current statement. */
5894 alpha_stdarg_optimize_hook (struct stdarg_info
*si
, const_gimple stmt
)
5896 tree base
, offset
, rhs
;
5900 if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt
))
5901 != GIMPLE_SINGLE_RHS
)
5904 rhs
= gimple_assign_rhs1 (stmt
);
5905 while (handled_component_p (rhs
))
5906 rhs
= TREE_OPERAND (rhs
, 0);
5907 if (TREE_CODE (rhs
) != MEM_REF
5908 || TREE_CODE (TREE_OPERAND (rhs
, 0)) != SSA_NAME
)
5911 stmt
= va_list_skip_additions (TREE_OPERAND (rhs
, 0));
5913 || !is_gimple_assign (stmt
)
5914 || gimple_assign_rhs_code (stmt
) != POINTER_PLUS_EXPR
)
5917 base
= gimple_assign_rhs1 (stmt
);
5918 if (TREE_CODE (base
) == SSA_NAME
)
5920 base_stmt
= va_list_skip_additions (base
);
5922 && is_gimple_assign (base_stmt
)
5923 && gimple_assign_rhs_code (base_stmt
) == COMPONENT_REF
)
5924 base
= gimple_assign_rhs1 (base_stmt
);
5927 if (TREE_CODE (base
) != COMPONENT_REF
5928 || TREE_OPERAND (base
, 1) != TYPE_FIELDS (va_list_type_node
))
5930 base
= gimple_assign_rhs2 (stmt
);
5931 if (TREE_CODE (base
) == SSA_NAME
)
5933 base_stmt
= va_list_skip_additions (base
);
5935 && is_gimple_assign (base_stmt
)
5936 && gimple_assign_rhs_code (base_stmt
) == COMPONENT_REF
)
5937 base
= gimple_assign_rhs1 (base_stmt
);
5940 if (TREE_CODE (base
) != COMPONENT_REF
5941 || TREE_OPERAND (base
, 1) != TYPE_FIELDS (va_list_type_node
))
5947 base
= get_base_address (base
);
5948 if (TREE_CODE (base
) != VAR_DECL
5949 || !bitmap_bit_p (si
->va_list_vars
, DECL_UID (base
) + num_ssa_names
))
5952 offset
= gimple_op (stmt
, 1 + offset_arg
);
5953 if (TREE_CODE (offset
) == SSA_NAME
)
5955 gimple offset_stmt
= va_list_skip_additions (offset
);
5958 && gimple_code (offset_stmt
) == GIMPLE_PHI
)
5961 gimple arg1_stmt
, arg2_stmt
;
5963 enum tree_code code1
, code2
;
5965 if (gimple_phi_num_args (offset_stmt
) != 2)
5969 = va_list_skip_additions (gimple_phi_arg_def (offset_stmt
, 0));
5971 = va_list_skip_additions (gimple_phi_arg_def (offset_stmt
, 1));
5972 if (arg1_stmt
== NULL
5973 || !is_gimple_assign (arg1_stmt
)
5974 || arg2_stmt
== NULL
5975 || !is_gimple_assign (arg2_stmt
))
5978 code1
= gimple_assign_rhs_code (arg1_stmt
);
5979 code2
= gimple_assign_rhs_code (arg2_stmt
);
5980 if (code1
== COMPONENT_REF
5981 && (code2
== MINUS_EXPR
|| code2
== PLUS_EXPR
))
5983 else if (code2
== COMPONENT_REF
5984 && (code1
== MINUS_EXPR
|| code1
== PLUS_EXPR
))
5986 gimple tem
= arg1_stmt
;
5988 arg1_stmt
= arg2_stmt
;
5994 if (!tree_fits_shwi_p (gimple_assign_rhs2 (arg2_stmt
)))
5997 sub
= tree_to_shwi (gimple_assign_rhs2 (arg2_stmt
));
5998 if (code2
== MINUS_EXPR
)
6000 if (sub
< -48 || sub
> -32)
6003 arg1
= gimple_assign_rhs1 (arg1_stmt
);
6004 arg2
= gimple_assign_rhs1 (arg2_stmt
);
6005 if (TREE_CODE (arg2
) == SSA_NAME
)
6007 arg2_stmt
= va_list_skip_additions (arg2
);
6008 if (arg2_stmt
== NULL
6009 || !is_gimple_assign (arg2_stmt
)
6010 || gimple_assign_rhs_code (arg2_stmt
) != COMPONENT_REF
)
6012 arg2
= gimple_assign_rhs1 (arg2_stmt
);
6017 if (TREE_CODE (arg1
) != COMPONENT_REF
6018 || TREE_OPERAND (arg1
, 1) != va_list_gpr_counter_field
6019 || get_base_address (arg1
) != base
)
6022 /* Need floating point regs. */
6023 cfun
->va_list_fpr_size
|= 2;
6027 && is_gimple_assign (offset_stmt
)
6028 && gimple_assign_rhs_code (offset_stmt
) == COMPONENT_REF
)
6029 offset
= gimple_assign_rhs1 (offset_stmt
);
6031 if (TREE_CODE (offset
) != COMPONENT_REF
6032 || TREE_OPERAND (offset
, 1) != va_list_gpr_counter_field
6033 || get_base_address (offset
) != base
)
6036 /* Need general regs. */
6037 cfun
->va_list_fpr_size
|= 1;
6041 si
->va_list_escapes
= true;
6046 /* Perform any needed actions needed for a function that is receiving a
6047 variable number of arguments. */
6050 alpha_setup_incoming_varargs (cumulative_args_t pcum
, enum machine_mode mode
,
6051 tree type
, int *pretend_size
, int no_rtl
)
6053 CUMULATIVE_ARGS cum
= *get_cumulative_args (pcum
);
6055 /* Skip the current argument. */
6056 targetm
.calls
.function_arg_advance (pack_cumulative_args (&cum
), mode
, type
,
6059 #if TARGET_ABI_OPEN_VMS
6060 /* For VMS, we allocate space for all 6 arg registers plus a count.
6062 However, if NO registers need to be saved, don't allocate any space.
6063 This is not only because we won't need the space, but because AP
6064 includes the current_pretend_args_size and we don't want to mess up
6065 any ap-relative addresses already made. */
6066 if (cum
.num_args
< 6)
6070 emit_move_insn (gen_rtx_REG (DImode
, 1), virtual_incoming_args_rtx
);
6071 emit_insn (gen_arg_home ());
6073 *pretend_size
= 7 * UNITS_PER_WORD
;
6076 /* On OSF/1 and friends, we allocate space for all 12 arg registers, but
6077 only push those that are remaining. However, if NO registers need to
6078 be saved, don't allocate any space. This is not only because we won't
6079 need the space, but because AP includes the current_pretend_args_size
6080 and we don't want to mess up any ap-relative addresses already made.
6082 If we are not to use the floating-point registers, save the integer
6083 registers where we would put the floating-point registers. This is
6084 not the most efficient way to implement varargs with just one register
6085 class, but it isn't worth doing anything more efficient in this rare
6093 alias_set_type set
= get_varargs_alias_set ();
6096 count
= cfun
->va_list_gpr_size
/ UNITS_PER_WORD
;
6097 if (count
> 6 - cum
)
6100 /* Detect whether integer registers or floating-point registers
6101 are needed by the detected va_arg statements. See above for
6102 how these values are computed. Note that the "escape" value
6103 is VA_LIST_MAX_FPR_SIZE, which is 255, which has both of
6105 gcc_assert ((VA_LIST_MAX_FPR_SIZE
& 3) == 3);
6107 if (cfun
->va_list_fpr_size
& 1)
6109 tmp
= gen_rtx_MEM (BLKmode
,
6110 plus_constant (Pmode
, virtual_incoming_args_rtx
,
6111 (cum
+ 6) * UNITS_PER_WORD
));
6112 MEM_NOTRAP_P (tmp
) = 1;
6113 set_mem_alias_set (tmp
, set
);
6114 move_block_from_reg (16 + cum
, tmp
, count
);
6117 if (cfun
->va_list_fpr_size
& 2)
6119 tmp
= gen_rtx_MEM (BLKmode
,
6120 plus_constant (Pmode
, virtual_incoming_args_rtx
,
6121 cum
* UNITS_PER_WORD
));
6122 MEM_NOTRAP_P (tmp
) = 1;
6123 set_mem_alias_set (tmp
, set
);
6124 move_block_from_reg (16 + cum
+ TARGET_FPREGS
*32, tmp
, count
);
6127 *pretend_size
= 12 * UNITS_PER_WORD
;
6132 alpha_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
6134 HOST_WIDE_INT offset
;
6135 tree t
, offset_field
, base_field
;
6137 if (TREE_CODE (TREE_TYPE (valist
)) == ERROR_MARK
)
6140 /* For Unix, TARGET_SETUP_INCOMING_VARARGS moves the starting address base
6141 up by 48, storing fp arg registers in the first 48 bytes, and the
6142 integer arg registers in the next 48 bytes. This is only done,
6143 however, if any integer registers need to be stored.
6145 If no integer registers need be stored, then we must subtract 48
6146 in order to account for the integer arg registers which are counted
6147 in argsize above, but which are not actually stored on the stack.
6148 Must further be careful here about structures straddling the last
6149 integer argument register; that futzes with pretend_args_size,
6150 which changes the meaning of AP. */
6153 offset
= TARGET_ABI_OPEN_VMS
? UNITS_PER_WORD
: 6 * UNITS_PER_WORD
;
6155 offset
= -6 * UNITS_PER_WORD
+ crtl
->args
.pretend_args_size
;
6157 if (TARGET_ABI_OPEN_VMS
)
6159 t
= make_tree (ptr_type_node
, virtual_incoming_args_rtx
);
6160 t
= fold_build_pointer_plus_hwi (t
, offset
+ NUM_ARGS
* UNITS_PER_WORD
);
6161 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
6162 TREE_SIDE_EFFECTS (t
) = 1;
6163 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6167 base_field
= TYPE_FIELDS (TREE_TYPE (valist
));
6168 offset_field
= DECL_CHAIN (base_field
);
6170 base_field
= build3 (COMPONENT_REF
, TREE_TYPE (base_field
),
6171 valist
, base_field
, NULL_TREE
);
6172 offset_field
= build3 (COMPONENT_REF
, TREE_TYPE (offset_field
),
6173 valist
, offset_field
, NULL_TREE
);
6175 t
= make_tree (ptr_type_node
, virtual_incoming_args_rtx
);
6176 t
= fold_build_pointer_plus_hwi (t
, offset
);
6177 t
= build2 (MODIFY_EXPR
, TREE_TYPE (base_field
), base_field
, t
);
6178 TREE_SIDE_EFFECTS (t
) = 1;
6179 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6181 t
= build_int_cst (NULL_TREE
, NUM_ARGS
* UNITS_PER_WORD
);
6182 t
= build2 (MODIFY_EXPR
, TREE_TYPE (offset_field
), offset_field
, t
);
6183 TREE_SIDE_EFFECTS (t
) = 1;
6184 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6189 alpha_gimplify_va_arg_1 (tree type
, tree base
, tree offset
,
6192 tree type_size
, ptr_type
, addend
, t
, addr
;
6193 gimple_seq internal_post
;
6195 /* If the type could not be passed in registers, skip the block
6196 reserved for the registers. */
6197 if (targetm
.calls
.must_pass_in_stack (TYPE_MODE (type
), type
))
6199 t
= build_int_cst (TREE_TYPE (offset
), 6*8);
6200 gimplify_assign (offset
,
6201 build2 (MAX_EXPR
, TREE_TYPE (offset
), offset
, t
),
6206 ptr_type
= build_pointer_type_for_mode (type
, ptr_mode
, true);
6208 if (TREE_CODE (type
) == COMPLEX_TYPE
)
6210 tree real_part
, imag_part
, real_temp
;
6212 real_part
= alpha_gimplify_va_arg_1 (TREE_TYPE (type
), base
,
6215 /* Copy the value into a new temporary, lest the formal temporary
6216 be reused out from under us. */
6217 real_temp
= get_initialized_tmp_var (real_part
, pre_p
, NULL
);
6219 imag_part
= alpha_gimplify_va_arg_1 (TREE_TYPE (type
), base
,
6222 return build2 (COMPLEX_EXPR
, type
, real_temp
, imag_part
);
6224 else if (TREE_CODE (type
) == REAL_TYPE
)
6226 tree fpaddend
, cond
, fourtyeight
;
6228 fourtyeight
= build_int_cst (TREE_TYPE (addend
), 6*8);
6229 fpaddend
= fold_build2 (MINUS_EXPR
, TREE_TYPE (addend
),
6230 addend
, fourtyeight
);
6231 cond
= fold_build2 (LT_EXPR
, boolean_type_node
, addend
, fourtyeight
);
6232 addend
= fold_build3 (COND_EXPR
, TREE_TYPE (addend
), cond
,
6236 /* Build the final address and force that value into a temporary. */
6237 addr
= fold_build_pointer_plus (fold_convert (ptr_type
, base
), addend
);
6238 internal_post
= NULL
;
6239 gimplify_expr (&addr
, pre_p
, &internal_post
, is_gimple_val
, fb_rvalue
);
6240 gimple_seq_add_seq (pre_p
, internal_post
);
6242 /* Update the offset field. */
6243 type_size
= TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type
));
6244 if (type_size
== NULL
|| TREE_OVERFLOW (type_size
))
6248 t
= size_binop (PLUS_EXPR
, type_size
, size_int (7));
6249 t
= size_binop (TRUNC_DIV_EXPR
, t
, size_int (8));
6250 t
= size_binop (MULT_EXPR
, t
, size_int (8));
6252 t
= fold_convert (TREE_TYPE (offset
), t
);
6253 gimplify_assign (offset
, build2 (PLUS_EXPR
, TREE_TYPE (offset
), offset
, t
),
6256 return build_va_arg_indirect_ref (addr
);
6260 alpha_gimplify_va_arg (tree valist
, tree type
, gimple_seq
*pre_p
,
6263 tree offset_field
, base_field
, offset
, base
, t
, r
;
6266 if (TARGET_ABI_OPEN_VMS
)
6267 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
6269 base_field
= TYPE_FIELDS (va_list_type_node
);
6270 offset_field
= DECL_CHAIN (base_field
);
6271 base_field
= build3 (COMPONENT_REF
, TREE_TYPE (base_field
),
6272 valist
, base_field
, NULL_TREE
);
6273 offset_field
= build3 (COMPONENT_REF
, TREE_TYPE (offset_field
),
6274 valist
, offset_field
, NULL_TREE
);
6276 /* Pull the fields of the structure out into temporaries. Since we never
6277 modify the base field, we can use a formal temporary. Sign-extend the
6278 offset field so that it's the proper width for pointer arithmetic. */
6279 base
= get_formal_tmp_var (base_field
, pre_p
);
6281 t
= fold_convert (build_nonstandard_integer_type (64, 0), offset_field
);
6282 offset
= get_initialized_tmp_var (t
, pre_p
, NULL
);
6284 indirect
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, false);
6286 type
= build_pointer_type_for_mode (type
, ptr_mode
, true);
6288 /* Find the value. Note that this will be a stable indirection, or
6289 a composite of stable indirections in the case of complex. */
6290 r
= alpha_gimplify_va_arg_1 (type
, base
, offset
, pre_p
);
6292 /* Stuff the offset temporary back into its field. */
6293 gimplify_assign (unshare_expr (offset_field
),
6294 fold_convert (TREE_TYPE (offset_field
), offset
), pre_p
);
6297 r
= build_va_arg_indirect_ref (r
);
6306 ALPHA_BUILTIN_CMPBGE
,
6307 ALPHA_BUILTIN_EXTBL
,
6308 ALPHA_BUILTIN_EXTWL
,
6309 ALPHA_BUILTIN_EXTLL
,
6310 ALPHA_BUILTIN_EXTQL
,
6311 ALPHA_BUILTIN_EXTWH
,
6312 ALPHA_BUILTIN_EXTLH
,
6313 ALPHA_BUILTIN_EXTQH
,
6314 ALPHA_BUILTIN_INSBL
,
6315 ALPHA_BUILTIN_INSWL
,
6316 ALPHA_BUILTIN_INSLL
,
6317 ALPHA_BUILTIN_INSQL
,
6318 ALPHA_BUILTIN_INSWH
,
6319 ALPHA_BUILTIN_INSLH
,
6320 ALPHA_BUILTIN_INSQH
,
6321 ALPHA_BUILTIN_MSKBL
,
6322 ALPHA_BUILTIN_MSKWL
,
6323 ALPHA_BUILTIN_MSKLL
,
6324 ALPHA_BUILTIN_MSKQL
,
6325 ALPHA_BUILTIN_MSKWH
,
6326 ALPHA_BUILTIN_MSKLH
,
6327 ALPHA_BUILTIN_MSKQH
,
6328 ALPHA_BUILTIN_UMULH
,
6330 ALPHA_BUILTIN_ZAPNOT
,
6331 ALPHA_BUILTIN_AMASK
,
6332 ALPHA_BUILTIN_IMPLVER
,
6334 ALPHA_BUILTIN_ESTABLISH_VMS_CONDITION_HANDLER
,
6335 ALPHA_BUILTIN_REVERT_VMS_CONDITION_HANDLER
,
6338 ALPHA_BUILTIN_MINUB8
,
6339 ALPHA_BUILTIN_MINSB8
,
6340 ALPHA_BUILTIN_MINUW4
,
6341 ALPHA_BUILTIN_MINSW4
,
6342 ALPHA_BUILTIN_MAXUB8
,
6343 ALPHA_BUILTIN_MAXSB8
,
6344 ALPHA_BUILTIN_MAXUW4
,
6345 ALPHA_BUILTIN_MAXSW4
,
6349 ALPHA_BUILTIN_UNPKBL
,
6350 ALPHA_BUILTIN_UNPKBW
,
6355 ALPHA_BUILTIN_CTPOP
,
6360 static enum insn_code
const code_for_builtin
[ALPHA_BUILTIN_max
] = {
6361 CODE_FOR_builtin_cmpbge
,
6369 CODE_FOR_builtin_insbl
,
6370 CODE_FOR_builtin_inswl
,
6371 CODE_FOR_builtin_insll
,
6383 CODE_FOR_umuldi3_highpart
,
6384 CODE_FOR_builtin_zap
,
6385 CODE_FOR_builtin_zapnot
,
6386 CODE_FOR_builtin_amask
,
6387 CODE_FOR_builtin_implver
,
6388 CODE_FOR_builtin_rpcc
,
6389 CODE_FOR_builtin_establish_vms_condition_handler
,
6390 CODE_FOR_builtin_revert_vms_condition_handler
,
6393 CODE_FOR_builtin_minub8
,
6394 CODE_FOR_builtin_minsb8
,
6395 CODE_FOR_builtin_minuw4
,
6396 CODE_FOR_builtin_minsw4
,
6397 CODE_FOR_builtin_maxub8
,
6398 CODE_FOR_builtin_maxsb8
,
6399 CODE_FOR_builtin_maxuw4
,
6400 CODE_FOR_builtin_maxsw4
,
6401 CODE_FOR_builtin_perr
,
6402 CODE_FOR_builtin_pklb
,
6403 CODE_FOR_builtin_pkwb
,
6404 CODE_FOR_builtin_unpkbl
,
6405 CODE_FOR_builtin_unpkbw
,
6410 CODE_FOR_popcountdi2
6413 struct alpha_builtin_def
6416 enum alpha_builtin code
;
6417 unsigned int target_mask
;
6421 static struct alpha_builtin_def
const zero_arg_builtins
[] = {
6422 { "__builtin_alpha_implver", ALPHA_BUILTIN_IMPLVER
, 0, true },
6423 { "__builtin_alpha_rpcc", ALPHA_BUILTIN_RPCC
, 0, false }
6426 static struct alpha_builtin_def
const one_arg_builtins
[] = {
6427 { "__builtin_alpha_amask", ALPHA_BUILTIN_AMASK
, 0, true },
6428 { "__builtin_alpha_pklb", ALPHA_BUILTIN_PKLB
, MASK_MAX
, true },
6429 { "__builtin_alpha_pkwb", ALPHA_BUILTIN_PKWB
, MASK_MAX
, true },
6430 { "__builtin_alpha_unpkbl", ALPHA_BUILTIN_UNPKBL
, MASK_MAX
, true },
6431 { "__builtin_alpha_unpkbw", ALPHA_BUILTIN_UNPKBW
, MASK_MAX
, true },
6432 { "__builtin_alpha_cttz", ALPHA_BUILTIN_CTTZ
, MASK_CIX
, true },
6433 { "__builtin_alpha_ctlz", ALPHA_BUILTIN_CTLZ
, MASK_CIX
, true },
6434 { "__builtin_alpha_ctpop", ALPHA_BUILTIN_CTPOP
, MASK_CIX
, true }
6437 static struct alpha_builtin_def
const two_arg_builtins
[] = {
6438 { "__builtin_alpha_cmpbge", ALPHA_BUILTIN_CMPBGE
, 0, true },
6439 { "__builtin_alpha_extbl", ALPHA_BUILTIN_EXTBL
, 0, true },
6440 { "__builtin_alpha_extwl", ALPHA_BUILTIN_EXTWL
, 0, true },
6441 { "__builtin_alpha_extll", ALPHA_BUILTIN_EXTLL
, 0, true },
6442 { "__builtin_alpha_extql", ALPHA_BUILTIN_EXTQL
, 0, true },
6443 { "__builtin_alpha_extwh", ALPHA_BUILTIN_EXTWH
, 0, true },
6444 { "__builtin_alpha_extlh", ALPHA_BUILTIN_EXTLH
, 0, true },
6445 { "__builtin_alpha_extqh", ALPHA_BUILTIN_EXTQH
, 0, true },
6446 { "__builtin_alpha_insbl", ALPHA_BUILTIN_INSBL
, 0, true },
6447 { "__builtin_alpha_inswl", ALPHA_BUILTIN_INSWL
, 0, true },
6448 { "__builtin_alpha_insll", ALPHA_BUILTIN_INSLL
, 0, true },
6449 { "__builtin_alpha_insql", ALPHA_BUILTIN_INSQL
, 0, true },
6450 { "__builtin_alpha_inswh", ALPHA_BUILTIN_INSWH
, 0, true },
6451 { "__builtin_alpha_inslh", ALPHA_BUILTIN_INSLH
, 0, true },
6452 { "__builtin_alpha_insqh", ALPHA_BUILTIN_INSQH
, 0, true },
6453 { "__builtin_alpha_mskbl", ALPHA_BUILTIN_MSKBL
, 0, true },
6454 { "__builtin_alpha_mskwl", ALPHA_BUILTIN_MSKWL
, 0, true },
6455 { "__builtin_alpha_mskll", ALPHA_BUILTIN_MSKLL
, 0, true },
6456 { "__builtin_alpha_mskql", ALPHA_BUILTIN_MSKQL
, 0, true },
6457 { "__builtin_alpha_mskwh", ALPHA_BUILTIN_MSKWH
, 0, true },
6458 { "__builtin_alpha_msklh", ALPHA_BUILTIN_MSKLH
, 0, true },
6459 { "__builtin_alpha_mskqh", ALPHA_BUILTIN_MSKQH
, 0, true },
6460 { "__builtin_alpha_umulh", ALPHA_BUILTIN_UMULH
, 0, true },
6461 { "__builtin_alpha_zap", ALPHA_BUILTIN_ZAP
, 0, true },
6462 { "__builtin_alpha_zapnot", ALPHA_BUILTIN_ZAPNOT
, 0, true },
6463 { "__builtin_alpha_minub8", ALPHA_BUILTIN_MINUB8
, MASK_MAX
, true },
6464 { "__builtin_alpha_minsb8", ALPHA_BUILTIN_MINSB8
, MASK_MAX
, true },
6465 { "__builtin_alpha_minuw4", ALPHA_BUILTIN_MINUW4
, MASK_MAX
, true },
6466 { "__builtin_alpha_minsw4", ALPHA_BUILTIN_MINSW4
, MASK_MAX
, true },
6467 { "__builtin_alpha_maxub8", ALPHA_BUILTIN_MAXUB8
, MASK_MAX
, true },
6468 { "__builtin_alpha_maxsb8", ALPHA_BUILTIN_MAXSB8
, MASK_MAX
, true },
6469 { "__builtin_alpha_maxuw4", ALPHA_BUILTIN_MAXUW4
, MASK_MAX
, true },
6470 { "__builtin_alpha_maxsw4", ALPHA_BUILTIN_MAXSW4
, MASK_MAX
, true },
6471 { "__builtin_alpha_perr", ALPHA_BUILTIN_PERR
, MASK_MAX
, true }
6474 static GTY(()) tree alpha_dimode_u
;
6475 static GTY(()) tree alpha_v8qi_u
;
6476 static GTY(()) tree alpha_v8qi_s
;
6477 static GTY(()) tree alpha_v4hi_u
;
6478 static GTY(()) tree alpha_v4hi_s
;
6480 static GTY(()) tree alpha_builtins
[(int) ALPHA_BUILTIN_max
];
6482 /* Return the alpha builtin for CODE. */
6485 alpha_builtin_decl (unsigned code
, bool initialize_p ATTRIBUTE_UNUSED
)
6487 if (code
>= ALPHA_BUILTIN_max
)
6488 return error_mark_node
;
6489 return alpha_builtins
[code
];
6492 /* Helper function of alpha_init_builtins. Add the built-in specified
6493 by NAME, TYPE, CODE, and ECF. */
6496 alpha_builtin_function (const char *name
, tree ftype
,
6497 enum alpha_builtin code
, unsigned ecf
)
6499 tree decl
= add_builtin_function (name
, ftype
, (int) code
,
6500 BUILT_IN_MD
, NULL
, NULL_TREE
);
6502 if (ecf
& ECF_CONST
)
6503 TREE_READONLY (decl
) = 1;
6504 if (ecf
& ECF_NOTHROW
)
6505 TREE_NOTHROW (decl
) = 1;
6507 alpha_builtins
[(int) code
] = decl
;
6510 /* Helper function of alpha_init_builtins. Add the COUNT built-in
6511 functions pointed to by P, with function type FTYPE. */
6514 alpha_add_builtins (const struct alpha_builtin_def
*p
, size_t count
,
6519 for (i
= 0; i
< count
; ++i
, ++p
)
6520 if ((target_flags
& p
->target_mask
) == p
->target_mask
)
6521 alpha_builtin_function (p
->name
, ftype
, p
->code
,
6522 (p
->is_const
? ECF_CONST
: 0) | ECF_NOTHROW
);
6526 alpha_init_builtins (void)
6530 alpha_dimode_u
= lang_hooks
.types
.type_for_mode (DImode
, 1);
6531 alpha_v8qi_u
= build_vector_type (unsigned_intQI_type_node
, 8);
6532 alpha_v8qi_s
= build_vector_type (intQI_type_node
, 8);
6533 alpha_v4hi_u
= build_vector_type (unsigned_intHI_type_node
, 4);
6534 alpha_v4hi_s
= build_vector_type (intHI_type_node
, 4);
6536 ftype
= build_function_type_list (alpha_dimode_u
, NULL_TREE
);
6537 alpha_add_builtins (zero_arg_builtins
, ARRAY_SIZE (zero_arg_builtins
), ftype
);
6539 ftype
= build_function_type_list (alpha_dimode_u
, alpha_dimode_u
, NULL_TREE
);
6540 alpha_add_builtins (one_arg_builtins
, ARRAY_SIZE (one_arg_builtins
), ftype
);
6542 ftype
= build_function_type_list (alpha_dimode_u
, alpha_dimode_u
,
6543 alpha_dimode_u
, NULL_TREE
);
6544 alpha_add_builtins (two_arg_builtins
, ARRAY_SIZE (two_arg_builtins
), ftype
);
6546 if (TARGET_ABI_OPEN_VMS
)
6548 ftype
= build_function_type_list (ptr_type_node
, ptr_type_node
,
6550 alpha_builtin_function ("__builtin_establish_vms_condition_handler",
6552 ALPHA_BUILTIN_ESTABLISH_VMS_CONDITION_HANDLER
,
6555 ftype
= build_function_type_list (ptr_type_node
, void_type_node
,
6557 alpha_builtin_function ("__builtin_revert_vms_condition_handler", ftype
,
6558 ALPHA_BUILTIN_REVERT_VMS_CONDITION_HANDLER
, 0);
6560 vms_patch_builtins ();
6564 /* Expand an expression EXP that calls a built-in function,
6565 with result going to TARGET if that's convenient
6566 (and in mode MODE if that's convenient).
6567 SUBTARGET may be used as the target for computing one of EXP's operands.
6568 IGNORE is nonzero if the value is to be ignored. */
6571 alpha_expand_builtin (tree exp
, rtx target
,
6572 rtx subtarget ATTRIBUTE_UNUSED
,
6573 enum machine_mode mode ATTRIBUTE_UNUSED
,
6574 int ignore ATTRIBUTE_UNUSED
)
6578 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
6579 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
6581 call_expr_arg_iterator iter
;
6582 enum insn_code icode
;
6583 rtx op
[MAX_ARGS
], pat
;
6587 if (fcode
>= ALPHA_BUILTIN_max
)
6588 internal_error ("bad builtin fcode");
6589 icode
= code_for_builtin
[fcode
];
6591 internal_error ("bad builtin fcode");
6593 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
6596 FOR_EACH_CALL_EXPR_ARG (arg
, iter
, exp
)
6598 const struct insn_operand_data
*insn_op
;
6600 if (arg
== error_mark_node
)
6602 if (arity
> MAX_ARGS
)
6605 insn_op
= &insn_data
[icode
].operand
[arity
+ nonvoid
];
6607 op
[arity
] = expand_expr (arg
, NULL_RTX
, insn_op
->mode
, EXPAND_NORMAL
);
6609 if (!(*insn_op
->predicate
) (op
[arity
], insn_op
->mode
))
6610 op
[arity
] = copy_to_mode_reg (insn_op
->mode
, op
[arity
]);
6616 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6618 || GET_MODE (target
) != tmode
6619 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6620 target
= gen_reg_rtx (tmode
);
6626 pat
= GEN_FCN (icode
) (target
);
6630 pat
= GEN_FCN (icode
) (target
, op
[0]);
6632 pat
= GEN_FCN (icode
) (op
[0]);
6635 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
6651 /* Several bits below assume HWI >= 64 bits. This should be enforced
6653 #if HOST_BITS_PER_WIDE_INT < 64
6654 # error "HOST_WIDE_INT too small"
6657 /* Fold the builtin for the CMPBGE instruction. This is a vector comparison
6658 with an 8-bit output vector. OPINT contains the integer operands; bit N
6659 of OP_CONST is set if OPINT[N] is valid. */
6662 alpha_fold_builtin_cmpbge (unsigned HOST_WIDE_INT opint
[], long op_const
)
6667 for (i
= 0, val
= 0; i
< 8; ++i
)
6669 unsigned HOST_WIDE_INT c0
= (opint
[0] >> (i
* 8)) & 0xff;
6670 unsigned HOST_WIDE_INT c1
= (opint
[1] >> (i
* 8)) & 0xff;
6674 return build_int_cst (alpha_dimode_u
, val
);
6676 else if (op_const
== 2 && opint
[1] == 0)
6677 return build_int_cst (alpha_dimode_u
, 0xff);
6681 /* Fold the builtin for the ZAPNOT instruction. This is essentially a
6682 specialized form of an AND operation. Other byte manipulation instructions
6683 are defined in terms of this instruction, so this is also used as a
6684 subroutine for other builtins.
6686 OP contains the tree operands; OPINT contains the extracted integer values.
6687 Bit N of OP_CONST it set if OPINT[N] is valid. OP may be null if only
6688 OPINT may be considered. */
6691 alpha_fold_builtin_zapnot (tree
*op
, unsigned HOST_WIDE_INT opint
[],
6696 unsigned HOST_WIDE_INT mask
= 0;
6699 for (i
= 0; i
< 8; ++i
)
6700 if ((opint
[1] >> i
) & 1)
6701 mask
|= (unsigned HOST_WIDE_INT
)0xff << (i
* 8);
6704 return build_int_cst (alpha_dimode_u
, opint
[0] & mask
);
6707 return fold_build2 (BIT_AND_EXPR
, alpha_dimode_u
, op
[0],
6708 build_int_cst (alpha_dimode_u
, mask
));
6710 else if ((op_const
& 1) && opint
[0] == 0)
6711 return build_int_cst (alpha_dimode_u
, 0);
6715 /* Fold the builtins for the EXT family of instructions. */
6718 alpha_fold_builtin_extxx (tree op
[], unsigned HOST_WIDE_INT opint
[],
6719 long op_const
, unsigned HOST_WIDE_INT bytemask
,
6723 tree
*zap_op
= NULL
;
6727 unsigned HOST_WIDE_INT loc
;
6730 loc
*= BITS_PER_UNIT
;
6736 unsigned HOST_WIDE_INT temp
= opint
[0];
6749 opint
[1] = bytemask
;
6750 return alpha_fold_builtin_zapnot (zap_op
, opint
, zap_const
);
6753 /* Fold the builtins for the INS family of instructions. */
6756 alpha_fold_builtin_insxx (tree op
[], unsigned HOST_WIDE_INT opint
[],
6757 long op_const
, unsigned HOST_WIDE_INT bytemask
,
6760 if ((op_const
& 1) && opint
[0] == 0)
6761 return build_int_cst (alpha_dimode_u
, 0);
6765 unsigned HOST_WIDE_INT temp
, loc
, byteloc
;
6766 tree
*zap_op
= NULL
;
6774 byteloc
= (64 - (loc
* 8)) & 0x3f;
6791 opint
[1] = bytemask
;
6792 return alpha_fold_builtin_zapnot (zap_op
, opint
, op_const
);
6799 alpha_fold_builtin_mskxx (tree op
[], unsigned HOST_WIDE_INT opint
[],
6800 long op_const
, unsigned HOST_WIDE_INT bytemask
,
6805 unsigned HOST_WIDE_INT loc
;
6813 opint
[1] = bytemask
^ 0xff;
6816 return alpha_fold_builtin_zapnot (op
, opint
, op_const
);
6820 alpha_fold_vector_minmax (enum tree_code code
, tree op
[], tree vtype
)
6822 tree op0
= fold_convert (vtype
, op
[0]);
6823 tree op1
= fold_convert (vtype
, op
[1]);
6824 tree val
= fold_build2 (code
, vtype
, op0
, op1
);
6825 return fold_build1 (VIEW_CONVERT_EXPR
, alpha_dimode_u
, val
);
6829 alpha_fold_builtin_perr (unsigned HOST_WIDE_INT opint
[], long op_const
)
6831 unsigned HOST_WIDE_INT temp
= 0;
6837 for (i
= 0; i
< 8; ++i
)
6839 unsigned HOST_WIDE_INT a
= (opint
[0] >> (i
* 8)) & 0xff;
6840 unsigned HOST_WIDE_INT b
= (opint
[1] >> (i
* 8)) & 0xff;
6847 return build_int_cst (alpha_dimode_u
, temp
);
6851 alpha_fold_builtin_pklb (unsigned HOST_WIDE_INT opint
[], long op_const
)
6853 unsigned HOST_WIDE_INT temp
;
6858 temp
= opint
[0] & 0xff;
6859 temp
|= (opint
[0] >> 24) & 0xff00;
6861 return build_int_cst (alpha_dimode_u
, temp
);
6865 alpha_fold_builtin_pkwb (unsigned HOST_WIDE_INT opint
[], long op_const
)
6867 unsigned HOST_WIDE_INT temp
;
6872 temp
= opint
[0] & 0xff;
6873 temp
|= (opint
[0] >> 8) & 0xff00;
6874 temp
|= (opint
[0] >> 16) & 0xff0000;
6875 temp
|= (opint
[0] >> 24) & 0xff000000;
6877 return build_int_cst (alpha_dimode_u
, temp
);
6881 alpha_fold_builtin_unpkbl (unsigned HOST_WIDE_INT opint
[], long op_const
)
6883 unsigned HOST_WIDE_INT temp
;
6888 temp
= opint
[0] & 0xff;
6889 temp
|= (opint
[0] & 0xff00) << 24;
6891 return build_int_cst (alpha_dimode_u
, temp
);
6895 alpha_fold_builtin_unpkbw (unsigned HOST_WIDE_INT opint
[], long op_const
)
6897 unsigned HOST_WIDE_INT temp
;
6902 temp
= opint
[0] & 0xff;
6903 temp
|= (opint
[0] & 0x0000ff00) << 8;
6904 temp
|= (opint
[0] & 0x00ff0000) << 16;
6905 temp
|= (opint
[0] & 0xff000000) << 24;
6907 return build_int_cst (alpha_dimode_u
, temp
);
6911 alpha_fold_builtin_cttz (unsigned HOST_WIDE_INT opint
[], long op_const
)
6913 unsigned HOST_WIDE_INT temp
;
6921 temp
= exact_log2 (opint
[0] & -opint
[0]);
6923 return build_int_cst (alpha_dimode_u
, temp
);
6927 alpha_fold_builtin_ctlz (unsigned HOST_WIDE_INT opint
[], long op_const
)
6929 unsigned HOST_WIDE_INT temp
;
6937 temp
= 64 - floor_log2 (opint
[0]) - 1;
6939 return build_int_cst (alpha_dimode_u
, temp
);
6943 alpha_fold_builtin_ctpop (unsigned HOST_WIDE_INT opint
[], long op_const
)
6945 unsigned HOST_WIDE_INT temp
, op
;
6953 temp
++, op
&= op
- 1;
6955 return build_int_cst (alpha_dimode_u
, temp
);
6958 /* Fold one of our builtin functions. */
6961 alpha_fold_builtin (tree fndecl
, int n_args
, tree
*op
,
6962 bool ignore ATTRIBUTE_UNUSED
)
6964 unsigned HOST_WIDE_INT opint
[MAX_ARGS
];
6968 if (n_args
> MAX_ARGS
)
6971 for (i
= 0; i
< n_args
; i
++)
6974 if (arg
== error_mark_node
)
6978 if (TREE_CODE (arg
) == INTEGER_CST
)
6980 op_const
|= 1L << i
;
6981 opint
[i
] = int_cst_value (arg
);
6985 switch (DECL_FUNCTION_CODE (fndecl
))
6987 case ALPHA_BUILTIN_CMPBGE
:
6988 return alpha_fold_builtin_cmpbge (opint
, op_const
);
6990 case ALPHA_BUILTIN_EXTBL
:
6991 return alpha_fold_builtin_extxx (op
, opint
, op_const
, 0x01, false);
6992 case ALPHA_BUILTIN_EXTWL
:
6993 return alpha_fold_builtin_extxx (op
, opint
, op_const
, 0x03, false);
6994 case ALPHA_BUILTIN_EXTLL
:
6995 return alpha_fold_builtin_extxx (op
, opint
, op_const
, 0x0f, false);
6996 case ALPHA_BUILTIN_EXTQL
:
6997 return alpha_fold_builtin_extxx (op
, opint
, op_const
, 0xff, false);
6998 case ALPHA_BUILTIN_EXTWH
:
6999 return alpha_fold_builtin_extxx (op
, opint
, op_const
, 0x03, true);
7000 case ALPHA_BUILTIN_EXTLH
:
7001 return alpha_fold_builtin_extxx (op
, opint
, op_const
, 0x0f, true);
7002 case ALPHA_BUILTIN_EXTQH
:
7003 return alpha_fold_builtin_extxx (op
, opint
, op_const
, 0xff, true);
7005 case ALPHA_BUILTIN_INSBL
:
7006 return alpha_fold_builtin_insxx (op
, opint
, op_const
, 0x01, false);
7007 case ALPHA_BUILTIN_INSWL
:
7008 return alpha_fold_builtin_insxx (op
, opint
, op_const
, 0x03, false);
7009 case ALPHA_BUILTIN_INSLL
:
7010 return alpha_fold_builtin_insxx (op
, opint
, op_const
, 0x0f, false);
7011 case ALPHA_BUILTIN_INSQL
:
7012 return alpha_fold_builtin_insxx (op
, opint
, op_const
, 0xff, false);
7013 case ALPHA_BUILTIN_INSWH
:
7014 return alpha_fold_builtin_insxx (op
, opint
, op_const
, 0x03, true);
7015 case ALPHA_BUILTIN_INSLH
:
7016 return alpha_fold_builtin_insxx (op
, opint
, op_const
, 0x0f, true);
7017 case ALPHA_BUILTIN_INSQH
:
7018 return alpha_fold_builtin_insxx (op
, opint
, op_const
, 0xff, true);
7020 case ALPHA_BUILTIN_MSKBL
:
7021 return alpha_fold_builtin_mskxx (op
, opint
, op_const
, 0x01, false);
7022 case ALPHA_BUILTIN_MSKWL
:
7023 return alpha_fold_builtin_mskxx (op
, opint
, op_const
, 0x03, false);
7024 case ALPHA_BUILTIN_MSKLL
:
7025 return alpha_fold_builtin_mskxx (op
, opint
, op_const
, 0x0f, false);
7026 case ALPHA_BUILTIN_MSKQL
:
7027 return alpha_fold_builtin_mskxx (op
, opint
, op_const
, 0xff, false);
7028 case ALPHA_BUILTIN_MSKWH
:
7029 return alpha_fold_builtin_mskxx (op
, opint
, op_const
, 0x03, true);
7030 case ALPHA_BUILTIN_MSKLH
:
7031 return alpha_fold_builtin_mskxx (op
, opint
, op_const
, 0x0f, true);
7032 case ALPHA_BUILTIN_MSKQH
:
7033 return alpha_fold_builtin_mskxx (op
, opint
, op_const
, 0xff, true);
7035 case ALPHA_BUILTIN_UMULH
:
7036 return fold_build2 (MULT_HIGHPART_EXPR
, alpha_dimode_u
, op
[0], op
[1]);
7038 case ALPHA_BUILTIN_ZAP
:
7041 case ALPHA_BUILTIN_ZAPNOT
:
7042 return alpha_fold_builtin_zapnot (op
, opint
, op_const
);
7044 case ALPHA_BUILTIN_MINUB8
:
7045 return alpha_fold_vector_minmax (MIN_EXPR
, op
, alpha_v8qi_u
);
7046 case ALPHA_BUILTIN_MINSB8
:
7047 return alpha_fold_vector_minmax (MIN_EXPR
, op
, alpha_v8qi_s
);
7048 case ALPHA_BUILTIN_MINUW4
:
7049 return alpha_fold_vector_minmax (MIN_EXPR
, op
, alpha_v4hi_u
);
7050 case ALPHA_BUILTIN_MINSW4
:
7051 return alpha_fold_vector_minmax (MIN_EXPR
, op
, alpha_v4hi_s
);
7052 case ALPHA_BUILTIN_MAXUB8
:
7053 return alpha_fold_vector_minmax (MAX_EXPR
, op
, alpha_v8qi_u
);
7054 case ALPHA_BUILTIN_MAXSB8
:
7055 return alpha_fold_vector_minmax (MAX_EXPR
, op
, alpha_v8qi_s
);
7056 case ALPHA_BUILTIN_MAXUW4
:
7057 return alpha_fold_vector_minmax (MAX_EXPR
, op
, alpha_v4hi_u
);
7058 case ALPHA_BUILTIN_MAXSW4
:
7059 return alpha_fold_vector_minmax (MAX_EXPR
, op
, alpha_v4hi_s
);
7061 case ALPHA_BUILTIN_PERR
:
7062 return alpha_fold_builtin_perr (opint
, op_const
);
7063 case ALPHA_BUILTIN_PKLB
:
7064 return alpha_fold_builtin_pklb (opint
, op_const
);
7065 case ALPHA_BUILTIN_PKWB
:
7066 return alpha_fold_builtin_pkwb (opint
, op_const
);
7067 case ALPHA_BUILTIN_UNPKBL
:
7068 return alpha_fold_builtin_unpkbl (opint
, op_const
);
7069 case ALPHA_BUILTIN_UNPKBW
:
7070 return alpha_fold_builtin_unpkbw (opint
, op_const
);
7072 case ALPHA_BUILTIN_CTTZ
:
7073 return alpha_fold_builtin_cttz (opint
, op_const
);
7074 case ALPHA_BUILTIN_CTLZ
:
7075 return alpha_fold_builtin_ctlz (opint
, op_const
);
7076 case ALPHA_BUILTIN_CTPOP
:
7077 return alpha_fold_builtin_ctpop (opint
, op_const
);
7079 case ALPHA_BUILTIN_AMASK
:
7080 case ALPHA_BUILTIN_IMPLVER
:
7081 case ALPHA_BUILTIN_RPCC
:
7082 /* None of these are foldable at compile-time. */
7088 /* This page contains routines that are used to determine what the function
7089 prologue and epilogue code will do and write them out. */
7091 /* Compute the size of the save area in the stack. */
7093 /* These variables are used for communication between the following functions.
7094 They indicate various things about the current function being compiled
7095 that are used to tell what kind of prologue, epilogue and procedure
7096 descriptor to generate. */
7098 /* Nonzero if we need a stack procedure. */
7099 enum alpha_procedure_types
{PT_NULL
= 0, PT_REGISTER
= 1, PT_STACK
= 2};
7100 static enum alpha_procedure_types alpha_procedure_type
;
7102 /* Register number (either FP or SP) that is used to unwind the frame. */
7103 static int vms_unwind_regno
;
7105 /* Register number used to save FP. We need not have one for RA since
7106 we don't modify it for register procedures. This is only defined
7107 for register frame procedures. */
7108 static int vms_save_fp_regno
;
7110 /* Register number used to reference objects off our PV. */
7111 static int vms_base_regno
;
7113 /* Compute register masks for saved registers. */
7116 alpha_sa_mask (unsigned long *imaskP
, unsigned long *fmaskP
)
7118 unsigned long imask
= 0;
7119 unsigned long fmask
= 0;
7122 /* When outputting a thunk, we don't have valid register life info,
7123 but assemble_start_function wants to output .frame and .mask
7132 if (TARGET_ABI_OPEN_VMS
&& alpha_procedure_type
== PT_STACK
)
7133 imask
|= (1UL << HARD_FRAME_POINTER_REGNUM
);
7135 /* One for every register we have to save. */
7136 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
7137 if (! fixed_regs
[i
] && ! call_used_regs
[i
]
7138 && df_regs_ever_live_p (i
) && i
!= REG_RA
)
7141 imask
|= (1UL << i
);
7143 fmask
|= (1UL << (i
- 32));
7146 /* We need to restore these for the handler. */
7147 if (crtl
->calls_eh_return
)
7151 unsigned regno
= EH_RETURN_DATA_REGNO (i
);
7152 if (regno
== INVALID_REGNUM
)
7154 imask
|= 1UL << regno
;
7158 /* If any register spilled, then spill the return address also. */
7159 /* ??? This is required by the Digital stack unwind specification
7160 and isn't needed if we're doing Dwarf2 unwinding. */
7161 if (imask
|| fmask
|| alpha_ra_ever_killed ())
7162 imask
|= (1UL << REG_RA
);
7169 alpha_sa_size (void)
7171 unsigned long mask
[2];
7175 alpha_sa_mask (&mask
[0], &mask
[1]);
7177 for (j
= 0; j
< 2; ++j
)
7178 for (i
= 0; i
< 32; ++i
)
7179 if ((mask
[j
] >> i
) & 1)
7182 if (TARGET_ABI_OPEN_VMS
)
7184 /* Start with a stack procedure if we make any calls (REG_RA used), or
7185 need a frame pointer, with a register procedure if we otherwise need
7186 at least a slot, and with a null procedure in other cases. */
7187 if ((mask
[0] >> REG_RA
) & 1 || frame_pointer_needed
)
7188 alpha_procedure_type
= PT_STACK
;
7189 else if (get_frame_size() != 0)
7190 alpha_procedure_type
= PT_REGISTER
;
7192 alpha_procedure_type
= PT_NULL
;
7194 /* Don't reserve space for saving FP & RA yet. Do that later after we've
7195 made the final decision on stack procedure vs register procedure. */
7196 if (alpha_procedure_type
== PT_STACK
)
7199 /* Decide whether to refer to objects off our PV via FP or PV.
7200 If we need FP for something else or if we receive a nonlocal
7201 goto (which expects PV to contain the value), we must use PV.
7202 Otherwise, start by assuming we can use FP. */
7205 = (frame_pointer_needed
7206 || cfun
->has_nonlocal_label
7207 || alpha_procedure_type
== PT_STACK
7208 || crtl
->outgoing_args_size
)
7209 ? REG_PV
: HARD_FRAME_POINTER_REGNUM
;
7211 /* If we want to copy PV into FP, we need to find some register
7212 in which to save FP. */
7214 vms_save_fp_regno
= -1;
7215 if (vms_base_regno
== HARD_FRAME_POINTER_REGNUM
)
7216 for (i
= 0; i
< 32; i
++)
7217 if (! fixed_regs
[i
] && call_used_regs
[i
] && ! df_regs_ever_live_p (i
))
7218 vms_save_fp_regno
= i
;
7220 /* A VMS condition handler requires a stack procedure in our
7221 implementation. (not required by the calling standard). */
7222 if ((vms_save_fp_regno
== -1 && alpha_procedure_type
== PT_REGISTER
)
7223 || cfun
->machine
->uses_condition_handler
)
7224 vms_base_regno
= REG_PV
, alpha_procedure_type
= PT_STACK
;
7225 else if (alpha_procedure_type
== PT_NULL
)
7226 vms_base_regno
= REG_PV
;
7228 /* Stack unwinding should be done via FP unless we use it for PV. */
7229 vms_unwind_regno
= (vms_base_regno
== REG_PV
7230 ? HARD_FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
);
7232 /* If this is a stack procedure, allow space for saving FP, RA and
7233 a condition handler slot if needed. */
7234 if (alpha_procedure_type
== PT_STACK
)
7235 sa_size
+= 2 + cfun
->machine
->uses_condition_handler
;
7239 /* Our size must be even (multiple of 16 bytes). */
7247 /* Define the offset between two registers, one to be eliminated,
7248 and the other its replacement, at the start of a routine. */
7251 alpha_initial_elimination_offset (unsigned int from
,
7252 unsigned int to ATTRIBUTE_UNUSED
)
7256 ret
= alpha_sa_size ();
7257 ret
+= ALPHA_ROUND (crtl
->outgoing_args_size
);
7261 case FRAME_POINTER_REGNUM
:
7264 case ARG_POINTER_REGNUM
:
7265 ret
+= (ALPHA_ROUND (get_frame_size ()
7266 + crtl
->args
.pretend_args_size
)
7267 - crtl
->args
.pretend_args_size
);
7277 #if TARGET_ABI_OPEN_VMS
7279 /* Worker function for TARGET_CAN_ELIMINATE. */
7282 alpha_vms_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
7284 /* We need the alpha_procedure_type to decide. Evaluate it now. */
7287 switch (alpha_procedure_type
)
7290 /* NULL procedures have no frame of their own and we only
7291 know how to resolve from the current stack pointer. */
7292 return to
== STACK_POINTER_REGNUM
;
7296 /* We always eliminate except to the stack pointer if there is no
7297 usable frame pointer at hand. */
7298 return (to
!= STACK_POINTER_REGNUM
7299 || vms_unwind_regno
!= HARD_FRAME_POINTER_REGNUM
);
7305 /* FROM is to be eliminated for TO. Return the offset so that TO+offset
7306 designates the same location as FROM. */
7309 alpha_vms_initial_elimination_offset (unsigned int from
, unsigned int to
)
7311 /* The only possible attempts we ever expect are ARG or FRAME_PTR to
7312 HARD_FRAME or STACK_PTR. We need the alpha_procedure_type to decide
7313 on the proper computations and will need the register save area size
7316 HOST_WIDE_INT sa_size
= alpha_sa_size ();
7318 /* PT_NULL procedures have no frame of their own and we only allow
7319 elimination to the stack pointer. This is the argument pointer and we
7320 resolve the soft frame pointer to that as well. */
7322 if (alpha_procedure_type
== PT_NULL
)
7325 /* For a PT_STACK procedure the frame layout looks as follows
7327 -----> decreasing addresses
7329 < size rounded up to 16 | likewise >
7330 --------------#------------------------------+++--------------+++-------#
7331 incoming args # pretended args | "frame" | regs sa | PV | outgoing args #
7332 --------------#---------------------------------------------------------#
7334 ARG_PTR FRAME_PTR HARD_FRAME_PTR STACK_PTR
7337 PT_REGISTER procedures are similar in that they may have a frame of their
7338 own. They have no regs-sa/pv/outgoing-args area.
7340 We first compute offset to HARD_FRAME_PTR, then add what we need to get
7341 to STACK_PTR if need be. */
7344 HOST_WIDE_INT offset
;
7345 HOST_WIDE_INT pv_save_size
= alpha_procedure_type
== PT_STACK
? 8 : 0;
7349 case FRAME_POINTER_REGNUM
:
7350 offset
= ALPHA_ROUND (sa_size
+ pv_save_size
);
7352 case ARG_POINTER_REGNUM
:
7353 offset
= (ALPHA_ROUND (sa_size
+ pv_save_size
7355 + crtl
->args
.pretend_args_size
)
7356 - crtl
->args
.pretend_args_size
);
7362 if (to
== STACK_POINTER_REGNUM
)
7363 offset
+= ALPHA_ROUND (crtl
->outgoing_args_size
);
7369 #define COMMON_OBJECT "common_object"
7372 common_object_handler (tree
*node
, tree name ATTRIBUTE_UNUSED
,
7373 tree args ATTRIBUTE_UNUSED
, int flags ATTRIBUTE_UNUSED
,
7374 bool *no_add_attrs ATTRIBUTE_UNUSED
)
7377 gcc_assert (DECL_P (decl
));
7379 DECL_COMMON (decl
) = 1;
7383 static const struct attribute_spec vms_attribute_table
[] =
7385 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
7386 affects_type_identity } */
7387 { COMMON_OBJECT
, 0, 1, true, false, false, common_object_handler
, false },
7388 { NULL
, 0, 0, false, false, false, NULL
, false }
7392 vms_output_aligned_decl_common(FILE *file
, tree decl
, const char *name
,
7393 unsigned HOST_WIDE_INT size
,
7396 tree attr
= DECL_ATTRIBUTES (decl
);
7397 fprintf (file
, "%s", COMMON_ASM_OP
);
7398 assemble_name (file
, name
);
7399 fprintf (file
, "," HOST_WIDE_INT_PRINT_UNSIGNED
, size
);
7400 /* ??? Unlike on OSF/1, the alignment factor is not in log units. */
7401 fprintf (file
, ",%u", align
/ BITS_PER_UNIT
);
7404 attr
= lookup_attribute (COMMON_OBJECT
, attr
);
7406 fprintf (file
, ",%s",
7407 IDENTIFIER_POINTER (TREE_VALUE (TREE_VALUE (attr
))));
7412 #undef COMMON_OBJECT
7417 find_lo_sum_using_gp (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
7419 return GET_CODE (*px
) == LO_SUM
&& XEXP (*px
, 0) == pic_offset_table_rtx
;
7423 alpha_find_lo_sum_using_gp (rtx insn
)
7425 return for_each_rtx (&PATTERN (insn
), find_lo_sum_using_gp
, NULL
) > 0;
7429 alpha_does_function_need_gp (void)
7433 /* The GP being variable is an OSF abi thing. */
7434 if (! TARGET_ABI_OSF
)
7437 /* We need the gp to load the address of __mcount. */
7438 if (TARGET_PROFILING_NEEDS_GP
&& crtl
->profile
)
7441 /* The code emitted by alpha_output_mi_thunk_osf uses the gp. */
7445 /* The nonlocal receiver pattern assumes that the gp is valid for
7446 the nested function. Reasonable because it's almost always set
7447 correctly already. For the cases where that's wrong, make sure
7448 the nested function loads its gp on entry. */
7449 if (crtl
->has_nonlocal_goto
)
7452 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
7453 Even if we are a static function, we still need to do this in case
7454 our address is taken and passed to something like qsort. */
7456 push_topmost_sequence ();
7457 insn
= get_insns ();
7458 pop_topmost_sequence ();
7460 for (; insn
; insn
= NEXT_INSN (insn
))
7461 if (NONDEBUG_INSN_P (insn
)
7462 && GET_CODE (PATTERN (insn
)) != USE
7463 && GET_CODE (PATTERN (insn
)) != CLOBBER
7464 && get_attr_usegp (insn
))
7471 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
7475 set_frame_related_p (void)
7477 rtx seq
= get_insns ();
7488 while (insn
!= NULL_RTX
)
7490 RTX_FRAME_RELATED_P (insn
) = 1;
7491 insn
= NEXT_INSN (insn
);
7493 seq
= emit_insn (seq
);
7497 seq
= emit_insn (seq
);
7498 RTX_FRAME_RELATED_P (seq
) = 1;
7503 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
7505 /* Generates a store with the proper unwind info attached. VALUE is
7506 stored at BASE_REG+BASE_OFS. If FRAME_BIAS is nonzero, then BASE_REG
7507 contains SP+FRAME_BIAS, and that is the unwind info that should be
7508 generated. If FRAME_REG != VALUE, then VALUE is being stored on
7509 behalf of FRAME_REG, and FRAME_REG should be present in the unwind. */
7512 emit_frame_store_1 (rtx value
, rtx base_reg
, HOST_WIDE_INT frame_bias
,
7513 HOST_WIDE_INT base_ofs
, rtx frame_reg
)
7515 rtx addr
, mem
, insn
;
7517 addr
= plus_constant (Pmode
, base_reg
, base_ofs
);
7518 mem
= gen_frame_mem (DImode
, addr
);
7520 insn
= emit_move_insn (mem
, value
);
7521 RTX_FRAME_RELATED_P (insn
) = 1;
7523 if (frame_bias
|| value
!= frame_reg
)
7527 addr
= plus_constant (Pmode
, stack_pointer_rtx
,
7528 frame_bias
+ base_ofs
);
7529 mem
= gen_rtx_MEM (DImode
, addr
);
7532 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
7533 gen_rtx_SET (VOIDmode
, mem
, frame_reg
));
7538 emit_frame_store (unsigned int regno
, rtx base_reg
,
7539 HOST_WIDE_INT frame_bias
, HOST_WIDE_INT base_ofs
)
7541 rtx reg
= gen_rtx_REG (DImode
, regno
);
7542 emit_frame_store_1 (reg
, base_reg
, frame_bias
, base_ofs
, reg
);
7545 /* Compute the frame size. SIZE is the size of the "naked" frame
7546 and SA_SIZE is the size of the register save area. */
7548 static HOST_WIDE_INT
7549 compute_frame_size (HOST_WIDE_INT size
, HOST_WIDE_INT sa_size
)
7551 if (TARGET_ABI_OPEN_VMS
)
7552 return ALPHA_ROUND (sa_size
7553 + (alpha_procedure_type
== PT_STACK
? 8 : 0)
7555 + crtl
->args
.pretend_args_size
);
7557 return ALPHA_ROUND (crtl
->outgoing_args_size
)
7560 + crtl
->args
.pretend_args_size
);
7563 /* Write function prologue. */
7565 /* On vms we have two kinds of functions:
7567 - stack frame (PROC_STACK)
7568 these are 'normal' functions with local vars and which are
7569 calling other functions
7570 - register frame (PROC_REGISTER)
7571 keeps all data in registers, needs no stack
7573 We must pass this to the assembler so it can generate the
7574 proper pdsc (procedure descriptor)
7575 This is done with the '.pdesc' command.
7577 On not-vms, we don't really differentiate between the two, as we can
7578 simply allocate stack without saving registers. */
7581 alpha_expand_prologue (void)
7583 /* Registers to save. */
7584 unsigned long imask
= 0;
7585 unsigned long fmask
= 0;
7586 /* Stack space needed for pushing registers clobbered by us. */
7587 HOST_WIDE_INT sa_size
, sa_bias
;
7588 /* Complete stack size needed. */
7589 HOST_WIDE_INT frame_size
;
7590 /* Probed stack size; it additionally includes the size of
7591 the "reserve region" if any. */
7592 HOST_WIDE_INT probed_size
;
7593 /* Offset from base reg to register save area. */
7594 HOST_WIDE_INT reg_offset
;
7598 sa_size
= alpha_sa_size ();
7599 frame_size
= compute_frame_size (get_frame_size (), sa_size
);
7601 if (flag_stack_usage_info
)
7602 current_function_static_stack_size
= frame_size
;
7604 if (TARGET_ABI_OPEN_VMS
)
7605 reg_offset
= 8 + 8 * cfun
->machine
->uses_condition_handler
;
7607 reg_offset
= ALPHA_ROUND (crtl
->outgoing_args_size
);
7609 alpha_sa_mask (&imask
, &fmask
);
7611 /* Emit an insn to reload GP, if needed. */
7614 alpha_function_needs_gp
= alpha_does_function_need_gp ();
7615 if (alpha_function_needs_gp
)
7616 emit_insn (gen_prologue_ldgp ());
7619 /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert
7620 the call to mcount ourselves, rather than having the linker do it
7621 magically in response to -pg. Since _mcount has special linkage,
7622 don't represent the call as a call. */
7623 if (TARGET_PROFILING_NEEDS_GP
&& crtl
->profile
)
7624 emit_insn (gen_prologue_mcount ());
7626 /* Adjust the stack by the frame size. If the frame size is > 4096
7627 bytes, we need to be sure we probe somewhere in the first and last
7628 4096 bytes (we can probably get away without the latter test) and
7629 every 8192 bytes in between. If the frame size is > 32768, we
7630 do this in a loop. Otherwise, we generate the explicit probe
7633 Note that we are only allowed to adjust sp once in the prologue. */
7635 probed_size
= frame_size
;
7636 if (flag_stack_check
)
7637 probed_size
+= STACK_CHECK_PROTECT
;
7639 if (probed_size
<= 32768)
7641 if (probed_size
> 4096)
7645 for (probed
= 4096; probed
< probed_size
; probed
+= 8192)
7646 emit_insn (gen_probe_stack (GEN_INT (-probed
)));
7648 /* We only have to do this probe if we aren't saving registers or
7649 if we are probing beyond the frame because of -fstack-check. */
7650 if ((sa_size
== 0 && probed_size
> probed
- 4096)
7651 || flag_stack_check
)
7652 emit_insn (gen_probe_stack (GEN_INT (-probed_size
)));
7655 if (frame_size
!= 0)
7656 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx
, stack_pointer_rtx
,
7657 GEN_INT (-frame_size
))));
7661 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
7662 number of 8192 byte blocks to probe. We then probe each block
7663 in the loop and then set SP to the proper location. If the
7664 amount remaining is > 4096, we have to do one more probe if we
7665 are not saving any registers or if we are probing beyond the
7666 frame because of -fstack-check. */
7668 HOST_WIDE_INT blocks
= (probed_size
+ 4096) / 8192;
7669 HOST_WIDE_INT leftover
= probed_size
+ 4096 - blocks
* 8192;
7670 rtx ptr
= gen_rtx_REG (DImode
, 22);
7671 rtx count
= gen_rtx_REG (DImode
, 23);
7674 emit_move_insn (count
, GEN_INT (blocks
));
7675 emit_insn (gen_adddi3 (ptr
, stack_pointer_rtx
, GEN_INT (4096)));
7677 /* Because of the difficulty in emitting a new basic block this
7678 late in the compilation, generate the loop as a single insn. */
7679 emit_insn (gen_prologue_stack_probe_loop (count
, ptr
));
7681 if ((leftover
> 4096 && sa_size
== 0) || flag_stack_check
)
7683 rtx last
= gen_rtx_MEM (DImode
,
7684 plus_constant (Pmode
, ptr
, -leftover
));
7685 MEM_VOLATILE_P (last
) = 1;
7686 emit_move_insn (last
, const0_rtx
);
7689 if (flag_stack_check
)
7691 /* If -fstack-check is specified we have to load the entire
7692 constant into a register and subtract from the sp in one go,
7693 because the probed stack size is not equal to the frame size. */
7694 HOST_WIDE_INT lo
, hi
;
7695 lo
= ((frame_size
& 0xffff) ^ 0x8000) - 0x8000;
7696 hi
= frame_size
- lo
;
7698 emit_move_insn (ptr
, GEN_INT (hi
));
7699 emit_insn (gen_adddi3 (ptr
, ptr
, GEN_INT (lo
)));
7700 seq
= emit_insn (gen_subdi3 (stack_pointer_rtx
, stack_pointer_rtx
,
7705 seq
= emit_insn (gen_adddi3 (stack_pointer_rtx
, ptr
,
7706 GEN_INT (-leftover
)));
7709 /* This alternative is special, because the DWARF code cannot
7710 possibly intuit through the loop above. So we invent this
7711 note it looks at instead. */
7712 RTX_FRAME_RELATED_P (seq
) = 1;
7713 add_reg_note (seq
, REG_FRAME_RELATED_EXPR
,
7714 gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
7715 plus_constant (Pmode
, stack_pointer_rtx
,
7719 /* Cope with very large offsets to the register save area. */
7721 sa_reg
= stack_pointer_rtx
;
7722 if (reg_offset
+ sa_size
> 0x8000)
7724 int low
= ((reg_offset
& 0xffff) ^ 0x8000) - 0x8000;
7727 if (low
+ sa_size
<= 0x8000)
7728 sa_bias
= reg_offset
- low
, reg_offset
= low
;
7730 sa_bias
= reg_offset
, reg_offset
= 0;
7732 sa_reg
= gen_rtx_REG (DImode
, 24);
7733 sa_bias_rtx
= GEN_INT (sa_bias
);
7735 if (add_operand (sa_bias_rtx
, DImode
))
7736 emit_insn (gen_adddi3 (sa_reg
, stack_pointer_rtx
, sa_bias_rtx
));
7739 emit_move_insn (sa_reg
, sa_bias_rtx
);
7740 emit_insn (gen_adddi3 (sa_reg
, stack_pointer_rtx
, sa_reg
));
7744 /* Save regs in stack order. Beginning with VMS PV. */
7745 if (TARGET_ABI_OPEN_VMS
&& alpha_procedure_type
== PT_STACK
)
7746 emit_frame_store (REG_PV
, stack_pointer_rtx
, 0, 0);
7748 /* Save register RA next. */
7749 if (imask
& (1UL << REG_RA
))
7751 emit_frame_store (REG_RA
, sa_reg
, sa_bias
, reg_offset
);
7752 imask
&= ~(1UL << REG_RA
);
7756 /* Now save any other registers required to be saved. */
7757 for (i
= 0; i
< 31; i
++)
7758 if (imask
& (1UL << i
))
7760 emit_frame_store (i
, sa_reg
, sa_bias
, reg_offset
);
7764 for (i
= 0; i
< 31; i
++)
7765 if (fmask
& (1UL << i
))
7767 emit_frame_store (i
+32, sa_reg
, sa_bias
, reg_offset
);
7771 if (TARGET_ABI_OPEN_VMS
)
7773 /* Register frame procedures save the fp. */
7774 if (alpha_procedure_type
== PT_REGISTER
)
7776 rtx insn
= emit_move_insn (gen_rtx_REG (DImode
, vms_save_fp_regno
),
7777 hard_frame_pointer_rtx
);
7778 add_reg_note (insn
, REG_CFA_REGISTER
, NULL
);
7779 RTX_FRAME_RELATED_P (insn
) = 1;
7782 if (alpha_procedure_type
!= PT_NULL
&& vms_base_regno
!= REG_PV
)
7783 emit_insn (gen_force_movdi (gen_rtx_REG (DImode
, vms_base_regno
),
7784 gen_rtx_REG (DImode
, REG_PV
)));
7786 if (alpha_procedure_type
!= PT_NULL
7787 && vms_unwind_regno
== HARD_FRAME_POINTER_REGNUM
)
7788 FRP (emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
));
7790 /* If we have to allocate space for outgoing args, do it now. */
7791 if (crtl
->outgoing_args_size
!= 0)
7794 = emit_move_insn (stack_pointer_rtx
,
7796 (Pmode
, hard_frame_pointer_rtx
,
7798 (crtl
->outgoing_args_size
))));
7800 /* Only set FRAME_RELATED_P on the stack adjustment we just emitted
7801 if ! frame_pointer_needed. Setting the bit will change the CFA
7802 computation rule to use sp again, which would be wrong if we had
7803 frame_pointer_needed, as this means sp might move unpredictably
7807 frame_pointer_needed
7808 => vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
7810 crtl->outgoing_args_size != 0
7811 => alpha_procedure_type != PT_NULL,
7813 so when we are not setting the bit here, we are guaranteed to
7814 have emitted an FRP frame pointer update just before. */
7815 RTX_FRAME_RELATED_P (seq
) = ! frame_pointer_needed
;
7820 /* If we need a frame pointer, set it from the stack pointer. */
7821 if (frame_pointer_needed
)
7823 if (TARGET_CAN_FAULT_IN_PROLOGUE
)
7824 FRP (emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
));
7826 /* This must always be the last instruction in the
7827 prologue, thus we emit a special move + clobber. */
7828 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx
,
7829 stack_pointer_rtx
, sa_reg
)));
7833 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
7834 the prologue, for exception handling reasons, we cannot do this for
7835 any insn that might fault. We could prevent this for mems with a
7836 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
7837 have to prevent all such scheduling with a blockage.
7839 Linux, on the other hand, never bothered to implement OSF/1's
7840 exception handling, and so doesn't care about such things. Anyone
7841 planning to use dwarf2 frame-unwind info can also omit the blockage. */
7843 if (! TARGET_CAN_FAULT_IN_PROLOGUE
)
7844 emit_insn (gen_blockage ());
7847 /* Count the number of .file directives, so that .loc is up to date. */
7848 int num_source_filenames
= 0;
7850 /* Output the textual info surrounding the prologue. */
7853 alpha_start_function (FILE *file
, const char *fnname
,
7854 tree decl ATTRIBUTE_UNUSED
)
7856 unsigned long imask
= 0;
7857 unsigned long fmask
= 0;
7858 /* Stack space needed for pushing registers clobbered by us. */
7859 HOST_WIDE_INT sa_size
;
7860 /* Complete stack size needed. */
7861 unsigned HOST_WIDE_INT frame_size
;
7862 /* The maximum debuggable frame size. */
7863 unsigned HOST_WIDE_INT max_frame_size
= 1UL << 31;
7864 /* Offset from base reg to register save area. */
7865 HOST_WIDE_INT reg_offset
;
7866 char *entry_label
= (char *) alloca (strlen (fnname
) + 6);
7867 char *tramp_label
= (char *) alloca (strlen (fnname
) + 6);
7870 #if TARGET_ABI_OPEN_VMS
7871 vms_start_function (fnname
);
7874 alpha_fnname
= fnname
;
7875 sa_size
= alpha_sa_size ();
7876 frame_size
= compute_frame_size (get_frame_size (), sa_size
);
7878 if (TARGET_ABI_OPEN_VMS
)
7879 reg_offset
= 8 + 8 * cfun
->machine
->uses_condition_handler
;
7881 reg_offset
= ALPHA_ROUND (crtl
->outgoing_args_size
);
7883 alpha_sa_mask (&imask
, &fmask
);
7885 /* Issue function start and label. */
7886 if (TARGET_ABI_OPEN_VMS
|| !flag_inhibit_size_directive
)
7888 fputs ("\t.ent ", file
);
7889 assemble_name (file
, fnname
);
7892 /* If the function needs GP, we'll write the "..ng" label there.
7893 Otherwise, do it here. */
7895 && ! alpha_function_needs_gp
7896 && ! cfun
->is_thunk
)
7899 assemble_name (file
, fnname
);
7900 fputs ("..ng:\n", file
);
7903 /* Nested functions on VMS that are potentially called via trampoline
7904 get a special transfer entry point that loads the called functions
7905 procedure descriptor and static chain. */
7906 if (TARGET_ABI_OPEN_VMS
7907 && !TREE_PUBLIC (decl
)
7908 && DECL_CONTEXT (decl
)
7909 && !TYPE_P (DECL_CONTEXT (decl
))
7910 && TREE_CODE (DECL_CONTEXT (decl
)) != TRANSLATION_UNIT_DECL
)
7912 strcpy (tramp_label
, fnname
);
7913 strcat (tramp_label
, "..tr");
7914 ASM_OUTPUT_LABEL (file
, tramp_label
);
7915 fprintf (file
, "\tldq $1,24($27)\n");
7916 fprintf (file
, "\tldq $27,16($27)\n");
7919 strcpy (entry_label
, fnname
);
7920 if (TARGET_ABI_OPEN_VMS
)
7921 strcat (entry_label
, "..en");
7923 ASM_OUTPUT_LABEL (file
, entry_label
);
7924 inside_function
= TRUE
;
7926 if (TARGET_ABI_OPEN_VMS
)
7927 fprintf (file
, "\t.base $%d\n", vms_base_regno
);
7930 && TARGET_IEEE_CONFORMANT
7931 && !flag_inhibit_size_directive
)
7933 /* Set flags in procedure descriptor to request IEEE-conformant
7934 math-library routines. The value we set it to is PDSC_EXC_IEEE
7935 (/usr/include/pdsc.h). */
7936 fputs ("\t.eflag 48\n", file
);
7939 /* Set up offsets to alpha virtual arg/local debugging pointer. */
7940 alpha_auto_offset
= -frame_size
+ crtl
->args
.pretend_args_size
;
7941 alpha_arg_offset
= -frame_size
+ 48;
7943 /* Describe our frame. If the frame size is larger than an integer,
7944 print it as zero to avoid an assembler error. We won't be
7945 properly describing such a frame, but that's the best we can do. */
7946 if (TARGET_ABI_OPEN_VMS
)
7947 fprintf (file
, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC
",$26,"
7948 HOST_WIDE_INT_PRINT_DEC
"\n",
7950 frame_size
>= (1UL << 31) ? 0 : frame_size
,
7952 else if (!flag_inhibit_size_directive
)
7953 fprintf (file
, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC
",$26,%d\n",
7954 (frame_pointer_needed
7955 ? HARD_FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
),
7956 frame_size
>= max_frame_size
? 0 : frame_size
,
7957 crtl
->args
.pretend_args_size
);
7959 /* Describe which registers were spilled. */
7960 if (TARGET_ABI_OPEN_VMS
)
7963 /* ??? Does VMS care if mask contains ra? The old code didn't
7964 set it, so I don't here. */
7965 fprintf (file
, "\t.mask 0x%lx,0\n", imask
& ~(1UL << REG_RA
));
7967 fprintf (file
, "\t.fmask 0x%lx,0\n", fmask
);
7968 if (alpha_procedure_type
== PT_REGISTER
)
7969 fprintf (file
, "\t.fp_save $%d\n", vms_save_fp_regno
);
7971 else if (!flag_inhibit_size_directive
)
7975 fprintf (file
, "\t.mask 0x%lx," HOST_WIDE_INT_PRINT_DEC
"\n", imask
,
7976 frame_size
>= max_frame_size
? 0 : reg_offset
- frame_size
);
7978 for (i
= 0; i
< 32; ++i
)
7979 if (imask
& (1UL << i
))
7984 fprintf (file
, "\t.fmask 0x%lx," HOST_WIDE_INT_PRINT_DEC
"\n", fmask
,
7985 frame_size
>= max_frame_size
? 0 : reg_offset
- frame_size
);
7988 #if TARGET_ABI_OPEN_VMS
7989 /* If a user condition handler has been installed at some point, emit
7990 the procedure descriptor bits to point the Condition Handling Facility
7991 at the indirection wrapper, and state the fp offset at which the user
7992 handler may be found. */
7993 if (cfun
->machine
->uses_condition_handler
)
7995 fprintf (file
, "\t.handler __gcc_shell_handler\n");
7996 fprintf (file
, "\t.handler_data %d\n", VMS_COND_HANDLER_FP_OFFSET
);
7999 #ifdef TARGET_VMS_CRASH_DEBUG
8000 /* Support of minimal traceback info. */
8001 switch_to_section (readonly_data_section
);
8002 fprintf (file
, "\t.align 3\n");
8003 assemble_name (file
, fnname
); fputs ("..na:\n", file
);
8004 fputs ("\t.ascii \"", file
);
8005 assemble_name (file
, fnname
);
8006 fputs ("\\0\"\n", file
);
8007 switch_to_section (text_section
);
8009 #endif /* TARGET_ABI_OPEN_VMS */
8012 /* Emit the .prologue note at the scheduled end of the prologue. */
8015 alpha_output_function_end_prologue (FILE *file
)
8017 if (TARGET_ABI_OPEN_VMS
)
8018 fputs ("\t.prologue\n", file
);
8019 else if (!flag_inhibit_size_directive
)
8020 fprintf (file
, "\t.prologue %d\n",
8021 alpha_function_needs_gp
|| cfun
->is_thunk
);
8024 /* Write function epilogue. */
8027 alpha_expand_epilogue (void)
8029 /* Registers to save. */
8030 unsigned long imask
= 0;
8031 unsigned long fmask
= 0;
8032 /* Stack space needed for pushing registers clobbered by us. */
8033 HOST_WIDE_INT sa_size
;
8034 /* Complete stack size needed. */
8035 HOST_WIDE_INT frame_size
;
8036 /* Offset from base reg to register save area. */
8037 HOST_WIDE_INT reg_offset
;
8038 int fp_is_frame_pointer
, fp_offset
;
8039 rtx sa_reg
, sa_reg_exp
= NULL
;
8040 rtx sp_adj1
, sp_adj2
, mem
, reg
, insn
;
8042 rtx cfa_restores
= NULL_RTX
;
8045 sa_size
= alpha_sa_size ();
8046 frame_size
= compute_frame_size (get_frame_size (), sa_size
);
8048 if (TARGET_ABI_OPEN_VMS
)
8050 if (alpha_procedure_type
== PT_STACK
)
8051 reg_offset
= 8 + 8 * cfun
->machine
->uses_condition_handler
;
8056 reg_offset
= ALPHA_ROUND (crtl
->outgoing_args_size
);
8058 alpha_sa_mask (&imask
, &fmask
);
8061 = (TARGET_ABI_OPEN_VMS
8062 ? alpha_procedure_type
== PT_STACK
8063 : frame_pointer_needed
);
8065 sa_reg
= stack_pointer_rtx
;
8067 if (crtl
->calls_eh_return
)
8068 eh_ofs
= EH_RETURN_STACKADJ_RTX
;
8074 /* If we have a frame pointer, restore SP from it. */
8075 if (TARGET_ABI_OPEN_VMS
8076 ? vms_unwind_regno
== HARD_FRAME_POINTER_REGNUM
8077 : frame_pointer_needed
)
8078 emit_move_insn (stack_pointer_rtx
, hard_frame_pointer_rtx
);
8080 /* Cope with very large offsets to the register save area. */
8081 if (reg_offset
+ sa_size
> 0x8000)
8083 int low
= ((reg_offset
& 0xffff) ^ 0x8000) - 0x8000;
8086 if (low
+ sa_size
<= 0x8000)
8087 bias
= reg_offset
- low
, reg_offset
= low
;
8089 bias
= reg_offset
, reg_offset
= 0;
8091 sa_reg
= gen_rtx_REG (DImode
, 22);
8092 sa_reg_exp
= plus_constant (Pmode
, stack_pointer_rtx
, bias
);
8094 emit_move_insn (sa_reg
, sa_reg_exp
);
8097 /* Restore registers in order, excepting a true frame pointer. */
8099 mem
= gen_frame_mem (DImode
, plus_constant (Pmode
, sa_reg
, reg_offset
));
8100 reg
= gen_rtx_REG (DImode
, REG_RA
);
8101 emit_move_insn (reg
, mem
);
8102 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
, cfa_restores
);
8105 imask
&= ~(1UL << REG_RA
);
8107 for (i
= 0; i
< 31; ++i
)
8108 if (imask
& (1UL << i
))
8110 if (i
== HARD_FRAME_POINTER_REGNUM
&& fp_is_frame_pointer
)
8111 fp_offset
= reg_offset
;
8114 mem
= gen_frame_mem (DImode
,
8115 plus_constant (Pmode
, sa_reg
,
8117 reg
= gen_rtx_REG (DImode
, i
);
8118 emit_move_insn (reg
, mem
);
8119 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
8125 for (i
= 0; i
< 31; ++i
)
8126 if (fmask
& (1UL << i
))
8128 mem
= gen_frame_mem (DFmode
, plus_constant (Pmode
, sa_reg
,
8130 reg
= gen_rtx_REG (DFmode
, i
+32);
8131 emit_move_insn (reg
, mem
);
8132 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
, cfa_restores
);
8137 if (frame_size
|| eh_ofs
)
8139 sp_adj1
= stack_pointer_rtx
;
8143 sp_adj1
= gen_rtx_REG (DImode
, 23);
8144 emit_move_insn (sp_adj1
,
8145 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, eh_ofs
));
8148 /* If the stack size is large, begin computation into a temporary
8149 register so as not to interfere with a potential fp restore,
8150 which must be consecutive with an SP restore. */
8151 if (frame_size
< 32768 && !cfun
->calls_alloca
)
8152 sp_adj2
= GEN_INT (frame_size
);
8153 else if (frame_size
< 0x40007fffL
)
8155 int low
= ((frame_size
& 0xffff) ^ 0x8000) - 0x8000;
8157 sp_adj2
= plus_constant (Pmode
, sp_adj1
, frame_size
- low
);
8158 if (sa_reg_exp
&& rtx_equal_p (sa_reg_exp
, sp_adj2
))
8162 sp_adj1
= gen_rtx_REG (DImode
, 23);
8163 emit_move_insn (sp_adj1
, sp_adj2
);
8165 sp_adj2
= GEN_INT (low
);
8169 rtx tmp
= gen_rtx_REG (DImode
, 23);
8170 sp_adj2
= alpha_emit_set_const (tmp
, DImode
, frame_size
, 3, false);
8173 /* We can't drop new things to memory this late, afaik,
8174 so build it up by pieces. */
8175 sp_adj2
= alpha_emit_set_long_const (tmp
, frame_size
,
8177 gcc_assert (sp_adj2
);
8181 /* From now on, things must be in order. So emit blockages. */
8183 /* Restore the frame pointer. */
8184 if (fp_is_frame_pointer
)
8186 emit_insn (gen_blockage ());
8187 mem
= gen_frame_mem (DImode
, plus_constant (Pmode
, sa_reg
,
8189 emit_move_insn (hard_frame_pointer_rtx
, mem
);
8190 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
,
8191 hard_frame_pointer_rtx
, cfa_restores
);
8193 else if (TARGET_ABI_OPEN_VMS
)
8195 emit_insn (gen_blockage ());
8196 emit_move_insn (hard_frame_pointer_rtx
,
8197 gen_rtx_REG (DImode
, vms_save_fp_regno
));
8198 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
,
8199 hard_frame_pointer_rtx
, cfa_restores
);
8202 /* Restore the stack pointer. */
8203 emit_insn (gen_blockage ());
8204 if (sp_adj2
== const0_rtx
)
8205 insn
= emit_move_insn (stack_pointer_rtx
, sp_adj1
);
8207 insn
= emit_move_insn (stack_pointer_rtx
,
8208 gen_rtx_PLUS (DImode
, sp_adj1
, sp_adj2
));
8209 REG_NOTES (insn
) = cfa_restores
;
8210 add_reg_note (insn
, REG_CFA_DEF_CFA
, stack_pointer_rtx
);
8211 RTX_FRAME_RELATED_P (insn
) = 1;
8215 gcc_assert (cfa_restores
== NULL
);
8217 if (TARGET_ABI_OPEN_VMS
&& alpha_procedure_type
== PT_REGISTER
)
8219 emit_insn (gen_blockage ());
8220 insn
= emit_move_insn (hard_frame_pointer_rtx
,
8221 gen_rtx_REG (DImode
, vms_save_fp_regno
));
8222 add_reg_note (insn
, REG_CFA_RESTORE
, hard_frame_pointer_rtx
);
8223 RTX_FRAME_RELATED_P (insn
) = 1;
8228 /* Output the rest of the textual info surrounding the epilogue. */
8231 alpha_end_function (FILE *file
, const char *fnname
, tree decl ATTRIBUTE_UNUSED
)
8235 /* We output a nop after noreturn calls at the very end of the function to
8236 ensure that the return address always remains in the caller's code range,
8237 as not doing so might confuse unwinding engines. */
8238 insn
= get_last_insn ();
8240 insn
= prev_active_insn (insn
);
8241 if (insn
&& CALL_P (insn
))
8242 output_asm_insn (get_insn_template (CODE_FOR_nop
, NULL
), NULL
);
8244 #if TARGET_ABI_OPEN_VMS
8245 /* Write the linkage entries. */
8246 alpha_write_linkage (file
, fnname
);
8249 /* End the function. */
8250 if (TARGET_ABI_OPEN_VMS
8251 || !flag_inhibit_size_directive
)
8253 fputs ("\t.end ", file
);
8254 assemble_name (file
, fnname
);
8257 inside_function
= FALSE
;
8261 /* Emit a tail call to FUNCTION after adjusting THIS by DELTA.
8263 In order to avoid the hordes of differences between generated code
8264 with and without TARGET_EXPLICIT_RELOCS, and to avoid duplicating
8265 lots of code loading up large constants, generate rtl and emit it
8266 instead of going straight to text.
8268 Not sure why this idea hasn't been explored before... */
8271 alpha_output_mi_thunk_osf (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
8272 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
8275 HOST_WIDE_INT hi
, lo
;
8276 rtx this_rtx
, insn
, funexp
;
8278 /* We always require a valid GP. */
8279 emit_insn (gen_prologue_ldgp ());
8280 emit_note (NOTE_INSN_PROLOGUE_END
);
8282 /* Find the "this" pointer. If the function returns a structure,
8283 the structure return pointer is in $16. */
8284 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
8285 this_rtx
= gen_rtx_REG (Pmode
, 17);
8287 this_rtx
= gen_rtx_REG (Pmode
, 16);
8289 /* Add DELTA. When possible we use ldah+lda. Otherwise load the
8290 entire constant for the add. */
8291 lo
= ((delta
& 0xffff) ^ 0x8000) - 0x8000;
8292 hi
= (((delta
- lo
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
8293 if (hi
+ lo
== delta
)
8296 emit_insn (gen_adddi3 (this_rtx
, this_rtx
, GEN_INT (hi
)));
8298 emit_insn (gen_adddi3 (this_rtx
, this_rtx
, GEN_INT (lo
)));
8302 rtx tmp
= alpha_emit_set_long_const (gen_rtx_REG (Pmode
, 0),
8303 delta
, -(delta
< 0));
8304 emit_insn (gen_adddi3 (this_rtx
, this_rtx
, tmp
));
8307 /* Add a delta stored in the vtable at VCALL_OFFSET. */
8312 tmp
= gen_rtx_REG (Pmode
, 0);
8313 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this_rtx
));
8315 lo
= ((vcall_offset
& 0xffff) ^ 0x8000) - 0x8000;
8316 hi
= (((vcall_offset
- lo
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
8317 if (hi
+ lo
== vcall_offset
)
8320 emit_insn (gen_adddi3 (tmp
, tmp
, GEN_INT (hi
)));
8324 tmp2
= alpha_emit_set_long_const (gen_rtx_REG (Pmode
, 1),
8325 vcall_offset
, -(vcall_offset
< 0));
8326 emit_insn (gen_adddi3 (tmp
, tmp
, tmp2
));
8330 tmp2
= gen_rtx_PLUS (Pmode
, tmp
, GEN_INT (lo
));
8333 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp2
));
8335 emit_insn (gen_adddi3 (this_rtx
, this_rtx
, tmp
));
8338 /* Generate a tail call to the target function. */
8339 if (! TREE_USED (function
))
8341 assemble_external (function
);
8342 TREE_USED (function
) = 1;
8344 funexp
= XEXP (DECL_RTL (function
), 0);
8345 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
8346 insn
= emit_call_insn (gen_sibcall (funexp
, const0_rtx
));
8347 SIBLING_CALL_P (insn
) = 1;
8349 /* Run just enough of rest_of_compilation to get the insns emitted.
8350 There's not really enough bulk here to make other passes such as
8351 instruction scheduling worth while. Note that use_thunk calls
8352 assemble_start_function and assemble_end_function. */
8353 insn
= get_insns ();
8354 shorten_branches (insn
);
8355 final_start_function (insn
, file
, 1);
8356 final (insn
, file
, 1);
8357 final_end_function ();
8359 #endif /* TARGET_ABI_OSF */
8361 /* Debugging support. */
8365 /* Name of the file containing the current function. */
8367 static const char *current_function_file
= "";
8369 /* Offsets to alpha virtual arg/local debugging pointers. */
8371 long alpha_arg_offset
;
8372 long alpha_auto_offset
;
8374 /* Emit a new filename to a stream. */
8377 alpha_output_filename (FILE *stream
, const char *name
)
8379 static int first_time
= TRUE
;
8384 ++num_source_filenames
;
8385 current_function_file
= name
;
8386 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
8387 output_quoted_string (stream
, name
);
8388 fprintf (stream
, "\n");
8391 else if (name
!= current_function_file
8392 && strcmp (name
, current_function_file
) != 0)
8394 ++num_source_filenames
;
8395 current_function_file
= name
;
8396 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
8398 output_quoted_string (stream
, name
);
8399 fprintf (stream
, "\n");
8403 /* Structure to show the current status of registers and memory. */
8405 struct shadow_summary
8408 unsigned int i
: 31; /* Mask of int regs */
8409 unsigned int fp
: 31; /* Mask of fp regs */
8410 unsigned int mem
: 1; /* mem == imem | fpmem */
8414 /* Summary the effects of expression X on the machine. Update SUM, a pointer
8415 to the summary structure. SET is nonzero if the insn is setting the
8416 object, otherwise zero. */
8419 summarize_insn (rtx x
, struct shadow_summary
*sum
, int set
)
8421 const char *format_ptr
;
8427 switch (GET_CODE (x
))
8429 /* ??? Note that this case would be incorrect if the Alpha had a
8430 ZERO_EXTRACT in SET_DEST. */
8432 summarize_insn (SET_SRC (x
), sum
, 0);
8433 summarize_insn (SET_DEST (x
), sum
, 1);
8437 summarize_insn (XEXP (x
, 0), sum
, 1);
8441 summarize_insn (XEXP (x
, 0), sum
, 0);
8445 for (i
= ASM_OPERANDS_INPUT_LENGTH (x
) - 1; i
>= 0; i
--)
8446 summarize_insn (ASM_OPERANDS_INPUT (x
, i
), sum
, 0);
8450 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
8451 summarize_insn (XVECEXP (x
, 0, i
), sum
, 0);
8455 summarize_insn (SUBREG_REG (x
), sum
, 0);
8460 int regno
= REGNO (x
);
8461 unsigned long mask
= ((unsigned long) 1) << (regno
% 32);
8463 if (regno
== 31 || regno
== 63)
8469 sum
->defd
.i
|= mask
;
8471 sum
->defd
.fp
|= mask
;
8476 sum
->used
.i
|= mask
;
8478 sum
->used
.fp
|= mask
;
8489 /* Find the regs used in memory address computation: */
8490 summarize_insn (XEXP (x
, 0), sum
, 0);
8493 case CONST_INT
: case CONST_DOUBLE
:
8494 case SYMBOL_REF
: case LABEL_REF
: case CONST
:
8495 case SCRATCH
: case ASM_INPUT
:
8498 /* Handle common unary and binary ops for efficiency. */
8499 case COMPARE
: case PLUS
: case MINUS
: case MULT
: case DIV
:
8500 case MOD
: case UDIV
: case UMOD
: case AND
: case IOR
:
8501 case XOR
: case ASHIFT
: case ROTATE
: case ASHIFTRT
: case LSHIFTRT
:
8502 case ROTATERT
: case SMIN
: case SMAX
: case UMIN
: case UMAX
:
8503 case NE
: case EQ
: case GE
: case GT
: case LE
:
8504 case LT
: case GEU
: case GTU
: case LEU
: case LTU
:
8505 summarize_insn (XEXP (x
, 0), sum
, 0);
8506 summarize_insn (XEXP (x
, 1), sum
, 0);
8509 case NEG
: case NOT
: case SIGN_EXTEND
: case ZERO_EXTEND
:
8510 case TRUNCATE
: case FLOAT_EXTEND
: case FLOAT_TRUNCATE
: case FLOAT
:
8511 case FIX
: case UNSIGNED_FLOAT
: case UNSIGNED_FIX
: case ABS
:
8512 case SQRT
: case FFS
:
8513 summarize_insn (XEXP (x
, 0), sum
, 0);
8517 format_ptr
= GET_RTX_FORMAT (GET_CODE (x
));
8518 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
8519 switch (format_ptr
[i
])
8522 summarize_insn (XEXP (x
, i
), sum
, 0);
8526 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
8527 summarize_insn (XVECEXP (x
, i
, j
), sum
, 0);
8539 /* Ensure a sufficient number of `trapb' insns are in the code when
8540 the user requests code with a trap precision of functions or
8543 In naive mode, when the user requests a trap-precision of
8544 "instruction", a trapb is needed after every instruction that may
8545 generate a trap. This ensures that the code is resumption safe but
8548 When optimizations are turned on, we delay issuing a trapb as long
8549 as possible. In this context, a trap shadow is the sequence of
8550 instructions that starts with a (potentially) trap generating
8551 instruction and extends to the next trapb or call_pal instruction
8552 (but GCC never generates call_pal by itself). We can delay (and
8553 therefore sometimes omit) a trapb subject to the following
8556 (a) On entry to the trap shadow, if any Alpha register or memory
8557 location contains a value that is used as an operand value by some
8558 instruction in the trap shadow (live on entry), then no instruction
8559 in the trap shadow may modify the register or memory location.
8561 (b) Within the trap shadow, the computation of the base register
8562 for a memory load or store instruction may not involve using the
8563 result of an instruction that might generate an UNPREDICTABLE
8566 (c) Within the trap shadow, no register may be used more than once
8567 as a destination register. (This is to make life easier for the
8570 (d) The trap shadow may not include any branch instructions. */
8573 alpha_handle_trap_shadows (void)
8575 struct shadow_summary shadow
;
8576 int trap_pending
, exception_nesting
;
8580 exception_nesting
= 0;
8583 shadow
.used
.mem
= 0;
8584 shadow
.defd
= shadow
.used
;
8586 for (i
= get_insns (); i
; i
= NEXT_INSN (i
))
8590 switch (NOTE_KIND (i
))
8592 case NOTE_INSN_EH_REGION_BEG
:
8593 exception_nesting
++;
8598 case NOTE_INSN_EH_REGION_END
:
8599 exception_nesting
--;
8604 case NOTE_INSN_EPILOGUE_BEG
:
8605 if (trap_pending
&& alpha_tp
>= ALPHA_TP_FUNC
)
8610 else if (trap_pending
)
8612 if (alpha_tp
== ALPHA_TP_FUNC
)
8615 && GET_CODE (PATTERN (i
)) == RETURN
)
8618 else if (alpha_tp
== ALPHA_TP_INSN
)
8622 struct shadow_summary sum
;
8627 sum
.defd
= sum
.used
;
8629 switch (GET_CODE (i
))
8632 /* Annoyingly, get_attr_trap will die on these. */
8633 if (GET_CODE (PATTERN (i
)) == USE
8634 || GET_CODE (PATTERN (i
)) == CLOBBER
)
8637 summarize_insn (PATTERN (i
), &sum
, 0);
8639 if ((sum
.defd
.i
& shadow
.defd
.i
)
8640 || (sum
.defd
.fp
& shadow
.defd
.fp
))
8642 /* (c) would be violated */
8646 /* Combine shadow with summary of current insn: */
8647 shadow
.used
.i
|= sum
.used
.i
;
8648 shadow
.used
.fp
|= sum
.used
.fp
;
8649 shadow
.used
.mem
|= sum
.used
.mem
;
8650 shadow
.defd
.i
|= sum
.defd
.i
;
8651 shadow
.defd
.fp
|= sum
.defd
.fp
;
8652 shadow
.defd
.mem
|= sum
.defd
.mem
;
8654 if ((sum
.defd
.i
& shadow
.used
.i
)
8655 || (sum
.defd
.fp
& shadow
.used
.fp
)
8656 || (sum
.defd
.mem
& shadow
.used
.mem
))
8658 /* (a) would be violated (also takes care of (b)) */
8659 gcc_assert (get_attr_trap (i
) != TRAP_YES
8660 || (!(sum
.defd
.i
& sum
.used
.i
)
8661 && !(sum
.defd
.fp
& sum
.used
.fp
)));
8679 n
= emit_insn_before (gen_trapb (), i
);
8680 PUT_MODE (n
, TImode
);
8681 PUT_MODE (i
, TImode
);
8685 shadow
.used
.mem
= 0;
8686 shadow
.defd
= shadow
.used
;
8691 if ((exception_nesting
> 0 || alpha_tp
>= ALPHA_TP_FUNC
)
8692 && NONJUMP_INSN_P (i
)
8693 && GET_CODE (PATTERN (i
)) != USE
8694 && GET_CODE (PATTERN (i
)) != CLOBBER
8695 && get_attr_trap (i
) == TRAP_YES
)
8697 if (optimize
&& !trap_pending
)
8698 summarize_insn (PATTERN (i
), &shadow
, 0);
8704 /* Alpha can only issue instruction groups simultaneously if they are
8705 suitably aligned. This is very processor-specific. */
8706 /* There are a number of entries in alphaev4_insn_pipe and alphaev5_insn_pipe
8707 that are marked "fake". These instructions do not exist on that target,
8708 but it is possible to see these insns with deranged combinations of
8709 command-line options, such as "-mtune=ev4 -mmax". Instead of aborting,
8710 choose a result at random. */
8712 enum alphaev4_pipe
{
8719 enum alphaev5_pipe
{
8730 static enum alphaev4_pipe
8731 alphaev4_insn_pipe (rtx insn
)
8733 if (recog_memoized (insn
) < 0)
8735 if (get_attr_length (insn
) != 4)
8738 switch (get_attr_type (insn
))
8754 case TYPE_MVI
: /* fake */
8769 case TYPE_FSQRT
: /* fake */
8770 case TYPE_FTOI
: /* fake */
8771 case TYPE_ITOF
: /* fake */
8779 static enum alphaev5_pipe
8780 alphaev5_insn_pipe (rtx insn
)
8782 if (recog_memoized (insn
) < 0)
8784 if (get_attr_length (insn
) != 4)
8787 switch (get_attr_type (insn
))
8807 case TYPE_FTOI
: /* fake */
8808 case TYPE_ITOF
: /* fake */
8823 case TYPE_FSQRT
: /* fake */
8834 /* IN_USE is a mask of the slots currently filled within the insn group.
8835 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
8836 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
8838 LEN is, of course, the length of the group in bytes. */
8841 alphaev4_next_group (rtx insn
, int *pin_use
, int *plen
)
8848 || GET_CODE (PATTERN (insn
)) == CLOBBER
8849 || GET_CODE (PATTERN (insn
)) == USE
)
8854 enum alphaev4_pipe pipe
;
8856 pipe
= alphaev4_insn_pipe (insn
);
8860 /* Force complex instructions to start new groups. */
8864 /* If this is a completely unrecognized insn, it's an asm.
8865 We don't know how long it is, so record length as -1 to
8866 signal a needed realignment. */
8867 if (recog_memoized (insn
) < 0)
8870 len
= get_attr_length (insn
);
8874 if (in_use
& EV4_IB0
)
8876 if (in_use
& EV4_IB1
)
8881 in_use
|= EV4_IB0
| EV4_IBX
;
8885 if (in_use
& EV4_IB0
)
8887 if (!(in_use
& EV4_IBX
) || (in_use
& EV4_IB1
))
8895 if (in_use
& EV4_IB1
)
8905 /* Haifa doesn't do well scheduling branches. */
8910 insn
= next_nonnote_insn (insn
);
8912 if (!insn
|| ! INSN_P (insn
))
8915 /* Let Haifa tell us where it thinks insn group boundaries are. */
8916 if (GET_MODE (insn
) == TImode
)
8919 if (GET_CODE (insn
) == CLOBBER
|| GET_CODE (insn
) == USE
)
8924 insn
= next_nonnote_insn (insn
);
8932 /* IN_USE is a mask of the slots currently filled within the insn group.
8933 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
8934 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
8936 LEN is, of course, the length of the group in bytes. */
8939 alphaev5_next_group (rtx insn
, int *pin_use
, int *plen
)
8946 || GET_CODE (PATTERN (insn
)) == CLOBBER
8947 || GET_CODE (PATTERN (insn
)) == USE
)
8952 enum alphaev5_pipe pipe
;
8954 pipe
= alphaev5_insn_pipe (insn
);
8958 /* Force complex instructions to start new groups. */
8962 /* If this is a completely unrecognized insn, it's an asm.
8963 We don't know how long it is, so record length as -1 to
8964 signal a needed realignment. */
8965 if (recog_memoized (insn
) < 0)
8968 len
= get_attr_length (insn
);
8971 /* ??? Most of the places below, we would like to assert never
8972 happen, as it would indicate an error either in Haifa, or
8973 in the scheduling description. Unfortunately, Haifa never
8974 schedules the last instruction of the BB, so we don't have
8975 an accurate TI bit to go off. */
8977 if (in_use
& EV5_E0
)
8979 if (in_use
& EV5_E1
)
8984 in_use
|= EV5_E0
| EV5_E01
;
8988 if (in_use
& EV5_E0
)
8990 if (!(in_use
& EV5_E01
) || (in_use
& EV5_E1
))
8998 if (in_use
& EV5_E1
)
9004 if (in_use
& EV5_FA
)
9006 if (in_use
& EV5_FM
)
9011 in_use
|= EV5_FA
| EV5_FAM
;
9015 if (in_use
& EV5_FA
)
9021 if (in_use
& EV5_FM
)
9034 /* Haifa doesn't do well scheduling branches. */
9035 /* ??? If this is predicted not-taken, slotting continues, except
9036 that no more IBR, FBR, or JSR insns may be slotted. */
9041 insn
= next_nonnote_insn (insn
);
9043 if (!insn
|| ! INSN_P (insn
))
9046 /* Let Haifa tell us where it thinks insn group boundaries are. */
9047 if (GET_MODE (insn
) == TImode
)
9050 if (GET_CODE (insn
) == CLOBBER
|| GET_CODE (insn
) == USE
)
9055 insn
= next_nonnote_insn (insn
);
9064 alphaev4_next_nop (int *pin_use
)
9066 int in_use
= *pin_use
;
9069 if (!(in_use
& EV4_IB0
))
9074 else if ((in_use
& (EV4_IBX
|EV4_IB1
)) == EV4_IBX
)
9079 else if (TARGET_FP
&& !(in_use
& EV4_IB1
))
9092 alphaev5_next_nop (int *pin_use
)
9094 int in_use
= *pin_use
;
9097 if (!(in_use
& EV5_E1
))
9102 else if (TARGET_FP
&& !(in_use
& EV5_FA
))
9107 else if (TARGET_FP
&& !(in_use
& EV5_FM
))
9119 /* The instruction group alignment main loop. */
9122 alpha_align_insns (unsigned int max_align
,
9123 rtx (*next_group
) (rtx
, int *, int *),
9124 rtx (*next_nop
) (int *))
9126 /* ALIGN is the known alignment for the insn group. */
9128 /* OFS is the offset of the current insn in the insn group. */
9130 int prev_in_use
, in_use
, len
, ldgp
;
9133 /* Let shorten branches care for assigning alignments to code labels. */
9134 shorten_branches (get_insns ());
9136 if (align_functions
< 4)
9138 else if ((unsigned int) align_functions
< max_align
)
9139 align
= align_functions
;
9143 ofs
= prev_in_use
= 0;
9146 i
= next_nonnote_insn (i
);
9148 ldgp
= alpha_function_needs_gp
? 8 : 0;
9152 next
= (*next_group
) (i
, &in_use
, &len
);
9154 /* When we see a label, resync alignment etc. */
9157 unsigned int new_align
= 1 << label_to_alignment (i
);
9159 if (new_align
>= align
)
9161 align
= new_align
< max_align
? new_align
: max_align
;
9165 else if (ofs
& (new_align
-1))
9166 ofs
= (ofs
| (new_align
-1)) + 1;
9170 /* Handle complex instructions special. */
9171 else if (in_use
== 0)
9173 /* Asms will have length < 0. This is a signal that we have
9174 lost alignment knowledge. Assume, however, that the asm
9175 will not mis-align instructions. */
9184 /* If the known alignment is smaller than the recognized insn group,
9185 realign the output. */
9186 else if ((int) align
< len
)
9188 unsigned int new_log_align
= len
> 8 ? 4 : 3;
9191 where
= prev
= prev_nonnote_insn (i
);
9192 if (!where
|| !LABEL_P (where
))
9195 /* Can't realign between a call and its gp reload. */
9196 if (! (TARGET_EXPLICIT_RELOCS
9197 && prev
&& CALL_P (prev
)))
9199 emit_insn_before (gen_realign (GEN_INT (new_log_align
)), where
);
9200 align
= 1 << new_log_align
;
9205 /* We may not insert padding inside the initial ldgp sequence. */
9209 /* If the group won't fit in the same INT16 as the previous,
9210 we need to add padding to keep the group together. Rather
9211 than simply leaving the insn filling to the assembler, we
9212 can make use of the knowledge of what sorts of instructions
9213 were issued in the previous group to make sure that all of
9214 the added nops are really free. */
9215 else if (ofs
+ len
> (int) align
)
9217 int nop_count
= (align
- ofs
) / 4;
9220 /* Insert nops before labels, branches, and calls to truly merge
9221 the execution of the nops with the previous instruction group. */
9222 where
= prev_nonnote_insn (i
);
9225 if (LABEL_P (where
))
9227 rtx where2
= prev_nonnote_insn (where
);
9228 if (where2
&& JUMP_P (where2
))
9231 else if (NONJUMP_INSN_P (where
))
9238 emit_insn_before ((*next_nop
)(&prev_in_use
), where
);
9239 while (--nop_count
);
9243 ofs
= (ofs
+ len
) & (align
- 1);
9244 prev_in_use
= in_use
;
9249 /* Insert an unop between sibcall or noreturn function call and GP load. */
9252 alpha_pad_function_end (void)
9256 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
9259 || !(SIBLING_CALL_P (insn
)
9260 || find_reg_note (insn
, REG_NORETURN
, NULL_RTX
)))
9263 /* Make sure we do not split a call and its corresponding
9264 CALL_ARG_LOCATION note. */
9265 next
= NEXT_INSN (insn
);
9268 if (BARRIER_P (next
))
9270 next
= NEXT_INSN (next
);
9274 if (NOTE_P (next
) && NOTE_KIND (next
) == NOTE_INSN_CALL_ARG_LOCATION
)
9277 next
= next_active_insn (insn
);
9280 rtx pat
= PATTERN (next
);
9282 if (GET_CODE (pat
) == SET
9283 && GET_CODE (SET_SRC (pat
)) == UNSPEC_VOLATILE
9284 && XINT (SET_SRC (pat
), 1) == UNSPECV_LDGP1
)
9285 emit_insn_after (gen_unop (), insn
);
9290 /* Machine dependent reorg pass. */
9295 /* Workaround for a linker error that triggers when an exception
9296 handler immediatelly follows a sibcall or a noreturn function.
9298 In the sibcall case:
9300 The instruction stream from an object file:
9302 1d8: 00 00 fb 6b jmp (t12)
9303 1dc: 00 00 ba 27 ldah gp,0(ra)
9304 1e0: 00 00 bd 23 lda gp,0(gp)
9305 1e4: 00 00 7d a7 ldq t12,0(gp)
9306 1e8: 00 40 5b 6b jsr ra,(t12),1ec <__funcZ+0x1ec>
9308 was converted in the final link pass to:
9310 12003aa88: 67 fa ff c3 br 120039428 <...>
9311 12003aa8c: 00 00 fe 2f unop
9312 12003aa90: 00 00 fe 2f unop
9313 12003aa94: 48 83 7d a7 ldq t12,-31928(gp)
9314 12003aa98: 00 40 5b 6b jsr ra,(t12),12003aa9c <__func+0x1ec>
9316 And in the noreturn case:
9318 The instruction stream from an object file:
9320 54: 00 40 5b 6b jsr ra,(t12),58 <__func+0x58>
9321 58: 00 00 ba 27 ldah gp,0(ra)
9322 5c: 00 00 bd 23 lda gp,0(gp)
9323 60: 00 00 7d a7 ldq t12,0(gp)
9324 64: 00 40 5b 6b jsr ra,(t12),68 <__func+0x68>
9326 was converted in the final link pass to:
9328 fdb24: a0 03 40 d3 bsr ra,fe9a8 <_called_func+0x8>
9329 fdb28: 00 00 fe 2f unop
9330 fdb2c: 00 00 fe 2f unop
9331 fdb30: 30 82 7d a7 ldq t12,-32208(gp)
9332 fdb34: 00 40 5b 6b jsr ra,(t12),fdb38 <__func+0x68>
9334 GP load instructions were wrongly cleared by the linker relaxation
9335 pass. This workaround prevents removal of GP loads by inserting
9336 an unop instruction between a sibcall or noreturn function call and
9337 exception handler prologue. */
9339 if (current_function_has_exception_handlers ())
9340 alpha_pad_function_end ();
9342 if (alpha_tp
!= ALPHA_TP_PROG
|| flag_exceptions
)
9343 alpha_handle_trap_shadows ();
9345 /* Due to the number of extra trapb insns, don't bother fixing up
9346 alignment when trap precision is instruction. Moreover, we can
9347 only do our job when sched2 is run. */
9348 if (optimize
&& !optimize_size
9349 && alpha_tp
!= ALPHA_TP_INSN
9350 && flag_schedule_insns_after_reload
)
9352 if (alpha_tune
== PROCESSOR_EV4
)
9353 alpha_align_insns (8, alphaev4_next_group
, alphaev4_next_nop
);
9354 else if (alpha_tune
== PROCESSOR_EV5
)
9355 alpha_align_insns (16, alphaev5_next_group
, alphaev5_next_nop
);
9360 alpha_file_start (void)
9362 default_file_start ();
9364 fputs ("\t.set noreorder\n", asm_out_file
);
9365 fputs ("\t.set volatile\n", asm_out_file
);
9367 fputs ("\t.set noat\n", asm_out_file
);
9368 if (TARGET_EXPLICIT_RELOCS
)
9369 fputs ("\t.set nomacro\n", asm_out_file
);
9370 if (TARGET_SUPPORT_ARCH
| TARGET_BWX
| TARGET_MAX
| TARGET_FIX
| TARGET_CIX
)
9374 if (alpha_cpu
== PROCESSOR_EV6
|| TARGET_FIX
|| TARGET_CIX
)
9376 else if (TARGET_MAX
)
9378 else if (TARGET_BWX
)
9380 else if (alpha_cpu
== PROCESSOR_EV5
)
9385 fprintf (asm_out_file
, "\t.arch %s\n", arch
);
9389 /* Since we don't have a .dynbss section, we should not allow global
9390 relocations in the .rodata section. */
9393 alpha_elf_reloc_rw_mask (void)
9395 return flag_pic
? 3 : 2;
9398 /* Return a section for X. The only special thing we do here is to
9399 honor small data. */
9402 alpha_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
9403 unsigned HOST_WIDE_INT align
)
9405 if (TARGET_SMALL_DATA
&& GET_MODE_SIZE (mode
) <= g_switch_value
)
9406 /* ??? Consider using mergeable sdata sections. */
9407 return sdata_section
;
9409 return default_elf_select_rtx_section (mode
, x
, align
);
9413 alpha_elf_section_type_flags (tree decl
, const char *name
, int reloc
)
9415 unsigned int flags
= 0;
9417 if (strcmp (name
, ".sdata") == 0
9418 || strncmp (name
, ".sdata.", 7) == 0
9419 || strncmp (name
, ".gnu.linkonce.s.", 16) == 0
9420 || strcmp (name
, ".sbss") == 0
9421 || strncmp (name
, ".sbss.", 6) == 0
9422 || strncmp (name
, ".gnu.linkonce.sb.", 17) == 0)
9423 flags
= SECTION_SMALL
;
9425 flags
|= default_section_type_flags (decl
, name
, reloc
);
9429 /* Structure to collect function names for final output in link section. */
9430 /* Note that items marked with GTY can't be ifdef'ed out. */
9438 struct GTY(()) alpha_links
9442 enum reloc_kind rkind
;
9445 #if TARGET_ABI_OPEN_VMS
9447 /* Return the VMS argument type corresponding to MODE. */
9450 alpha_arg_type (enum machine_mode mode
)
9455 return TARGET_FLOAT_VAX
? FF
: FS
;
9457 return TARGET_FLOAT_VAX
? FD
: FT
;
9463 /* Return an rtx for an integer representing the VMS Argument Information
9467 alpha_arg_info_reg_val (CUMULATIVE_ARGS cum
)
9469 unsigned HOST_WIDE_INT regval
= cum
.num_args
;
9472 for (i
= 0; i
< 6; i
++)
9473 regval
|= ((int) cum
.atypes
[i
]) << (i
* 3 + 8);
9475 return GEN_INT (regval
);
9479 /* Return a SYMBOL_REF representing the reference to the .linkage entry
9480 of function FUNC built for calls made from CFUNDECL. LFLAG is 1 if
9481 this is the reference to the linkage pointer value, 0 if this is the
9482 reference to the function entry value. RFLAG is 1 if this a reduced
9483 reference (code address only), 0 if this is a full reference. */
9486 alpha_use_linkage (rtx func
, bool lflag
, bool rflag
)
9488 struct alpha_links
*al
= NULL
;
9489 const char *name
= XSTR (func
, 0);
9491 if (cfun
->machine
->links
)
9493 splay_tree_node lnode
;
9495 /* Is this name already defined? */
9496 lnode
= splay_tree_lookup (cfun
->machine
->links
, (splay_tree_key
) name
);
9498 al
= (struct alpha_links
*) lnode
->value
;
9501 cfun
->machine
->links
= splay_tree_new_ggc
9502 ((splay_tree_compare_fn
) strcmp
,
9503 ggc_alloc_splay_tree_str_alpha_links_splay_tree_s
,
9504 ggc_alloc_splay_tree_str_alpha_links_splay_tree_node_s
);
9515 /* Follow transparent alias, as this is used for CRTL translations. */
9516 id
= maybe_get_identifier (name
);
9519 while (IDENTIFIER_TRANSPARENT_ALIAS (id
))
9520 id
= TREE_CHAIN (id
);
9521 name
= IDENTIFIER_POINTER (id
);
9524 buf_len
= strlen (name
) + 8 + 9;
9525 linksym
= (char *) alloca (buf_len
);
9526 snprintf (linksym
, buf_len
, "$%d..%s..lk", cfun
->funcdef_no
, name
);
9528 al
= ggc_alloc_alpha_links ();
9530 al
->linkage
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (linksym
));
9532 splay_tree_insert (cfun
->machine
->links
,
9533 (splay_tree_key
) ggc_strdup (name
),
9534 (splay_tree_value
) al
);
9537 al
->rkind
= rflag
? KIND_CODEADDR
: KIND_LINKAGE
;
9540 return gen_rtx_MEM (Pmode
, plus_constant (Pmode
, al
->linkage
, 8));
9546 alpha_write_one_linkage (splay_tree_node node
, void *data
)
9548 const char *const name
= (const char *) node
->key
;
9549 struct alpha_links
*link
= (struct alpha_links
*) node
->value
;
9550 FILE *stream
= (FILE *) data
;
9552 ASM_OUTPUT_INTERNAL_LABEL (stream
, XSTR (link
->linkage
, 0));
9553 if (link
->rkind
== KIND_CODEADDR
)
9555 /* External and used, request code address. */
9556 fprintf (stream
, "\t.code_address ");
9560 if (!SYMBOL_REF_EXTERNAL_P (link
->func
)
9561 && SYMBOL_REF_LOCAL_P (link
->func
))
9563 /* Locally defined, build linkage pair. */
9564 fprintf (stream
, "\t.quad %s..en\n", name
);
9565 fprintf (stream
, "\t.quad ");
9569 /* External, request linkage pair. */
9570 fprintf (stream
, "\t.linkage ");
9573 assemble_name (stream
, name
);
9574 fputs ("\n", stream
);
9580 alpha_write_linkage (FILE *stream
, const char *funname
)
9582 fprintf (stream
, "\t.link\n");
9583 fprintf (stream
, "\t.align 3\n");
9586 #ifdef TARGET_VMS_CRASH_DEBUG
9587 fputs ("\t.name ", stream
);
9588 assemble_name (stream
, funname
);
9589 fputs ("..na\n", stream
);
9592 ASM_OUTPUT_LABEL (stream
, funname
);
9593 fprintf (stream
, "\t.pdesc ");
9594 assemble_name (stream
, funname
);
9595 fprintf (stream
, "..en,%s\n",
9596 alpha_procedure_type
== PT_STACK
? "stack"
9597 : alpha_procedure_type
== PT_REGISTER
? "reg" : "null");
9599 if (cfun
->machine
->links
)
9601 splay_tree_foreach (cfun
->machine
->links
, alpha_write_one_linkage
, stream
);
9602 /* splay_tree_delete (func->links); */
9606 /* Switch to an arbitrary section NAME with attributes as specified
9607 by FLAGS. ALIGN specifies any known alignment requirements for
9608 the section; 0 if the default should be used. */
9611 vms_asm_named_section (const char *name
, unsigned int flags
,
9612 tree decl ATTRIBUTE_UNUSED
)
9614 fputc ('\n', asm_out_file
);
9615 fprintf (asm_out_file
, ".section\t%s", name
);
9617 if (flags
& SECTION_DEBUG
)
9618 fprintf (asm_out_file
, ",NOWRT");
9620 fputc ('\n', asm_out_file
);
9623 /* Record an element in the table of global constructors. SYMBOL is
9624 a SYMBOL_REF of the function to be called; PRIORITY is a number
9625 between 0 and MAX_INIT_PRIORITY.
9627 Differs from default_ctors_section_asm_out_constructor in that the
9628 width of the .ctors entry is always 64 bits, rather than the 32 bits
9629 used by a normal pointer. */
9632 vms_asm_out_constructor (rtx symbol
, int priority ATTRIBUTE_UNUSED
)
9634 switch_to_section (ctors_section
);
9635 assemble_align (BITS_PER_WORD
);
9636 assemble_integer (symbol
, UNITS_PER_WORD
, BITS_PER_WORD
, 1);
9640 vms_asm_out_destructor (rtx symbol
, int priority ATTRIBUTE_UNUSED
)
9642 switch_to_section (dtors_section
);
9643 assemble_align (BITS_PER_WORD
);
9644 assemble_integer (symbol
, UNITS_PER_WORD
, BITS_PER_WORD
, 1);
9648 alpha_use_linkage (rtx func ATTRIBUTE_UNUSED
,
9649 bool lflag ATTRIBUTE_UNUSED
,
9650 bool rflag ATTRIBUTE_UNUSED
)
9655 #endif /* TARGET_ABI_OPEN_VMS */
9658 alpha_init_libfuncs (void)
9660 if (TARGET_ABI_OPEN_VMS
)
9662 /* Use the VMS runtime library functions for division and
9664 set_optab_libfunc (sdiv_optab
, SImode
, "OTS$DIV_I");
9665 set_optab_libfunc (sdiv_optab
, DImode
, "OTS$DIV_L");
9666 set_optab_libfunc (udiv_optab
, SImode
, "OTS$DIV_UI");
9667 set_optab_libfunc (udiv_optab
, DImode
, "OTS$DIV_UL");
9668 set_optab_libfunc (smod_optab
, SImode
, "OTS$REM_I");
9669 set_optab_libfunc (smod_optab
, DImode
, "OTS$REM_L");
9670 set_optab_libfunc (umod_optab
, SImode
, "OTS$REM_UI");
9671 set_optab_libfunc (umod_optab
, DImode
, "OTS$REM_UL");
9672 abort_libfunc
= init_one_libfunc ("decc$abort");
9673 memcmp_libfunc
= init_one_libfunc ("decc$memcmp");
9674 #ifdef MEM_LIBFUNCS_INIT
9680 /* On the Alpha, we use this to disable the floating-point registers
9681 when they don't exist. */
9684 alpha_conditional_register_usage (void)
9687 if (! TARGET_FPREGS
)
9688 for (i
= 32; i
< 63; i
++)
9689 fixed_regs
[i
] = call_used_regs
[i
] = 1;
9692 /* Canonicalize a comparison from one we don't have to one we do have. */
9695 alpha_canonicalize_comparison (int *code
, rtx
*op0
, rtx
*op1
,
9696 bool op0_preserve_value
)
9698 if (!op0_preserve_value
9699 && (*code
== GE
|| *code
== GT
|| *code
== GEU
|| *code
== GTU
)
9700 && (REG_P (*op1
) || *op1
== const0_rtx
))
9705 *code
= (int)swap_condition ((enum rtx_code
)*code
);
9708 if ((*code
== LT
|| *code
== LTU
)
9709 && CONST_INT_P (*op1
) && INTVAL (*op1
) == 256)
9711 *code
= *code
== LT
? LE
: LEU
;
9712 *op1
= GEN_INT (255);
9716 /* Initialize the GCC target structure. */
9717 #if TARGET_ABI_OPEN_VMS
9718 # undef TARGET_ATTRIBUTE_TABLE
9719 # define TARGET_ATTRIBUTE_TABLE vms_attribute_table
9720 # undef TARGET_CAN_ELIMINATE
9721 # define TARGET_CAN_ELIMINATE alpha_vms_can_eliminate
9724 #undef TARGET_IN_SMALL_DATA_P
9725 #define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p
9727 #undef TARGET_ASM_ALIGNED_HI_OP
9728 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
9729 #undef TARGET_ASM_ALIGNED_DI_OP
9730 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
9732 /* Default unaligned ops are provided for ELF systems. To get unaligned
9733 data for non-ELF systems, we have to turn off auto alignment. */
9734 #if TARGET_ABI_OPEN_VMS
9735 #undef TARGET_ASM_UNALIGNED_HI_OP
9736 #define TARGET_ASM_UNALIGNED_HI_OP "\t.align 0\n\t.word\t"
9737 #undef TARGET_ASM_UNALIGNED_SI_OP
9738 #define TARGET_ASM_UNALIGNED_SI_OP "\t.align 0\n\t.long\t"
9739 #undef TARGET_ASM_UNALIGNED_DI_OP
9740 #define TARGET_ASM_UNALIGNED_DI_OP "\t.align 0\n\t.quad\t"
9743 #undef TARGET_ASM_RELOC_RW_MASK
9744 #define TARGET_ASM_RELOC_RW_MASK alpha_elf_reloc_rw_mask
9745 #undef TARGET_ASM_SELECT_RTX_SECTION
9746 #define TARGET_ASM_SELECT_RTX_SECTION alpha_elf_select_rtx_section
9747 #undef TARGET_SECTION_TYPE_FLAGS
9748 #define TARGET_SECTION_TYPE_FLAGS alpha_elf_section_type_flags
9750 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
9751 #define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
9753 #undef TARGET_INIT_LIBFUNCS
9754 #define TARGET_INIT_LIBFUNCS alpha_init_libfuncs
9756 #undef TARGET_LEGITIMIZE_ADDRESS
9757 #define TARGET_LEGITIMIZE_ADDRESS alpha_legitimize_address
9758 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
9759 #define TARGET_MODE_DEPENDENT_ADDRESS_P alpha_mode_dependent_address_p
9761 #undef TARGET_ASM_FILE_START
9762 #define TARGET_ASM_FILE_START alpha_file_start
9764 #undef TARGET_SCHED_ADJUST_COST
9765 #define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
9766 #undef TARGET_SCHED_ISSUE_RATE
9767 #define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
9768 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
9769 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
9770 alpha_multipass_dfa_lookahead
9772 #undef TARGET_HAVE_TLS
9773 #define TARGET_HAVE_TLS HAVE_AS_TLS
9775 #undef TARGET_BUILTIN_DECL
9776 #define TARGET_BUILTIN_DECL alpha_builtin_decl
9777 #undef TARGET_INIT_BUILTINS
9778 #define TARGET_INIT_BUILTINS alpha_init_builtins
9779 #undef TARGET_EXPAND_BUILTIN
9780 #define TARGET_EXPAND_BUILTIN alpha_expand_builtin
9781 #undef TARGET_FOLD_BUILTIN
9782 #define TARGET_FOLD_BUILTIN alpha_fold_builtin
9784 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
9785 #define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall
9786 #undef TARGET_CANNOT_COPY_INSN_P
9787 #define TARGET_CANNOT_COPY_INSN_P alpha_cannot_copy_insn_p
9788 #undef TARGET_LEGITIMATE_CONSTANT_P
9789 #define TARGET_LEGITIMATE_CONSTANT_P alpha_legitimate_constant_p
9790 #undef TARGET_CANNOT_FORCE_CONST_MEM
9791 #define TARGET_CANNOT_FORCE_CONST_MEM alpha_cannot_force_const_mem
9794 #undef TARGET_ASM_OUTPUT_MI_THUNK
9795 #define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
9796 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
9797 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
9798 #undef TARGET_STDARG_OPTIMIZE_HOOK
9799 #define TARGET_STDARG_OPTIMIZE_HOOK alpha_stdarg_optimize_hook
9802 /* Use 16-bits anchor. */
9803 #undef TARGET_MIN_ANCHOR_OFFSET
9804 #define TARGET_MIN_ANCHOR_OFFSET -0x7fff - 1
9805 #undef TARGET_MAX_ANCHOR_OFFSET
9806 #define TARGET_MAX_ANCHOR_OFFSET 0x7fff
9807 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
9808 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
9810 #undef TARGET_RTX_COSTS
9811 #define TARGET_RTX_COSTS alpha_rtx_costs
9812 #undef TARGET_ADDRESS_COST
9813 #define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
9815 #undef TARGET_MACHINE_DEPENDENT_REORG
9816 #define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg
9818 #undef TARGET_PROMOTE_FUNCTION_MODE
9819 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
9820 #undef TARGET_PROMOTE_PROTOTYPES
9821 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_false
9822 #undef TARGET_RETURN_IN_MEMORY
9823 #define TARGET_RETURN_IN_MEMORY alpha_return_in_memory
9824 #undef TARGET_PASS_BY_REFERENCE
9825 #define TARGET_PASS_BY_REFERENCE alpha_pass_by_reference
9826 #undef TARGET_SETUP_INCOMING_VARARGS
9827 #define TARGET_SETUP_INCOMING_VARARGS alpha_setup_incoming_varargs
9828 #undef TARGET_STRICT_ARGUMENT_NAMING
9829 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
9830 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
9831 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
9832 #undef TARGET_SPLIT_COMPLEX_ARG
9833 #define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg
9834 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
9835 #define TARGET_GIMPLIFY_VA_ARG_EXPR alpha_gimplify_va_arg
9836 #undef TARGET_ARG_PARTIAL_BYTES
9837 #define TARGET_ARG_PARTIAL_BYTES alpha_arg_partial_bytes
9838 #undef TARGET_FUNCTION_ARG
9839 #define TARGET_FUNCTION_ARG alpha_function_arg
9840 #undef TARGET_FUNCTION_ARG_ADVANCE
9841 #define TARGET_FUNCTION_ARG_ADVANCE alpha_function_arg_advance
9842 #undef TARGET_TRAMPOLINE_INIT
9843 #define TARGET_TRAMPOLINE_INIT alpha_trampoline_init
9845 #undef TARGET_INSTANTIATE_DECLS
9846 #define TARGET_INSTANTIATE_DECLS alpha_instantiate_decls
9848 #undef TARGET_SECONDARY_RELOAD
9849 #define TARGET_SECONDARY_RELOAD alpha_secondary_reload
9851 #undef TARGET_SCALAR_MODE_SUPPORTED_P
9852 #define TARGET_SCALAR_MODE_SUPPORTED_P alpha_scalar_mode_supported_p
9853 #undef TARGET_VECTOR_MODE_SUPPORTED_P
9854 #define TARGET_VECTOR_MODE_SUPPORTED_P alpha_vector_mode_supported_p
9856 #undef TARGET_BUILD_BUILTIN_VA_LIST
9857 #define TARGET_BUILD_BUILTIN_VA_LIST alpha_build_builtin_va_list
9859 #undef TARGET_EXPAND_BUILTIN_VA_START
9860 #define TARGET_EXPAND_BUILTIN_VA_START alpha_va_start
9862 /* The Alpha architecture does not require sequential consistency. See
9863 http://www.cs.umd.edu/~pugh/java/memoryModel/AlphaReordering.html
9864 for an example of how it can be violated in practice. */
9865 #undef TARGET_RELAXED_ORDERING
9866 #define TARGET_RELAXED_ORDERING true
9868 #undef TARGET_OPTION_OVERRIDE
9869 #define TARGET_OPTION_OVERRIDE alpha_option_override
9871 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
9872 #undef TARGET_MANGLE_TYPE
9873 #define TARGET_MANGLE_TYPE alpha_mangle_type
9876 #undef TARGET_LEGITIMATE_ADDRESS_P
9877 #define TARGET_LEGITIMATE_ADDRESS_P alpha_legitimate_address_p
9879 #undef TARGET_CONDITIONAL_REGISTER_USAGE
9880 #define TARGET_CONDITIONAL_REGISTER_USAGE alpha_conditional_register_usage
9882 #undef TARGET_CANONICALIZE_COMPARISON
9883 #define TARGET_CANONICALIZE_COMPARISON alpha_canonicalize_comparison
9885 struct gcc_target targetm
= TARGET_INITIALIZER
;
9888 #include "gt-alpha.h"