Commit f79e1b0f by Eric Botcazou Committed by Eric Botcazou

re PR target/46208 (redundant extensions of argument registers)

	PR target/46208
	* config/sparc/sparc.c (TARGET_PROMOTE_PROTOTYPES): Delete.
	(sparc_promote_prototypes): Likewise.
	(sparc_promote_function_mode): Promote in 32-bit mode as well.
	(sparc_return_in_memory): Remove superfluous parentheses.
	(sparc_struct_value_rtx): Fix long lines.
	(sparc_function_value_1): Promote in 32-bit mode as well.

From-SVN: r166433
parent 79770339
2010-11-08 Eric Botcazou <ebotcazou@adacore.com>
PR target/46208
* config/sparc/sparc.c (TARGET_PROMOTE_PROTOTYPES): Delete.
(sparc_promote_prototypes): Likewise.
(sparc_promote_function_mode): Promote in 32-bit mode as well.
(sparc_return_in_memory): Remove superfluous parentheses.
(sparc_struct_value_rtx): Fix long lines.
(sparc_function_value_1): Promote in 32-bit mode as well.
2010-11-08 Andrey Belevantsev <abel@ispras.ru> 2010-11-08 Andrey Belevantsev <abel@ispras.ru>
PR rtl-optimization/45352 PR rtl-optimization/45352
...@@ -405,7 +405,6 @@ static rtx sparc_tls_got (void); ...@@ -405,7 +405,6 @@ static rtx sparc_tls_got (void);
static const char *get_some_local_dynamic_name (void); static const char *get_some_local_dynamic_name (void);
static int get_some_local_dynamic_name_1 (rtx *, void *); static int get_some_local_dynamic_name_1 (rtx *, void *);
static bool sparc_rtx_costs (rtx, int, int, int *, bool); static bool sparc_rtx_costs (rtx, int, int, int *, bool);
static bool sparc_promote_prototypes (const_tree);
static rtx sparc_function_value (const_tree, const_tree, bool); static rtx sparc_function_value (const_tree, const_tree, bool);
static rtx sparc_libcall_value (enum machine_mode, const_rtx); static rtx sparc_libcall_value (enum machine_mode, const_rtx);
static bool sparc_function_value_regno_p (const unsigned int); static bool sparc_function_value_regno_p (const unsigned int);
...@@ -554,9 +553,6 @@ static const struct default_options sparc_option_optimization_table[] = ...@@ -554,9 +553,6 @@ static const struct default_options sparc_option_optimization_table[] =
#undef TARGET_PROMOTE_FUNCTION_MODE #undef TARGET_PROMOTE_FUNCTION_MODE
#define TARGET_PROMOTE_FUNCTION_MODE sparc_promote_function_mode #define TARGET_PROMOTE_FUNCTION_MODE sparc_promote_function_mode
#undef TARGET_PROMOTE_PROTOTYPES
#define TARGET_PROMOTE_PROTOTYPES sparc_promote_prototypes
#undef TARGET_FUNCTION_VALUE #undef TARGET_FUNCTION_VALUE
#define TARGET_FUNCTION_VALUE sparc_function_value #define TARGET_FUNCTION_VALUE sparc_function_value
#undef TARGET_LIBCALL_VALUE #undef TARGET_LIBCALL_VALUE
...@@ -4909,15 +4905,6 @@ init_cumulative_args (struct sparc_args *cum, tree fntype, ...@@ -4909,15 +4905,6 @@ init_cumulative_args (struct sparc_args *cum, tree fntype,
cum->libcall_p = fntype == 0; cum->libcall_p = fntype == 0;
} }
/* Handle the TARGET_PROMOTE_PROTOTYPES target hook.
When a prototype says `char' or `short', really pass an `int'. */
static bool
sparc_promote_prototypes (const_tree fntype ATTRIBUTE_UNUSED)
{
return TARGET_ARCH32 ? true : false;
}
/* Handle promotion of pointer and integer arguments. */ /* Handle promotion of pointer and integer arguments. */
static enum machine_mode static enum machine_mode
...@@ -4933,12 +4920,8 @@ sparc_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, ...@@ -4933,12 +4920,8 @@ sparc_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
return Pmode; return Pmode;
} }
/* For TARGET_ARCH64 we need this, as we don't have instructions /* Integral arguments are passed as full words, as per the ABI. */
for arithmetic operations which do zero/sign extension at the same time, if (GET_MODE_CLASS (mode) == MODE_INT
so without this we end up with a srl/sra after every assignment to an
user variable, which means very very bad code. */
if (TARGET_ARCH64
&& GET_MODE_CLASS (mode) == MODE_INT
&& GET_MODE_SIZE (mode) < UNITS_PER_WORD) && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
return word_mode; return word_mode;
...@@ -5959,8 +5942,8 @@ sparc_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) ...@@ -5959,8 +5942,8 @@ sparc_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
integers are returned like floats of the same size, that is in integers are returned like floats of the same size, that is in
registers. Return all vector floats like structure and unions; registers. Return all vector floats like structure and unions;
note that they always have BLKmode like the latter. */ note that they always have BLKmode like the latter. */
return ((TYPE_MODE (type) == BLKmode return (TYPE_MODE (type) == BLKmode
&& (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 32)); && (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 32);
} }
/* Handle the TARGET_STRUCT_VALUE target hook. /* Handle the TARGET_STRUCT_VALUE target hook.
...@@ -6001,22 +5984,22 @@ sparc_struct_value_rtx (tree fndecl, int incoming) ...@@ -6001,22 +5984,22 @@ sparc_struct_value_rtx (tree fndecl, int incoming)
tree size = TYPE_SIZE_UNIT (TREE_TYPE (fndecl)); tree size = TYPE_SIZE_UNIT (TREE_TYPE (fndecl));
rtx size_rtx = GEN_INT (TREE_INT_CST_LOW (size) & 0xfff); rtx size_rtx = GEN_INT (TREE_INT_CST_LOW (size) & 0xfff);
/* Construct a temporary return value */ /* Construct a temporary return value */
rtx temp_val = assign_stack_local (Pmode, TREE_INT_CST_LOW (size), 0); rtx temp_val
= assign_stack_local (Pmode, TREE_INT_CST_LOW (size), 0);
/* Implement SPARC 32-bit psABI callee returns struck checking /* Implement SPARC 32-bit psABI callee return struct checking:
requirements:
Fetch the instruction where we will return to and see if Fetch the instruction where we will return to and see if
it's an unimp instruction (the most significant 10 bits it's an unimp instruction (the most significant 10 bits
will be zero). */ will be zero). */
emit_move_insn (scratch, gen_rtx_MEM (SImode, emit_move_insn (scratch, gen_rtx_MEM (SImode,
plus_constant (ret_rtx, 8))); plus_constant (ret_rtx, 8)));
/* Assume the size is valid and pre-adjust */ /* Assume the size is valid and pre-adjust */
emit_insn (gen_add3_insn (ret_rtx, ret_rtx, GEN_INT (4))); emit_insn (gen_add3_insn (ret_rtx, ret_rtx, GEN_INT (4)));
emit_cmp_and_jump_insns (scratch, size_rtx, EQ, const0_rtx, SImode, 0, endlab); emit_cmp_and_jump_insns (scratch, size_rtx, EQ, const0_rtx, SImode,
0, endlab);
emit_insn (gen_sub3_insn (ret_rtx, ret_rtx, GEN_INT (4))); emit_insn (gen_sub3_insn (ret_rtx, ret_rtx, GEN_INT (4)));
/* Assign stack temp: /* Write the address of the memory pointed to by temp_val into
Write the address of the memory pointed to by temp_val into
the memory pointed to by mem */ the memory pointed to by mem */
emit_move_insn (mem, XEXP (temp_val, 0)); emit_move_insn (mem, XEXP (temp_val, 0));
emit_label (endlab); emit_label (endlab);
...@@ -6107,12 +6090,19 @@ sparc_function_value_1 (const_tree type, enum machine_mode mode, ...@@ -6107,12 +6090,19 @@ sparc_function_value_1 (const_tree type, enum machine_mode mode,
mclass = MODE_INT; mclass = MODE_INT;
} }
/* This must match sparc_promote_function_mode. /* We should only have pointer and integer types at this point. This
??? Maybe 32-bit pointers should actually remain in Pmode? */ must match sparc_promote_function_mode. */
else if (mclass == MODE_INT && GET_MODE_SIZE (mode) < UNITS_PER_WORD) else if (mclass == MODE_INT && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
mode = word_mode; mode = word_mode;
} }
/* We should only have pointer and integer types at this point. This must
match sparc_promote_function_mode. */
else if (TARGET_ARCH32
&& mclass == MODE_INT
&& GET_MODE_SIZE (mode) < UNITS_PER_WORD)
mode = word_mode;
if ((mclass == MODE_FLOAT || mclass == MODE_COMPLEX_FLOAT) && TARGET_FPU) if ((mclass == MODE_FLOAT || mclass == MODE_COMPLEX_FLOAT) && TARGET_FPU)
regno = SPARC_FP_ARG_FIRST; regno = SPARC_FP_ARG_FIRST;
else else
...@@ -6122,9 +6112,8 @@ sparc_function_value_1 (const_tree type, enum machine_mode mode, ...@@ -6122,9 +6112,8 @@ sparc_function_value_1 (const_tree type, enum machine_mode mode,
} }
/* Handle TARGET_FUNCTION_VALUE. /* Handle TARGET_FUNCTION_VALUE.
On the SPARC, the value is found in the first "output" register, but the
On SPARC the value is found in the first "output" register, but the called called function leaves it in the first "input" register. */
function leaves it in the first "input" register. */
static rtx static rtx
sparc_function_value (const_tree valtype, sparc_function_value (const_tree valtype,
...@@ -6143,9 +6132,9 @@ sparc_libcall_value (enum machine_mode mode, ...@@ -6143,9 +6132,9 @@ sparc_libcall_value (enum machine_mode mode,
return sparc_function_value_1 (NULL_TREE, mode, false); return sparc_function_value_1 (NULL_TREE, mode, false);
} }
/* Handle FUNCTION_VALUE_REGNO_P. /* Handle FUNCTION_VALUE_REGNO_P.
On SPARC, the first "output" reg is used for integer values, and On the SPARC, the first "output" reg is used for integer values, and the
the first floating point register is used for floating point values. */ first floating point register is used for floating point values. */
static bool static bool
sparc_function_value_regno_p (const unsigned int regno) sparc_function_value_regno_p (const unsigned int regno)
......
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