static tree
stabilize_va_list (tree valist, int needs_lvalue)
{
- tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist));
- if (vatype !=NULL && TREE_CODE (vatype) == ARRAY_TYPE)
+ if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
{
if (TREE_SIDE_EFFECTS (valist))
valist = save_expr (valist);
/* For this case, the backends will be expecting a pointer to
- vatype, but it's possible we've actually been given an array
- (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)).
+ TREE_TYPE (va_list_type_node), but it's possible we've
+ actually been given an array (an actual va_list_type_node).
So fix it. */
if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
{
- tree p1 = build_pointer_type (TREE_TYPE (vatype));
+ tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
valist = build_fold_addr_expr_with_type (valist, p1);
}
}
if (! TREE_SIDE_EFFECTS (valist))
return valist;
- pt = build_pointer_type (vatype);
+ pt = build_pointer_type (va_list_type_node);
valist = fold_build1 (ADDR_EXPR, pt, valist);
TREE_SIDE_EFFECTS (valist) = 1;
}
return ptr_type_node;
}
-/* The "standard" abi va_list is va_list_type_node. */
-
-tree
-std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED)
-{
- return va_list_type_node;
-}
-
-/* The "standard" type of va_list is va_list_type_node. */
-
-tree
-std_canonical_va_list_type (tree type)
-{
- tree wtype, htype;
-
- wtype = va_list_type_node;
- htype = type;
- if (TREE_CODE (wtype) == ARRAY_TYPE)
- {
- /* If va_list is an array type, the argument may have decayed
- to a pointer type, e.g. by being passed to another function.
- In that case, unwrap both types so that we can compare the
- underlying records. */
- if (TREE_CODE (htype) == ARRAY_TYPE
- || POINTER_TYPE_P (htype))
- {
- wtype = TREE_TYPE (wtype);
- htype = TREE_TYPE (htype);
- }
- }
- if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
- return va_list_type_node;
-
- return NULL_TREE;
-}
-
/* The "standard" implementation of va_start: just assign `nextarg' to
the variable. */
enum gimplify_status
gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
{
- tree promoted_type, have_va_type;
+ tree promoted_type, want_va_type, have_va_type;
tree valist = TREE_OPERAND (*expr_p, 0);
tree type = TREE_TYPE (*expr_p);
tree t;
/* Verify that valist is of the proper type. */
+ want_va_type = va_list_type_node;
have_va_type = TREE_TYPE (valist);
+
if (have_va_type == error_mark_node)
return GS_ERROR;
- have_va_type = targetm.canonical_va_list_type (have_va_type);
- if (have_va_type == NULL_TREE)
+ if (TREE_CODE (want_va_type) == ARRAY_TYPE)
+ {
+ /* If va_list is an array type, the argument may have decayed
+ to a pointer type, e.g. by being passed to another function.
+ In that case, unwrap both types so that we can compare the
+ underlying records. */
+ if (TREE_CODE (have_va_type) == ARRAY_TYPE
+ || POINTER_TYPE_P (have_va_type))
+ {
+ want_va_type = TREE_TYPE (want_va_type);
+ have_va_type = TREE_TYPE (have_va_type);
+ }
+ }
+
+ if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
{
error ("first argument to %<va_arg%> not of type %<va_list%>");
return GS_ERROR;
/* Generate a diagnostic for requesting data of a type that cannot
be passed through `...' due to type promotion at the call site. */
- if ((promoted_type = lang_hooks.types.type_promotes_to (type))
+ else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
!= type)
{
static bool gave_help;
{
/* Make it easier for the backends by protecting the valist argument
from multiple evaluations. */
- if (TREE_CODE (have_va_type) == ARRAY_TYPE)
+ if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
{
/* For this case, the backends will be expecting a pointer to
- TREE_TYPE (abi), but it's possible we've
- actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
+ TREE_TYPE (va_list_type_node), but it's possible we've
+ actually been given an array (an actual va_list_type_node).
So fix it. */
if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
{
- tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
+ tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
valist = build_fold_addr_expr_with_type (valist, p1);
}
gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
dst = stabilize_va_list (dst, 1);
src = stabilize_va_list (src, 0);
- gcc_assert (cfun != NULL && cfun->decl != NULL_TREE);
-
- if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE)
+ if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
{
- t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src);
+ t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
/* Evaluate to pointers. */
dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
- size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)),
- NULL_RTX, VOIDmode, EXPAND_NORMAL);
+ size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
+ VOIDmode, EXPAND_NORMAL);
dstb = convert_memory_address (Pmode, dstb);
srcb = convert_memory_address (Pmode, srcb);
/* "Dereference" to BLKmode memories. */
dstb = gen_rtx_MEM (BLKmode, dstb);
set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
- set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
+ set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
srcb = gen_rtx_MEM (BLKmode, srcb);
set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
- set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
+ set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
/* Copy. */
emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
lang_hooks.decls.pushdecl
(build_decl (TYPE_DECL, get_identifier ("__builtin_va_list"),
va_list_type_node));
-#ifdef TARGET_ENUM_VA_LIST
- {
- int l;
- const char *pname;
- tree ptype;
- for (l = 0; TARGET_ENUM_VA_LIST (l, &pname, &ptype); ++l)
- {
- lang_hooks.decls.pushdecl
- (build_decl (TYPE_DECL, get_identifier (pname),
- ptype));
-
- }
- }
-#endif
if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
{
extra_headers="cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h
pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
nmmintrin.h bmmintrin.h mmintrin-common.h
- wmmintrin.h cross-stdarg.h"
+ wmmintrin.h"
;;
x86_64-*-*)
cpu_type=i386
extra_headers="cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h
pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
nmmintrin.h bmmintrin.h mmintrin-common.h
- wmmintrin.h cross-stdarg.h"
+ wmmintrin.h"
need_64bit_hwint=yes
;;
ia64-*-*)
extern int ix86_function_abi (const_tree);
extern int ix86_function_type_abi (const_tree);
extern void ix86_call_abi_override (const_tree);
-extern tree ix86_fn_abi_va_list (tree);
-extern tree ix86_canonical_va_list_type (tree);
-extern int ix86_enum_va_list (int, const char **, tree *);
extern int ix86_reg_parm_stack_space (const_tree);
extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx,
/* Values 1-5: see jump.c */
int ix86_branch_cost;
-/* Calling abi specific va_list type nodes. */
-static GTY(()) tree sysv_va_list_type_node;
-static GTY(()) tree ms_va_list_type_node;
-
/* Variables which are this size or smaller are put in the data/bss
or ldata/lbss sections. */
set_param_value ("l2-cache-size", ix86_cost->l2_cache_size);
/* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
- can be optimized to ap = __builtin_next_arg (0). */
- if (!TARGET_64BIT)
+ can be optimized to ap = __builtin_next_arg (0).
+ For abi switching it should be corrected. */
+ if (!TARGET_64BIT || DEFAULT_ABI == MS_ABI)
targetm.expand_builtin_va_start = NULL;
if (TARGET_64BIT)
else
abi = lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)) ? SYSV_ABI : MS_ABI;
+ if (DEFAULT_ABI == MS_ABI && abi == SYSV_ABI)
+ sorry ("using sysv calling convention on target w64 is not supported");
+
return abi;
}
return DEFAULT_ABI;
\f
/* Create the va_list data type. */
-/* Returns the calling convention specific va_list date type.
- The argument ABI can be DEFAULT_ABI, MS_ABI, or SYSV_ABI. */
-
static tree
-ix86_build_builtin_va_list_abi (enum calling_abi abi)
+ix86_build_builtin_va_list (void)
{
tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
/* For i386 we use plain pointer to argument area. */
- if (!TARGET_64BIT || abi == MS_ABI)
+ if (!TARGET_64BIT || ix86_cfun_abi () == MS_ABI)
return build_pointer_type (char_type_node);
record = (*lang_hooks.types.make_type) (RECORD_TYPE);
return build_array_type (record, build_index_type (size_zero_node));
}
-/* Setup the builtin va_list data type and for 64-bit the additional
- calling convention specific va_list data types. */
-
-static tree
-ix86_build_builtin_va_list (void)
-{
- tree ret = ix86_build_builtin_va_list_abi (DEFAULT_ABI);
-
- /* Initialize abi specific va_list builtin types. */
- if (TARGET_64BIT)
- {
- tree t;
-
- t = ix86_build_builtin_va_list_abi (SYSV_ABI);
- if (TREE_CODE (t) != RECORD_TYPE)
- t = build_variant_type_copy (t);
- sysv_va_list_type_node = t;
-
- t = ix86_build_builtin_va_list_abi (MS_ABI);
- if (TREE_CODE (t) != RECORD_TYPE)
- t = build_variant_type_copy (t);
- ms_va_list_type_node = t;
- }
-
- return ret;
-}
-
/* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
static void
tree type;
/* Only 64bit target needs something special. */
- if (!TARGET_64BIT ||
- ix86_canonical_va_list_type (TREE_TYPE (valist)) == ms_va_list_type_node)
+ if (!TARGET_64BIT || cfun->machine->call_abi == MS_ABI)
{
std_expand_builtin_va_start (valist, nextarg);
return;
}
- f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
+ f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
f_fpr = TREE_CHAIN (f_gpr);
f_ovf = TREE_CHAIN (f_fpr);
f_sav = TREE_CHAIN (f_ovf);
enum machine_mode nat_mode;
/* Only 64bit target needs something special. */
- if (!TARGET_64BIT ||
- ix86_canonical_va_list_type (TREE_TYPE (valist)) == ms_va_list_type_node)
+ if (!TARGET_64BIT || cfun->machine->call_abi == MS_ABI)
return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
- f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
+ f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
f_fpr = TREE_CHAIN (f_gpr);
f_ovf = TREE_CHAIN (f_fpr);
f_sav = TREE_CHAIN (f_ovf);
}
}
-/* Internal method for ix86_init_builtins. */
-
-static void
-ix86_init_builtins_va_builtins_abi (void)
-{
- tree ms_va_ref, sysv_va_ref;
- tree fnvoid_va_end_ms, fnvoid_va_end_sysv;
- tree fnvoid_va_start_ms, fnvoid_va_start_sysv;
- tree fnvoid_va_copy_ms, fnvoid_va_copy_sysv;
- tree fnattr_ms = NULL_TREE, fnattr_sysv = NULL_TREE;
-
- if (!TARGET_64BIT)
- return;
- fnattr_ms = build_tree_list (get_identifier ("ms_abi"), NULL_TREE);
- fnattr_sysv = build_tree_list (get_identifier ("sysv_abi"), NULL_TREE);
- ms_va_ref = build_reference_type (ms_va_list_type_node);
- sysv_va_ref =
- build_pointer_type (TREE_TYPE (sysv_va_list_type_node));
-
- fnvoid_va_end_ms =
- build_function_type_list (void_type_node, ms_va_ref, NULL_TREE);
- fnvoid_va_start_ms =
- build_varargs_function_type_list (void_type_node, ms_va_ref, NULL_TREE);
- fnvoid_va_end_sysv =
- build_function_type_list (void_type_node, sysv_va_ref, NULL_TREE);
- fnvoid_va_start_sysv =
- build_varargs_function_type_list (void_type_node, sysv_va_ref,
- NULL_TREE);
- fnvoid_va_copy_ms =
- build_function_type_list (void_type_node, ms_va_list_type_node, ms_va_ref,
- NULL_TREE);
- fnvoid_va_copy_sysv =
- build_function_type_list (void_type_node, sysv_va_list_type_node,
- sysv_va_ref, NULL_TREE);
-
- add_builtin_function ("__builtin_ms_va_start", fnvoid_va_start_ms,
- BUILT_IN_VA_START, BUILT_IN_NORMAL, NULL, fnattr_ms);
- add_builtin_function ("__builtin_ms_va_end", fnvoid_va_end_ms,
- BUILT_IN_VA_END, BUILT_IN_NORMAL, NULL, fnattr_ms);
- add_builtin_function ("__builtin_ms_va_copy", fnvoid_va_copy_ms,
- BUILT_IN_VA_COPY, BUILT_IN_NORMAL, NULL, fnattr_ms);
- add_builtin_function ("__builtin_sysv_va_start", fnvoid_va_start_sysv,
- BUILT_IN_VA_START, BUILT_IN_NORMAL, NULL, fnattr_sysv);
- add_builtin_function ("__builtin_sysv_va_end", fnvoid_va_end_sysv,
- BUILT_IN_VA_END, BUILT_IN_NORMAL, NULL, fnattr_sysv);
- add_builtin_function ("__builtin_sysv_va_copy", fnvoid_va_copy_sysv,
- BUILT_IN_VA_COPY, BUILT_IN_NORMAL, NULL, fnattr_sysv);
-}
-
static void
ix86_init_builtins (void)
{
if (TARGET_MMX)
ix86_init_mmx_sse_builtins ();
- if (TARGET_64BIT)
- ix86_init_builtins_va_builtins_abi ();
}
/* Errors in the source file can cause expand_expr to return const0_rtx
reg_alloc_order [pos++] = 0;
}
-/* Handle a "ms_abi" or "sysv" attribute; arguments as in
- struct attribute_spec.handler. */
-static tree
-ix86_handle_abi_attribute (tree *node, tree name,
- tree args ATTRIBUTE_UNUSED,
- int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
-{
- if (TREE_CODE (*node) != FUNCTION_TYPE
- && TREE_CODE (*node) != METHOD_TYPE
- && TREE_CODE (*node) != FIELD_DECL
- && TREE_CODE (*node) != TYPE_DECL)
- {
- warning (OPT_Wattributes, "%qs attribute only applies to functions",
- IDENTIFIER_POINTER (name));
- *no_add_attrs = true;
- return NULL_TREE;
- }
- if (!TARGET_64BIT)
- {
- warning (OPT_Wattributes, "%qs attribute only available for 64-bit",
- IDENTIFIER_POINTER (name));
- *no_add_attrs = true;
- return NULL_TREE;
- }
-
- /* Can combine regparm with all attributes but fastcall. */
- if (is_attribute_p ("ms_abi", name))
- {
- if (lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (*node)))
- {
- error ("ms_abi and sysv_abi attributes are not compatible");
- }
-
- return NULL_TREE;
- }
- else if (is_attribute_p ("sysv_abi", name))
- {
- if (lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (*node)))
- {
- error ("ms_abi and sysv_abi attributes are not compatible");
- }
-
- return NULL_TREE;
- }
-
- return NULL_TREE;
-}
-
/* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
struct attribute_spec.handler. */
static tree
#ifdef SUBTARGET_ATTRIBUTE_TABLE
SUBTARGET_ATTRIBUTE_TABLE,
#endif
- /* ms_abi and sysv_abi calling convention function attributes. */
- { "ms_abi", 0, 0, false, true, true, ix86_handle_abi_attribute },
- { "sysv_abi", 0, 0, false, true, true, ix86_handle_abi_attribute },
- /* End element. */
{ NULL, 0, 0, false, false, false, NULL }
};
return 0;
}
-/* This function returns the calling abi specific va_list type node.
- It returns the FNDECL specific va_list type. */
-
-tree
-ix86_fn_abi_va_list (tree fndecl)
-{
- int abi;
-
- if (!TARGET_64BIT)
- return va_list_type_node;
- gcc_assert (fndecl != NULL_TREE);
- abi = ix86_function_abi ((const_tree) fndecl);
-
- if (abi == DEFAULT_ABI)
- return va_list_type_node;
- else if (abi == MS_ABI)
- return ms_va_list_type_node;
- else
- return sysv_va_list_type_node;
-}
-
-/* Returns the canonical va_list type specified by TYPE. If there
- is no valid TYPE provided, it return NULL_TREE. */
-
-tree
-ix86_canonical_va_list_type (tree type)
-{
- tree wtype, htype;
- if (TARGET_64BIT)
- {
- wtype = sysv_va_list_type_node;
- htype = type;
- if (TREE_CODE (wtype) == ARRAY_TYPE)
- {
- /* If va_list is an array type, the argument may have decayed
- to a pointer type, e.g. by being passed to another function.
- In that case, unwrap both types so that we can compare the
- underlying records. */
- if (TREE_CODE (htype) == ARRAY_TYPE
- || POINTER_TYPE_P (htype))
- {
- wtype = TREE_TYPE (wtype);
- htype = TREE_TYPE (htype);
- }
- }
- if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
- return sysv_va_list_type_node;
- wtype = ms_va_list_type_node;
- htype = type;
- if (TREE_CODE (wtype) == ARRAY_TYPE)
- {
- /* If va_list is an array type, the argument may have decayed
- to a pointer type, e.g. by being passed to another function.
- In that case, unwrap both types so that we can compare the
- underlying records. */
- if (TREE_CODE (htype) == ARRAY_TYPE
- || POINTER_TYPE_P (htype))
- {
- wtype = TREE_TYPE (wtype);
- htype = TREE_TYPE (htype);
- }
- }
- if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
- return ms_va_list_type_node;
-
- return NULL_TREE;
- }
- return std_canonical_va_list_type (type);
-}
-
-/* Iterate through the target-specific builtin types for va_list.
- IDX denotes the iterator, *PTREE is set to the result type of
- the va_list builtin, and *PNAME to its internal type.
- Returns zero if there is no element for this index, otherwise
- IDX should be increased upon the next call.
- Note, do not iterate a base builtin's name like __builtin_va_list.
- Used from c_common_nodes_and_builtins. */
-
-int
-ix86_enum_va_list (int idx, const char **pname, tree *ptree)
-{
- if (!TARGET_64BIT)
- return 0;
- switch (idx) {
- case 0:
- *ptree = ms_va_list_type_node;
- *pname = "__builtin_ms_va_list";
- break;
- case 1:
- *ptree = sysv_va_list_type_node;
- *pname = "__builtin_sysv_va_list";
- break;
- default:
- return 0;
- }
- return 1;
-}
-
/* Initialize the GCC target structure. */
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY ix86_return_in_memory
#undef TARGET_BUILD_BUILTIN_VA_LIST
#define TARGET_BUILD_BUILTIN_VA_LIST ix86_build_builtin_va_list
-#undef TARGET_FN_ABI_VA_LIST
-#define TARGET_FN_ABI_VA_LIST ix86_fn_abi_va_list
-
-#undef TARGET_CANONICAL_VA_LIST_TYPE
-#define TARGET_CANONICAL_VA_LIST_TYPE ix86_canonical_va_list_type
-
#undef TARGET_EXPAND_BUILTIN_VA_START
#define TARGET_EXPAND_BUILTIN_VA_START ix86_va_start
#define TARGET_64BIT_MS_ABI (TARGET_64BIT && ix86_cfun_abi () == MS_ABI)
/* Available call abi. */
-enum calling_abi
+enum
{
SYSV_ABI = 0,
MS_ABI = 1
#undef TARG_COND_BRANCH_COST
#define TARG_COND_BRANCH_COST ix86_cost->branch_cost
-/* Enum through the target specific extra va_list types. Please, do not
- iterate the base va_list type name. */
-#define TARGET_ENUM_VA_LIST(IDX, PNAME, PTYPE) \
- (!TARGET_64BIT ? 0 : ix86_enum_va_list (IDX, PNAME, PTYPE))
-
/* Cost of any scalar operation, excluding load and store. */
#undef TARG_SCALAR_STMT_COST
#define TARG_SCALAR_STMT_COST ix86_cost->scalar_stmt_cost
The default version of the hook returns @code{void*}.
@end deftypefn
-@deftypefn {Target Hook} tree TARGET_FN_ABI_VA_LIST (tree @var{fndecl})
-This hook returns the va_list type of the calling convention specified by
-@var{fndecl}.
-The default version of this hook returns @code{va_list_type_node}.
-@end deftypefn
-
-@deftypefn {Target Hook} tree TARGET_CANONICAL_VA_LIST_TYPE (tree @var{type})
-This hook returns the va_list type of the calling convention specified by the
-type of @var{type}. If @var{type} is not a valid va_list type, it returns
-@code{NULL_TREE}.
-@end deftypefn
-
@deftypefn {Target Hook} tree TARGET_GIMPLIFY_VA_ARG_EXPR (tree @var{valist}, tree @var{type}, tree *@var{pre_p}, tree *@var{post_p})
This hook performs target-specific gimplification of
@code{VA_ARG_EXPR}. The first two parameters correspond to the
should recognize only the caller's register numbers.
@end defmac
-@defmac TARGET_ENUM_VA_LIST (@var{idx}, @var{pname}, @var{ptype})
-This target macro is used in function @code{c_common_nodes_and_builtins}
-to iterate through the target specific builtin types for va_list. The
-variable @var{idx} is used as iterator. @var{pname} has to be a pointer
-to a @code{const char *} and @var{ptype} a pointer to a @code{tree} typed
-variable.
-The arguments @var{pname} and @var{ptype} are used to store the result of
-this macro and are set to the name of the va_list builtin type and its
-internal type.
-If the return value of this macro is zero, then there is no more element.
-Otherwise the @var{IDX} should be increased for the next call of this
-macro to iterate through all types.
-@end defmac
-
@defmac APPLY_RESULT_SIZE
Define this macro if @samp{untyped_call} and @samp{untyped_return}
need more space than is implied by @code{FUNCTION_VALUE_REGNO_P} for
/* Functions from builtins.c: */
extern rtx expand_builtin (tree, rtx, rtx, enum machine_mode, int);
extern tree std_build_builtin_va_list (void);
-extern tree std_fn_abi_va_list (tree);
-extern tree std_canonical_va_list_type (tree);
-
extern void std_expand_builtin_va_start (tree, rtx);
extern rtx default_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
extern void expand_builtin_setjmp_setup (rtx, rtx);
#define TARGET_MACHINE_DEPENDENT_REORG 0
#define TARGET_BUILD_BUILTIN_VA_LIST std_build_builtin_va_list
-#define TARGET_FN_ABI_VA_LIST std_fn_abi_va_list
-#define TARGET_CANONICAL_VA_LIST_TYPE std_canonical_va_list_type
#define TARGET_EXPAND_BUILTIN_VA_START 0
#define TARGET_GET_PCH_VALIDITY default_get_pch_validity
TARGET_CC_MODES_COMPATIBLE, \
TARGET_MACHINE_DEPENDENT_REORG, \
TARGET_BUILD_BUILTIN_VA_LIST, \
- TARGET_FN_ABI_VA_LIST, \
- TARGET_CANONICAL_VA_LIST_TYPE, \
TARGET_EXPAND_BUILTIN_VA_START, \
TARGET_GIMPLIFY_VA_ARG_EXPR, \
TARGET_GET_PCH_VALIDITY, \
/* Create the __builtin_va_list type. */
tree (* build_builtin_va_list) (void);
- /* Get the cfun/fndecl calling abi __builtin_va_list type. */
- tree (* fn_abi_va_list) (tree);
-
- /* Get the __builtin_va_list type dependent on input type. */
- tree (* canonical_va_list_type) (tree);
-
/* Expand the __builtin_va_start builtin. */
void (* expand_builtin_va_start) (tree valist, rtx nextarg);
return false;
}
-/* Returns true if the TYPE is one of the available va_list types.
- Otherwise it returns false.
- Note, that for multiple calling conventions there can be more
- than just one va_list type present. */
-
-static bool
-is_va_list_type (tree type)
-{
- tree h;
-
- if (type == NULL_TREE)
- return false;
- h = targetm.canonical_va_list_type (type);
- if (h == NULL_TREE)
- return false;
- if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (h))
- return true;
- return false;
-}
-
/* Return true if DECL can be decomposed into a set of independent
(though not necessarily scalar) variables. */
tree-stdarg.c, as the decomposition is truly a win. This could also
be fixed if the stdarg pass ran early, but this can't be done until
we've aliasing information early too. See PR 30791. */
- if (early_sra && is_va_list_type (TREE_TYPE (var)))
+ if (early_sra
+ && TYPE_MAIN_VARIANT (TREE_TYPE (var))
+ == TYPE_MAIN_VARIANT (va_list_type_node))
return false;
return true;
static tree
optimize_stdarg_builtin (tree call)
{
- tree callee, lhs, rhs, cfun_va_list;
+ tree callee, lhs, rhs;
bool va_list_simple_ptr;
if (TREE_CODE (call) != CALL_EXPR)
return NULL_TREE;
- callee = get_callee_fndecl (call);
-
- cfun_va_list = targetm.fn_abi_va_list (callee);
- va_list_simple_ptr = POINTER_TYPE_P (cfun_va_list)
- && (TREE_TYPE (cfun_va_list) == void_type_node
- || TREE_TYPE (cfun_va_list) == char_type_node);
+ va_list_simple_ptr = POINTER_TYPE_P (va_list_type_node)
+ && (TREE_TYPE (va_list_type_node) == void_type_node
+ || TREE_TYPE (va_list_type_node) == char_type_node);
+ callee = get_callee_fndecl (call);
switch (DECL_FUNCTION_CODE (callee))
{
case BUILT_IN_VA_START:
lhs = CALL_EXPR_ARG (call, 0);
if (!POINTER_TYPE_P (TREE_TYPE (lhs))
|| TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs)))
- != TYPE_MAIN_VARIANT (cfun_va_list))
+ != TYPE_MAIN_VARIANT (va_list_type_node))
return NULL_TREE;
lhs = build_fold_indirect_ref (lhs);
lhs = CALL_EXPR_ARG (call, 0);
if (!POINTER_TYPE_P (TREE_TYPE (lhs))
|| TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs)))
- != TYPE_MAIN_VARIANT (cfun_va_list))
+ != TYPE_MAIN_VARIANT (va_list_type_node))
return NULL_TREE;
lhs = build_fold_indirect_ref (lhs);
rhs = CALL_EXPR_ARG (call, 1);
if (TYPE_MAIN_VARIANT (TREE_TYPE (rhs))
- != TYPE_MAIN_VARIANT (cfun_va_list))
+ != TYPE_MAIN_VARIANT (va_list_type_node))
return NULL_TREE;
rhs = fold_convert (TREE_TYPE (lhs), rhs);
bool va_list_simple_ptr;
struct stdarg_info si;
const char *funcname = NULL;
- tree cfun_va_list;
cfun->va_list_gpr_size = 0;
cfun->va_list_fpr_size = 0;
if (dump_file)
funcname = lang_hooks.decl_printable_name (current_function_decl, 2);
- cfun_va_list = targetm.fn_abi_va_list (cfun->decl);
- va_list_simple_ptr = POINTER_TYPE_P (cfun_va_list)
- && (TREE_TYPE (cfun_va_list) == void_type_node
- || TREE_TYPE (cfun_va_list) == char_type_node);
- gcc_assert (is_gimple_reg_type (cfun_va_list) == va_list_simple_ptr);
+ va_list_simple_ptr = POINTER_TYPE_P (va_list_type_node)
+ && (TREE_TYPE (va_list_type_node) == void_type_node
+ || TREE_TYPE (va_list_type_node) == char_type_node);
+ gcc_assert (is_gimple_reg_type (va_list_type_node) == va_list_simple_ptr);
FOR_EACH_BB (bb)
{
ap = TREE_OPERAND (ap, 0);
}
if (TYPE_MAIN_VARIANT (TREE_TYPE (ap))
- != TYPE_MAIN_VARIANT (targetm.fn_abi_va_list (cfun->decl))
+ != TYPE_MAIN_VARIANT (va_list_type_node)
|| TREE_CODE (ap) != VAR_DECL)
{
va_list_escapes = true;