Commit 3b23a6d3 by Kai Tietz Committed by Kai Tietz

i386-protos.h (ix86_return_in_memory): Removed.

2008-05-20  Kai Tietz  <kai.tietz@onevision.com>

	* config/i386/i386-protos.h (ix86_return_in_memory): Removed.
	(ix86_i386elf_return_in_memory): Likewise.
	(ix86_i386interix_return_in_memory): Likewise.
	* config/i386/i386-interix.h (TARGET_RETURN_IN_MEMORY): Removed.
	(SUBTARGET_RETURN_IN_MEMORY): New.
	* config/i386/i386elf.h: Likewise.
	* config/i386/ptx4-i.h: Likewise.
	* config/i386/sol2-10.h: Likewise.
	* config/i386/sysv4.h: Likewise.
	* config/i386/vx-common.h: Likewise.
	* config/i386/i386.h (TARGET_RETURN_IN_MEMORY): Removed.
	* config/i386/i386.c (ix86_return_in_memory): Made static and
	make use of optional SUBTARGET_RETURN_IN_MEMORY macro.
	(ix86_i386elf_return_in_memory): Removed.
	(ix86_i386interix_return_in_memory): Removed.
	(TARGET_RETURN_IN_MEMORY): Declared within i386.c only.
	* target-def.h (TARGET_RETURN_IN_MEMORY): Remove protection #ifdef.

From-SVN: r135604
parent be9ed5d5
2008-05-20 Kai Tietz <kai.tietz@onevision.com>
* config/i386/i386-protos.h (ix86_return_in_memory): Removed.
(ix86_i386elf_return_in_memory): Likewise.
(ix86_i386interix_return_in_memory): Likewise.
* config/i386/i386-interix.h (TARGET_RETURN_IN_MEMORY): Removed.
(SUBTARGET_RETURN_IN_MEMORY): New.
* config/i386/i386elf.h: Likewise.
* config/i386/ptx4-i.h: Likewise.
* config/i386/sol2-10.h: Likewise.
* config/i386/sysv4.h: Likewise.
* config/i386/vx-common.h: Likewise.
* config/i386/i386.h (TARGET_RETURN_IN_MEMORY): Removed.
* config/i386/i386.c (ix86_return_in_memory): Made static and
make use of optional SUBTARGET_RETURN_IN_MEMORY macro.
(ix86_i386elf_return_in_memory): Removed.
(ix86_i386interix_return_in_memory): Removed.
(TARGET_RETURN_IN_MEMORY): Declared within i386.c only.
* target-def.h (TARGET_RETURN_IN_MEMORY): Remove protection #ifdef.
2008-05-20 Alexandre Oliva <aoliva@redhat.com> 2008-05-20 Alexandre Oliva <aoliva@redhat.com>
* cselib.c (cselib_record_sets): Use correct mode for IF_THEN_ELSE. * cselib.c (cselib_record_sets): Use correct mode for IF_THEN_ELSE.
......
...@@ -34,7 +34,10 @@ along with GCC; see the file COPYING3. If not see ...@@ -34,7 +34,10 @@ along with GCC; see the file COPYING3. If not see
#endif #endif
#undef TARGET_64BIT_MS_ABI #undef TARGET_64BIT_MS_ABI
#define TARGET_64BIT_MS_ABI TARGET_64BIT #define TARGET_64BIT_MS_ABI (!cfun ? DEFAULT_ABI == MS_ABI : TARGET_64BIT && cfun->machine->call_abi == MS_ABI)
#undef DEFAULT_ABI
#define DEFAULT_ABI (TARGET_64BIT ? MS_ABI : SYSV_ABI)
#undef DBX_REGISTER_NUMBER #undef DBX_REGISTER_NUMBER
#define DBX_REGISTER_NUMBER(n) \ #define DBX_REGISTER_NUMBER(n) \
...@@ -123,12 +126,6 @@ along with GCC; see the file COPYING3. If not see ...@@ -123,12 +126,6 @@ along with GCC; see the file COPYING3. If not see
#undef LONG_TYPE_SIZE #undef LONG_TYPE_SIZE
#define LONG_TYPE_SIZE 32 #define LONG_TYPE_SIZE 32
#undef REG_PARM_STACK_SPACE
#define REG_PARM_STACK_SPACE(FNDECL) (TARGET_64BIT_MS_ABI ? 32 : 0)
#undef OUTGOING_REG_PARM_STACK_SPACE
#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) (TARGET_64BIT_MS_ABI ? 1 : 0)
#undef REGPARM_MAX #undef REGPARM_MAX
#define REGPARM_MAX (TARGET_64BIT_MS_ABI ? 4 : 3) #define REGPARM_MAX (TARGET_64BIT_MS_ABI ? 4 : 3)
...@@ -214,7 +211,7 @@ do { \ ...@@ -214,7 +211,7 @@ do { \
#define CHECK_STACK_LIMIT 4000 #define CHECK_STACK_LIMIT 4000
#undef STACK_BOUNDARY #undef STACK_BOUNDARY
#define STACK_BOUNDARY (TARGET_64BIT_MS_ABI ? 128 : BITS_PER_WORD) #define STACK_BOUNDARY (DEFAULT_ABI == MS_ABI ? 128 : BITS_PER_WORD)
/* By default, target has a 80387, uses IEEE compatible arithmetic, /* By default, target has a 80387, uses IEEE compatible arithmetic,
returns float values in the 387 and needs stack probes. returns float values in the 387 and needs stack probes.
......
...@@ -357,5 +357,6 @@ extern void i386_pe_unique_section (tree, int); ...@@ -357,5 +357,6 @@ extern void i386_pe_unique_section (tree, int);
#define DEFAULT_PCC_STRUCT_RETURN 0 #define DEFAULT_PCC_STRUCT_RETURN 0
#undef TARGET_RETURN_IN_MEMORY #define SUBTARGET_RETURN_IN_MEMORY(TYPE, FNTYPE) \
#define TARGET_RETURN_IN_MEMORY ix86_i386interix_return_in_memory (TYPE_MODE (TYPE) == BLKmode \
|| (AGGREGATE_TYPE_P (TYPE) && int_size_in_bytes (TYPE) > 8 ))
\ No newline at end of file
...@@ -134,12 +134,12 @@ extern rtx ix86_libcall_value (enum machine_mode); ...@@ -134,12 +134,12 @@ extern rtx ix86_libcall_value (enum machine_mode);
extern bool ix86_function_value_regno_p (int); extern bool ix86_function_value_regno_p (int);
extern bool ix86_function_arg_regno_p (int); extern bool ix86_function_arg_regno_p (int);
extern int ix86_function_arg_boundary (enum machine_mode, tree); extern int ix86_function_arg_boundary (enum machine_mode, tree);
extern bool ix86_return_in_memory (const_tree, const_tree);
extern bool ix86_sol10_return_in_memory (const_tree,const_tree); extern bool ix86_sol10_return_in_memory (const_tree,const_tree);
extern bool ix86_i386elf_return_in_memory (const_tree,const_tree);
extern bool ix86_i386interix_return_in_memory (const_tree,const_tree);
extern rtx ix86_force_to_memory (enum machine_mode, rtx); extern rtx ix86_force_to_memory (enum machine_mode, rtx);
extern void ix86_free_from_memory (enum machine_mode); extern void ix86_free_from_memory (enum machine_mode);
extern int ix86_cfun_abi (void);
extern int ix86_function_abi (const_tree);
extern int ix86_function_type_abi (const_tree);
extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx, extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx,
rtx, rtx, rtx, rtx); rtx, rtx, rtx, rtx);
extern bool ix86_hard_regno_mode_ok (int, enum machine_mode); extern bool ix86_hard_regno_mode_ok (int, enum machine_mode);
......
...@@ -1618,8 +1618,12 @@ rtx ix86_compare_op0 = NULL_RTX; ...@@ -1618,8 +1618,12 @@ rtx ix86_compare_op0 = NULL_RTX;
rtx ix86_compare_op1 = NULL_RTX; rtx ix86_compare_op1 = NULL_RTX;
rtx ix86_compare_emitted = NULL_RTX; rtx ix86_compare_emitted = NULL_RTX;
/* Abi specific values for REGPARM_MAX */
#define X86_64_REGPARM_MAX 6
#define X86_64_SSE_REGPARM_MAX 8
/* Size of the register save area. */ /* Size of the register save area. */
#define X86_64_VARARGS_SIZE (REGPARM_MAX * UNITS_PER_WORD + SSE_REGPARM_MAX * 16) #define X86_64_VARARGS_SIZE (X86_64_REGPARM_MAX * UNITS_PER_WORD + X86_64_SSE_REGPARM_MAX * 16)
/* Define the structure for the machine field in struct function. */ /* Define the structure for the machine field in struct function. */
...@@ -2306,11 +2310,11 @@ override_options (void) ...@@ -2306,11 +2310,11 @@ override_options (void)
} }
else else
{ {
/* For TARGET_64BIT_MS_ABI, force pic on, in order to enable the /* For TARGET_64BIT and MS_ABI, force pic on, in order to enable the
use of rip-relative addressing. This eliminates fixups that use of rip-relative addressing. This eliminates fixups that
would otherwise be needed if this object is to be placed in a would otherwise be needed if this object is to be placed in a
DLL, and is essentially just as efficient as direct addressing. */ DLL, and is essentially just as efficient as direct addressing. */
if (TARGET_64BIT_MS_ABI) if (TARGET_64BIT && DEFAULT_ABI == MS_ABI)
ix86_cmodel = CM_SMALL_PIC, flag_pic = 1; ix86_cmodel = CM_SMALL_PIC, flag_pic = 1;
else if (TARGET_64BIT) else if (TARGET_64BIT)
ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL; ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
...@@ -2761,8 +2765,9 @@ override_options (void) ...@@ -2761,8 +2765,9 @@ override_options (void)
set_param_value ("l2-cache-size", ix86_cost->l2_cache_size); set_param_value ("l2-cache-size", ix86_cost->l2_cache_size);
/* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0) /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
can be optimized to ap = __builtin_next_arg (0). */ can be optimized to ap = __builtin_next_arg (0).
if (!TARGET_64BIT || TARGET_64BIT_MS_ABI) For abi switching it should be corrected. */
if (!TARGET_64BIT || DEFAULT_ABI == MS_ABI)
targetm.expand_builtin_va_start = NULL; targetm.expand_builtin_va_start = NULL;
} }
...@@ -3160,7 +3165,7 @@ ix86_handle_cconv_attribute (tree *node, tree name, ...@@ -3160,7 +3165,7 @@ ix86_handle_cconv_attribute (tree *node, tree name,
if (TARGET_64BIT) if (TARGET_64BIT)
{ {
/* Do not warn when emulating the MS ABI. */ /* Do not warn when emulating the MS ABI. */
if (!TARGET_64BIT_MS_ABI) if (TREE_CODE (*node) != FUNCTION_TYPE || !ix86_function_type_abi (*node))
warning (OPT_Wattributes, "%qs attribute ignored", warning (OPT_Wattributes, "%qs attribute ignored",
IDENTIFIER_POINTER (name)); IDENTIFIER_POINTER (name));
*no_add_attrs = true; *no_add_attrs = true;
...@@ -3263,7 +3268,11 @@ ix86_function_regparm (const_tree type, const_tree decl) ...@@ -3263,7 +3268,11 @@ ix86_function_regparm (const_tree type, const_tree decl)
static bool error_issued; static bool error_issued;
if (TARGET_64BIT) if (TARGET_64BIT)
return regparm; {
if (ix86_function_type_abi (type) == DEFAULT_ABI)
return regparm;
return DEFAULT_ABI != SYSV_ABI ? 6 : 4; /* $$$$ */
}
attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type)); attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
if (attr) if (attr)
...@@ -3494,11 +3503,15 @@ ix86_function_arg_regno_p (int regno) ...@@ -3494,11 +3503,15 @@ ix86_function_arg_regno_p (int regno)
return true; return true;
} }
/* TODO: The function should depend on current function ABI but
builtins.c would need updating then. Therefore we use the
default ABI. */
/* RAX is used as hidden argument to va_arg functions. */ /* RAX is used as hidden argument to va_arg functions. */
if (!TARGET_64BIT_MS_ABI && regno == AX_REG) if (DEFAULT_ABI == SYSV_ABI && regno == AX_REG)
return true; return true;
if (TARGET_64BIT_MS_ABI) if (DEFAULT_ABI == MS_ABI)
parm_regs = x86_64_ms_abi_int_parameter_registers; parm_regs = x86_64_ms_abi_int_parameter_registers;
else else
parm_regs = x86_64_int_parameter_registers; parm_regs = x86_64_int_parameter_registers;
...@@ -3523,6 +3536,57 @@ ix86_must_pass_in_stack (enum machine_mode mode, const_tree type) ...@@ -3523,6 +3536,57 @@ ix86_must_pass_in_stack (enum machine_mode mode, const_tree type)
&& type && TREE_CODE (type) != VECTOR_TYPE); && type && TREE_CODE (type) != VECTOR_TYPE);
} }
/* It returns the size, in bytes, of the area reserved for arguments passed
in registers for the function represented by fndecl dependent to the used
abi format. */
unsigned int
ix86_reg_parm_stack_space (const_tree fndecl)
{
int call_abi = 0;
/* For libcalls it is possible that there is no fndecl at hand.
Therefore assume for this case the default abi of the target. */
if (!fndecl)
call_abi = DEFAULT_ABI;
else
call_abi = ix86_function_abi (fndecl);
if (call_abi == 1)
return 32;
return 0;
}
/* Returns value SYSV_ABI, MS_ABI dependent on fntype, specifying the
call abi used. */
int
ix86_function_type_abi (const_tree fntype)
{
if (TARGET_64BIT && fntype != NULL)
{
if (DEFAULT_ABI == SYSV_ABI)
return lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (fntype)) ? MS_ABI : SYSV_ABI;
else
return lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)) ? SYSV_ABI : MS_ABI;
}
return DEFAULT_ABI;
}
int
ix86_function_abi (const_tree fndecl)
{
if (! fndecl)
return DEFAULT_ABI;
return ix86_function_type_abi (TREE_TYPE (fndecl));
}
/* Returns value SYSV_ABI, MS_ABI dependent on cfun, specifying the
call abi used. */
int
ix86_cfun_abi (void)
{
if (! cfun || ! TARGET_64BIT)
return DEFAULT_ABI;
return cfun->machine->call_abi;
}
/* Initialize a variable CUM of type CUMULATIVE_ARGS /* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE. for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0. */ For a library call, FNTYPE is 0. */
...@@ -3538,8 +3602,20 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */ ...@@ -3538,8 +3602,20 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
/* Set up the number of registers to use for passing arguments. */ /* Set up the number of registers to use for passing arguments. */
cum->nregs = ix86_regparm; cum->nregs = ix86_regparm;
if (TARGET_64BIT)
{
if (cum->call_abi != DEFAULT_ABI)
cum->nregs = DEFAULT_ABI != SYSV_ABI ? 6 : 4;
}
if (TARGET_SSE) if (TARGET_SSE)
cum->sse_nregs = SSE_REGPARM_MAX; {
cum->sse_nregs = SSE_REGPARM_MAX;
if (TARGET_64BIT)
{
if (cum->call_abi != DEFAULT_ABI)
cum->sse_nregs = DEFAULT_ABI != SYSV_ABI ? 8 : 4; /* $$$$ */
}
}
if (TARGET_MMX) if (TARGET_MMX)
cum->mmx_nregs = MMX_REGPARM_MAX; cum->mmx_nregs = MMX_REGPARM_MAX;
cum->warn_sse = true; cum->warn_sse = true;
...@@ -4325,7 +4401,7 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -4325,7 +4401,7 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
if (type) if (type)
mode = type_natural_mode (type); mode = type_natural_mode (type);
if (TARGET_64BIT_MS_ABI) if (TARGET_64BIT && (cum ? cum->call_abi : DEFAULT_ABI) == MS_ABI)
function_arg_advance_ms_64 (cum, bytes, words); function_arg_advance_ms_64 (cum, bytes, words);
else if (TARGET_64BIT) else if (TARGET_64BIT)
function_arg_advance_64 (cum, mode, type, words); function_arg_advance_64 (cum, mode, type, words);
...@@ -4452,8 +4528,9 @@ function_arg_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -4452,8 +4528,9 @@ function_arg_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
if (mode == VOIDmode) if (mode == VOIDmode)
return GEN_INT (cum->maybe_vaarg return GEN_INT (cum->maybe_vaarg
? (cum->sse_nregs < 0 ? (cum->sse_nregs < 0
? SSE_REGPARM_MAX ? (cum->call_abi == DEFAULT_ABI ? SSE_REGPARM_MAX
: cum->sse_regno) : (DEFAULT_ABI != SYSV_ABI ? 8 : 4)) /* $$$$ */
: cum->sse_regno)
: -1); : -1);
return construct_container (mode, orig_mode, type, 0, cum->nregs, return construct_container (mode, orig_mode, type, 0, cum->nregs,
...@@ -4527,7 +4604,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode omode, ...@@ -4527,7 +4604,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode omode,
if (type && TREE_CODE (type) == VECTOR_TYPE) if (type && TREE_CODE (type) == VECTOR_TYPE)
mode = type_natural_mode (type); mode = type_natural_mode (type);
if (TARGET_64BIT_MS_ABI) if (TARGET_64BIT && (cum ? cum->call_abi : DEFAULT_ABI) == MS_ABI)
return function_arg_ms_64 (cum, mode, omode, named, bytes); return function_arg_ms_64 (cum, mode, omode, named, bytes);
else if (TARGET_64BIT) else if (TARGET_64BIT)
return function_arg_64 (cum, mode, omode, type); return function_arg_64 (cum, mode, omode, type);
...@@ -4547,7 +4624,7 @@ ix86_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, ...@@ -4547,7 +4624,7 @@ ix86_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
const_tree type, bool named ATTRIBUTE_UNUSED) const_tree type, bool named ATTRIBUTE_UNUSED)
{ {
/* See Windows x64 Software Convention. */ /* See Windows x64 Software Convention. */
if (TARGET_64BIT_MS_ABI) if (TARGET_64BIT && (cum ? cum->call_abi : DEFAULT_ABI) == MS_ABI)
{ {
int msize = (int) GET_MODE_SIZE (mode); int msize = (int) GET_MODE_SIZE (mode);
if (type) if (type)
...@@ -4674,7 +4751,10 @@ ix86_function_value_regno_p (int regno) ...@@ -4674,7 +4751,10 @@ ix86_function_value_regno_p (int regno)
return true; return true;
case FIRST_FLOAT_REG: case FIRST_FLOAT_REG:
if (TARGET_64BIT_MS_ABI) /* TODO: The function should depend on current function ABI but
builtins.c would need updating then. Therefore we use the
default ABI. */
if (TARGET_64BIT && DEFAULT_ABI == MS_ABI)
return false; return false;
return TARGET_FLOAT_RETURNS_IN_80387; return TARGET_FLOAT_RETURNS_IN_80387;
...@@ -4765,7 +4845,7 @@ function_value_64 (enum machine_mode orig_mode, enum machine_mode mode, ...@@ -4765,7 +4845,7 @@ function_value_64 (enum machine_mode orig_mode, enum machine_mode mode,
} }
ret = construct_container (mode, orig_mode, valtype, 1, ret = construct_container (mode, orig_mode, valtype, 1,
REGPARM_MAX, SSE_REGPARM_MAX, X86_64_REGPARM_MAX, X86_64_SSE_REGPARM_MAX,
x86_64_int_return_registers, 0); x86_64_int_return_registers, 0);
/* For zero sized structures, construct_container returns NULL, but we /* For zero sized structures, construct_container returns NULL, but we
...@@ -4813,7 +4893,7 @@ ix86_function_value_1 (const_tree valtype, const_tree fntype_or_decl, ...@@ -4813,7 +4893,7 @@ ix86_function_value_1 (const_tree valtype, const_tree fntype_or_decl,
fn = fntype_or_decl; fn = fntype_or_decl;
fntype = fn ? TREE_TYPE (fn) : fntype_or_decl; fntype = fn ? TREE_TYPE (fn) : fntype_or_decl;
if (TARGET_64BIT_MS_ABI) if (TARGET_64BIT && ix86_function_type_abi (fntype) == MS_ABI)
return function_value_ms_64 (orig_mode, mode); return function_value_ms_64 (orig_mode, mode);
else if (TARGET_64BIT) else if (TARGET_64BIT)
return function_value_64 (orig_mode, mode, valtype); return function_value_64 (orig_mode, mode, valtype);
...@@ -4901,17 +4981,21 @@ return_in_memory_ms_64 (const_tree type, enum machine_mode mode) ...@@ -4901,17 +4981,21 @@ return_in_memory_ms_64 (const_tree type, enum machine_mode mode)
return (size != 1 && size != 2 && size != 4 && size != 8); return (size != 1 && size != 2 && size != 4 && size != 8);
} }
bool static bool
ix86_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) ix86_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
{ {
#ifdef SUBTARGET_RETURN_IN_MEMORY
return SUBTARGET_RETURN_IN_MEMORY (type, fntype);
#else
const enum machine_mode mode = type_natural_mode (type); const enum machine_mode mode = type_natural_mode (type);
if (TARGET_64BIT_MS_ABI) if (TARGET_64BIT && ix86_function_type_abi (fntype) == MS_ABI)
return return_in_memory_ms_64 (type, mode); return return_in_memory_ms_64 (type, mode);
else if (TARGET_64BIT) else if (TARGET_64BIT)
return return_in_memory_64 (type, mode); return return_in_memory_64 (type, mode);
else else
return return_in_memory_32 (type, mode); return return_in_memory_32 (type, mode);
#endif
} }
/* Return false iff TYPE is returned in memory. This version is used /* Return false iff TYPE is returned in memory. This version is used
...@@ -4951,20 +5035,6 @@ ix86_sol10_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED ...@@ -4951,20 +5035,6 @@ ix86_sol10_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED
return size > 12; return size > 12;
} }
bool
ix86_i386elf_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
{
return (TYPE_MODE (type) == BLKmode
|| (VECTOR_MODE_P (TYPE_MODE (type)) && int_size_in_bytes (type) == 8));
}
bool
ix86_i386interix_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
{
return (TYPE_MODE (type) == BLKmode
|| (AGGREGATE_TYPE_P (type) && int_size_in_bytes(type) > 8 ));
}
/* When returning SSE vector types, we have a choice of either /* When returning SSE vector types, we have a choice of either
(1) being abi incompatible with a -march switch, or (1) being abi incompatible with a -march switch, or
(2) generating an error. (2) generating an error.
...@@ -5020,7 +5090,7 @@ ix86_build_builtin_va_list (void) ...@@ -5020,7 +5090,7 @@ ix86_build_builtin_va_list (void)
tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl; tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
/* For i386 we use plain pointer to argument area. */ /* For i386 we use plain pointer to argument area. */
if (!TARGET_64BIT || TARGET_64BIT_MS_ABI) if (!TARGET_64BIT || ix86_cfun_abi () == MS_ABI)
return build_pointer_type (char_type_node); return build_pointer_type (char_type_node);
record = (*lang_hooks.types.make_type) (RECORD_TYPE); record = (*lang_hooks.types.make_type) (RECORD_TYPE);
...@@ -5068,6 +5138,10 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum) ...@@ -5068,6 +5138,10 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
rtx nsse_reg; rtx nsse_reg;
alias_set_type set; alias_set_type set;
int i; int i;
int regparm = ix86_regparm;
if((cum ? cum->call_abi : ix86_cfun_abi ()) != DEFAULT_ABI)
regparm = DEFAULT_ABI != SYSV_ABI ? 6 : 4; /* $$$$ */
if (! cfun->va_list_gpr_size && ! cfun->va_list_fpr_size) if (! cfun->va_list_gpr_size && ! cfun->va_list_fpr_size)
return; return;
...@@ -5087,7 +5161,7 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum) ...@@ -5087,7 +5161,7 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
set = get_varargs_alias_set (); set = get_varargs_alias_set ();
for (i = cum->regno; for (i = cum->regno;
i < ix86_regparm i < regparm
&& i < cum->regno + cfun->va_list_gpr_size / UNITS_PER_WORD; && i < cum->regno + cfun->va_list_gpr_size / UNITS_PER_WORD;
i++) i++)
{ {
...@@ -5190,7 +5264,7 @@ ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -5190,7 +5264,7 @@ ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
if (stdarg_p (fntype)) if (stdarg_p (fntype))
function_arg_advance (&next_cum, mode, type, 1); function_arg_advance (&next_cum, mode, type, 1);
if (TARGET_64BIT_MS_ABI) if ((cum ? cum->call_abi : DEFAULT_ABI) == MS_ABI)
setup_incoming_varargs_ms_64 (&next_cum); setup_incoming_varargs_ms_64 (&next_cum);
else else
setup_incoming_varargs_64 (&next_cum); setup_incoming_varargs_64 (&next_cum);
...@@ -5207,7 +5281,7 @@ ix86_va_start (tree valist, rtx nextarg) ...@@ -5207,7 +5281,7 @@ ix86_va_start (tree valist, rtx nextarg)
tree type; tree type;
/* Only 64bit target needs something special. */ /* Only 64bit target needs something special. */
if (!TARGET_64BIT || TARGET_64BIT_MS_ABI) if (!TARGET_64BIT || cfun->machine->call_abi == MS_ABI)
{ {
std_expand_builtin_va_start (valist, nextarg); std_expand_builtin_va_start (valist, nextarg);
return; return;
...@@ -5286,7 +5360,7 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p) ...@@ -5286,7 +5360,7 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
enum machine_mode nat_mode; enum machine_mode nat_mode;
/* Only 64bit target needs something special. */ /* Only 64bit target needs something special. */
if (!TARGET_64BIT || TARGET_64BIT_MS_ABI) if (!TARGET_64BIT || cfun->machine->call_abi == MS_ABI)
return std_gimplify_va_arg_expr (valist, type, pre_p, post_p); return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node)); f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
...@@ -5308,7 +5382,8 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p) ...@@ -5308,7 +5382,8 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
nat_mode = type_natural_mode (type); nat_mode = type_natural_mode (type);
container = construct_container (nat_mode, TYPE_MODE (type), type, 0, container = construct_container (nat_mode, TYPE_MODE (type), type, 0,
REGPARM_MAX, SSE_REGPARM_MAX, intreg, 0); X86_64_REGPARM_MAX, X86_64_SSE_REGPARM_MAX,
intreg, 0);
/* Pull the value out of the saved registers. */ /* Pull the value out of the saved registers. */
...@@ -5386,8 +5461,8 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p) ...@@ -5386,8 +5461,8 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
if (needed_sseregs) if (needed_sseregs)
{ {
t = build_int_cst (TREE_TYPE (fpr), t = build_int_cst (TREE_TYPE (fpr),
(SSE_REGPARM_MAX - needed_sseregs + 1) * 16 (X86_64_SSE_REGPARM_MAX - needed_sseregs + 1) * 16
+ REGPARM_MAX * 8); + X86_64_REGPARM_MAX * 8);
t = build2 (GE_EXPR, boolean_type_node, fpr, t); t = build2 (GE_EXPR, boolean_type_node, fpr, t);
t2 = build1 (GOTO_EXPR, void_type_node, lab_false); t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE); t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
...@@ -6513,9 +6588,9 @@ ix86_expand_prologue (void) ...@@ -6513,9 +6588,9 @@ ix86_expand_prologue (void)
bool eax_live; bool eax_live;
rtx t; rtx t;
gcc_assert (!TARGET_64BIT || TARGET_64BIT_MS_ABI); gcc_assert (!TARGET_64BIT || cfun->machine->call_abi == MS_ABI);
if (TARGET_64BIT_MS_ABI) if (cfun->machine->call_abi == MS_ABI)
eax_live = false; eax_live = false;
else else
eax_live = ix86_eax_live_at_start_p (); eax_live = ix86_eax_live_at_start_p ();
...@@ -8325,7 +8400,7 @@ output_pic_addr_const (FILE *file, rtx x, int code) ...@@ -8325,7 +8400,7 @@ output_pic_addr_const (FILE *file, rtx x, int code)
#endif #endif
assemble_name (file, name); assemble_name (file, name);
} }
if (!TARGET_MACHO && !TARGET_64BIT_MS_ABI if (!TARGET_MACHO && !(TARGET_64BIT && DEFAULT_ABI == MS_ABI)
&& code == 'P' && ! SYMBOL_REF_LOCAL_P (x)) && code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
fputs ("@PLT", file); fputs ("@PLT", file);
break; break;
...@@ -16418,6 +16493,7 @@ ix86_init_machine_status (void) ...@@ -16418,6 +16493,7 @@ ix86_init_machine_status (void)
f = GGC_CNEW (struct machine_function); f = GGC_CNEW (struct machine_function);
f->use_fast_prologue_epilogue_nregs = -1; f->use_fast_prologue_epilogue_nregs = -1;
f->tls_descriptor_call_expanded_p = 0; f->tls_descriptor_call_expanded_p = 0;
f->call_abi = DEFAULT_ABI;
return f; return f;
} }
...@@ -22994,7 +23070,7 @@ x86_this_parameter (tree function) ...@@ -22994,7 +23070,7 @@ x86_this_parameter (tree function)
{ {
const int *parm_regs; const int *parm_regs;
if (TARGET_64BIT_MS_ABI) if (ix86_function_type_abi (type) == MS_ABI)
parm_regs = x86_64_ms_abi_int_parameter_registers; parm_regs = x86_64_ms_abi_int_parameter_registers;
else else
parm_regs = x86_64_int_parameter_registers; parm_regs = x86_64_int_parameter_registers;
...@@ -23162,7 +23238,7 @@ x86_output_mi_thunk (FILE *file ATTRIBUTE_UNUSED, ...@@ -23162,7 +23238,7 @@ x86_output_mi_thunk (FILE *file ATTRIBUTE_UNUSED,
output_asm_insn ("jmp\t%P0", xops); output_asm_insn ("jmp\t%P0", xops);
/* All thunks should be in the same object as their target, /* All thunks should be in the same object as their target,
and thus binds_local_p should be true. */ and thus binds_local_p should be true. */
else if (TARGET_64BIT_MS_ABI) else if (TARGET_64BIT && cfun->machine->call_abi == MS_ABI)
gcc_unreachable (); gcc_unreachable ();
else else
{ {
...@@ -23245,7 +23321,7 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED) ...@@ -23245,7 +23321,7 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
fprintf (file, "\tleaq\t%sP%d@(%%rip),%%r11\n", LPREFIX, labelno); fprintf (file, "\tleaq\t%sP%d@(%%rip),%%r11\n", LPREFIX, labelno);
#endif #endif
if (!TARGET_64BIT_MS_ABI && flag_pic) if (DEFAULT_ABI == SYSV_ABI && flag_pic)
fprintf (file, "\tcall\t*%s@GOTPCREL(%%rip)\n", MCOUNT_NAME); fprintf (file, "\tcall\t*%s@GOTPCREL(%%rip)\n", MCOUNT_NAME);
else else
fprintf (file, "\tcall\t%s\n", MCOUNT_NAME); fprintf (file, "\tcall\t%s\n", MCOUNT_NAME);
...@@ -25795,6 +25871,9 @@ x86_builtin_vectorization_cost (bool runtime_test) ...@@ -25795,6 +25871,9 @@ x86_builtin_vectorization_cost (bool runtime_test)
} }
/* Initialize the GCC target structure. */ /* Initialize the GCC target structure. */
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY ix86_return_in_memory
#undef TARGET_ATTRIBUTE_TABLE #undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE ix86_attribute_table #define TARGET_ATTRIBUTE_TABLE ix86_attribute_table
#if TARGET_DLLIMPORT_DECL_ATTRIBUTES #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
......
...@@ -446,7 +446,17 @@ extern tree x86_mfence; ...@@ -446,7 +446,17 @@ extern tree x86_mfence;
#define TARGET_MACHO 0 #define TARGET_MACHO 0
/* Likewise, for the Windows 64-bit ABI. */ /* Likewise, for the Windows 64-bit ABI. */
#define TARGET_64BIT_MS_ABI 0 #define TARGET_64BIT_MS_ABI (TARGET_64BIT && ix86_cfun_abi () == MS_ABI)
/* Available call abi. */
enum
{
SYSV_ABI = 0,
MS_ABI = 1
};
/* The default abi form used by target. */
#define DEFAULT_ABI SYSV_ABI
/* Subtargets may reset this to 1 in order to enable 96-bit long double /* Subtargets may reset this to 1 in order to enable 96-bit long double
with the rounding mode forced to 53 bits. */ with the rounding mode forced to 53 bits. */
...@@ -804,7 +814,8 @@ enum target_cpu_default ...@@ -804,7 +814,8 @@ enum target_cpu_default
#define PARM_BOUNDARY BITS_PER_WORD #define PARM_BOUNDARY BITS_PER_WORD
/* Boundary (in *bits*) on which stack pointer should be aligned. */ /* Boundary (in *bits*) on which stack pointer should be aligned. */
#define STACK_BOUNDARY BITS_PER_WORD #define STACK_BOUNDARY (TARGET_64BIT && DEFAULT_ABI == MS_ABI ? 128 \
: BITS_PER_WORD)
/* Boundary (in *bits*) on which the stack pointer prefers to be /* Boundary (in *bits*) on which the stack pointer prefers to be
aligned; the compiler cannot rely on having this alignment. */ aligned; the compiler cannot rely on having this alignment. */
...@@ -1029,6 +1040,35 @@ enum target_cpu_default ...@@ -1029,6 +1040,35 @@ enum target_cpu_default
#define ORDER_REGS_FOR_LOCAL_ALLOC x86_order_regs_for_local_alloc () #define ORDER_REGS_FOR_LOCAL_ALLOC x86_order_regs_for_local_alloc ()
/* regclass.c */
extern void init_regs (void);
#define OVERRIDE_ABI_FORMAT(FNDECL) \
do { \
if (FNDECL == NULL) \
cfun->machine->call_abi = DEFAULT_ABI; \
else \
cfun->machine->call_abi = ix86_function_type_abi (TREE_TYPE (FNDECL)); \
if (cfun->machine->call_abi == MS_ABI && call_used_regs) \
{ \
if (call_used_regs[4 /*RSI*/] != 0 || call_used_regs[5 /*RDI*/] != 0) \
{ \
call_used_regs[4 /*RSI*/] = 0; \
call_used_regs[5 /*RDI*/] = 0; \
init_regs (); \
} \
} \
else if (TARGET_64BIT && call_used_regs) \
{ \
if (call_used_regs[4 /*RSI*/] != 1 || call_used_regs[5 /*RDI*/] != 1) \
{ \
call_used_regs[4 /*RSI*/] = 1; \
call_used_regs[5 /*RDI*/] = 1; \
init_regs (); \
} \
} \
} while (0)
/* Macro to conditionally modify fixed_regs/call_used_regs. */ /* Macro to conditionally modify fixed_regs/call_used_regs. */
#define CONDITIONAL_REGISTER_USAGE \ #define CONDITIONAL_REGISTER_USAGE \
do { \ do { \
...@@ -1079,11 +1119,6 @@ do { \ ...@@ -1079,11 +1119,6 @@ do { \
for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++) \ for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++) \
reg_names[i] = ""; \ reg_names[i] = ""; \
} \ } \
if (TARGET_64BIT_MS_ABI) \
{ \
call_used_regs[4 /*RSI*/] = 0; \
call_used_regs[5 /*RDI*/] = 0; \
} \
} while (0) } while (0)
/* Return number of consecutive hard regs needed starting at reg REGNO /* Return number of consecutive hard regs needed starting at reg REGNO
...@@ -1261,25 +1296,6 @@ do { \ ...@@ -1261,25 +1296,6 @@ do { \
#define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_" #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
/* A C expression which can inhibit the returning of certain function
values in registers, based on the type of value. A nonzero value
says to return the function value in memory, just as large
structures are always returned. Here TYPE will be a C expression
of type `tree', representing the data type of the value.
Note that values of mode `BLKmode' must be explicitly handled by
this macro. Also, the option `-fpcc-struct-return' takes effect
regardless of this macro. On most systems, it is possible to
leave the macro undefined; this causes a default definition to be
used, whose value is the constant 1 for `BLKmode' values, and 0
otherwise.
Do not use this macro to indicate that structures and unions
should always be returned in memory. You should instead use
`DEFAULT_PCC_STRUCT_RETURN' to indicate this. */
#define TARGET_RETURN_IN_MEMORY ix86_return_in_memory
/* This is overridden by <cygwin.h>. */ /* This is overridden by <cygwin.h>. */
#define MS_AGGREGATE_RETURN 0 #define MS_AGGREGATE_RETURN 0
...@@ -1628,7 +1644,11 @@ enum reg_class ...@@ -1628,7 +1644,11 @@ enum reg_class
This space can be allocated by the caller, or be a part of the This space can be allocated by the caller, or be a part of the
machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
which. */ which. */
#define REG_PARM_STACK_SPACE(FNDECL) 0 #define REG_PARM_STACK_SPACE(FNDECL) ix86_reg_parm_stack_space (FNDECL)
#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) (ix86_function_type_abi (FNTYPE) == MS_ABI ? 1 : 0)
extern unsigned int ix86_reg_parm_stack_space (const_tree);
/* Value is the number of bytes of arguments automatically /* Value is the number of bytes of arguments automatically
popped when returning from a subroutine call. popped when returning from a subroutine call.
...@@ -1690,6 +1710,8 @@ typedef struct ix86_args { ...@@ -1690,6 +1710,8 @@ typedef struct ix86_args {
int maybe_vaarg; /* true for calls to possibly vardic fncts. */ int maybe_vaarg; /* true for calls to possibly vardic fncts. */
int float_in_sse; /* 1 if in 32-bit mode SFmode (2 for DFmode) should int float_in_sse; /* 1 if in 32-bit mode SFmode (2 for DFmode) should
be passed in SSE registers. Otherwise 0. */ be passed in SSE registers. Otherwise 0. */
int call_abi; /* Set to SYSV_ABI for sysv abi. Otherwise
MS_ABI for ms abi. */
} CUMULATIVE_ARGS; } CUMULATIVE_ARGS;
/* Initialize a variable CUM of type CUMULATIVE_ARGS /* Initialize a variable CUM of type CUMULATIVE_ARGS
...@@ -2467,6 +2489,9 @@ struct machine_function GTY(()) ...@@ -2467,6 +2489,9 @@ struct machine_function GTY(())
ix86_current_function_calls_tls_descriptor macro for a better ix86_current_function_calls_tls_descriptor macro for a better
approximation. */ approximation. */
int tls_descriptor_call_expanded_p; int tls_descriptor_call_expanded_p;
/* This value is used for amd64 targets and specifies the current abi
to be used. MS_ABI means ms abi. Otherwise SYSV_ABI means sysv abi. */
int call_abi;
}; };
#define ix86_stack_locals (cfun->machine->stack_locals) #define ix86_stack_locals (cfun->machine->stack_locals)
......
...@@ -29,8 +29,9 @@ along with GCC; see the file COPYING3. If not see ...@@ -29,8 +29,9 @@ along with GCC; see the file COPYING3. If not see
/* The ELF ABI for the i386 says that records and unions are returned /* The ELF ABI for the i386 says that records and unions are returned
in memory. */ in memory. */
#undef TARGET_RETURN_IN_MEMORY #define SUBTARGET_RETURN_IN_MEMORY(TYPE, FNTYPE) \
#define TARGET_RETURN_IN_MEMORY ix86_i386elf_return_in_memory (TYPE_MODE (TYPE) == BLKmode \
|| (VECTOR_MODE_P (TYPE_MODE (TYPE)) && int_size_in_bytes (TYPE) == 8))
#undef CPP_SPEC #undef CPP_SPEC
#define CPP_SPEC "" #define CPP_SPEC ""
......
...@@ -38,7 +38,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -38,7 +38,7 @@ along with GCC; see the file COPYING3. If not see
builtin_define_std ("WINNT"); \ builtin_define_std ("WINNT"); \
builtin_define_with_int_value ("_INTEGRAL_MAX_BITS", \ builtin_define_with_int_value ("_INTEGRAL_MAX_BITS", \
TYPE_PRECISION (intmax_type_node));\ TYPE_PRECISION (intmax_type_node));\
if (TARGET_64BIT_MS_ABI) \ if (TARGET_64BIT && DEFAULT_ABI == MS_ABI) \
{ \ { \
builtin_define ("__MINGW64__"); \ builtin_define ("__MINGW64__"); \
builtin_define_std ("WIN64"); \ builtin_define_std ("WIN64"); \
......
...@@ -27,8 +27,9 @@ along with GCC; see the file COPYING3. If not see ...@@ -27,8 +27,9 @@ along with GCC; see the file COPYING3. If not see
/* The svr4 ABI for the i386 says that records and unions are returned /* The svr4 ABI for the i386 says that records and unions are returned
in memory. */ in memory. */
#undef TARGET_RETURN_IN_MEMORY #define SUBTARGET_RETURN_IN_MEMORY(TYPE, FNTYPE) \
#define TARGET_RETURN_IN_MEMORY ix86_i386elf_return_in_memory (TYPE_MODE (TYPE) == BLKmode \
|| (VECTOR_MODE_P (TYPE_MODE (TYPE)) && int_size_in_bytes (TYPE) == 8));
#define TARGET_OS_CPP_BUILTINS() \ #define TARGET_OS_CPP_BUILTINS() \
do \ do \
......
...@@ -110,5 +110,5 @@ along with GCC; see the file COPYING3. If not see ...@@ -110,5 +110,5 @@ along with GCC; see the file COPYING3. If not see
#undef TARGET_ASM_NAMED_SECTION #undef TARGET_ASM_NAMED_SECTION
#define TARGET_ASM_NAMED_SECTION i386_solaris_elf_named_section #define TARGET_ASM_NAMED_SECTION i386_solaris_elf_named_section
#undef TARGET_RETURN_IN_MEMORY #define SUBTARGET_RETURN_IN_MEMORY(TYPE, FNTYPE) \
#define TARGET_RETURN_IN_MEMORY ix86_sol10_return_in_memory ix86_sol10_return_in_memory (TYPE, FNTYPE)
...@@ -25,8 +25,9 @@ along with GCC; see the file COPYING3. If not see ...@@ -25,8 +25,9 @@ along with GCC; see the file COPYING3. If not see
/* The svr4 ABI for the i386 says that records and unions are returned /* The svr4 ABI for the i386 says that records and unions are returned
in memory. */ in memory. */
#undef TARGET_RETURN_IN_MEMORY #define SUBTARGET_RETURN_IN_MEMORY(TYPE, FNTYPE) \
#define TARGET_RETURN_IN_MEMORY ix86_i386elf_return_in_memory (TYPE_MODE (TYPE) == BLKmode \
|| (VECTOR_MODE_P (TYPE_MODE (TYPE)) && int_size_in_bytes (TYPE) == 8));
/* Output at beginning of assembler file. */ /* Output at beginning of assembler file. */
/* The .file command should always begin the output. */ /* The .file command should always begin the output. */
......
...@@ -22,5 +22,5 @@ along with GCC; see the file COPYING3. If not see ...@@ -22,5 +22,5 @@ along with GCC; see the file COPYING3. If not see
/* VxWorks uses the same ABI as Solaris 10. */ /* VxWorks uses the same ABI as Solaris 10. */
#undef TARGET_RETURN_IN_MEMORY #define SUBTARGET_RETURN_IN_MEMORY(TYPE, FNTYPE) \
#define TARGET_RETURN_IN_MEMORY ix86_sol10_return_in_memory ix86_sol10_return_in_memory (TYPE, FNTYPE)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment