Back out these patches:

2003-06-02  J"orn Rennecke <joern.rennecke@superh.com>
          * sh.h (OLD_ARG_MODE): New macro.
          (FUNCTION_ARG_ADVANCE, FUNCTION_ARG_PASS_BY_REFERENCE): Use it.
          (FUNCTION_ARG_1): Break out of:
          (FUNCTION_ARG).  Use OLD_ARG_MODE.
	 2003-06-06  J"orn Rennecke <joern.rennecke@superh.com>
          * sh.h (FUNCTION_ARG_1): Consistently use NEW_MODE for the mode
          of the generated register.

	* sh.h (FUNCTION_ARG_SCmode_WART): Define.
	(FUNCTION_ARG): Unless FUNCTION_ARG_SCmode_WART is defined and
	an even number of floating point regs are in use, use the same
	sequence of argument passing registers for SCmode as would be
	used for two SFmode values.
	* sh.c (sh_va_arg): If FUNCTION_ARG_SCmode_WART is defined,
	swap real / imaginary parts in incoming SCmode values passed
	in registers.

From-SVN: r68430
This commit is contained in:
J"orn Rennecke 2003-06-24 17:22:05 +00:00 committed by Joern Rennecke
parent d28dd0f9d1
commit 6d1cb95f3f
3 changed files with 139 additions and 43 deletions

View File

@ -1,3 +1,24 @@
2003-06-24 J"orn Rennecke <joern.rennecke@superh.com>
Back out these patches:
2003-06-02 J"orn Rennecke <joern.rennecke@superh.com>
* sh.h (OLD_ARG_MODE): New macro.
(FUNCTION_ARG_ADVANCE, FUNCTION_ARG_PASS_BY_REFERENCE): Use it.
(FUNCTION_ARG_1): Break out of:
(FUNCTION_ARG). Use OLD_ARG_MODE.
2003-06-06 J"orn Rennecke <joern.rennecke@superh.com>
* sh.h (FUNCTION_ARG_1): Consistently use NEW_MODE for the mode
of the generated register.
* sh.h (FUNCTION_ARG_SCmode_WART): Define.
(FUNCTION_ARG): Unless FUNCTION_ARG_SCmode_WART is defined and
an even number of floating point regs are in use, use the same
sequence of argument passing registers for SCmode as would be
used for two SFmode values.
* sh.c (sh_va_arg): If FUNCTION_ARG_SCmode_WART is defined,
swap real / imaginary parts in incoming SCmode values passed
in registers.
2003-06-24 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de> 2003-06-24 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
PR target/11260 PR target/11260

View File

@ -5940,8 +5940,9 @@ sh_va_arg (valist, type)
HOST_WIDE_INT size, rsize; HOST_WIDE_INT size, rsize;
tree tmp, pptr_type_node; tree tmp, pptr_type_node;
rtx addr_rtx, r; rtx addr_rtx, r;
rtx result; rtx result_ptr, result = NULL_RTX;
int pass_by_ref = MUST_PASS_IN_STACK (TYPE_MODE (type), type); int pass_by_ref = MUST_PASS_IN_STACK (TYPE_MODE (type), type);
rtx lab_over;
size = int_size_in_bytes (type); size = int_size_in_bytes (type);
rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD; rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
@ -5955,7 +5956,7 @@ sh_va_arg (valist, type)
tree f_next_o, f_next_o_limit, f_next_fp, f_next_fp_limit, f_next_stack; tree f_next_o, f_next_o_limit, f_next_fp, f_next_fp_limit, f_next_stack;
tree next_o, next_o_limit, next_fp, next_fp_limit, next_stack; tree next_o, next_o_limit, next_fp, next_fp_limit, next_stack;
int pass_as_float; int pass_as_float;
rtx lab_false, lab_over; rtx lab_false;
f_next_o = TYPE_FIELDS (va_list_type_node); f_next_o = TYPE_FIELDS (va_list_type_node);
f_next_o_limit = TREE_CHAIN (f_next_o); f_next_o_limit = TREE_CHAIN (f_next_o);
@ -5973,6 +5974,16 @@ sh_va_arg (valist, type)
next_stack = build (COMPONENT_REF, TREE_TYPE (f_next_stack), next_stack = build (COMPONENT_REF, TREE_TYPE (f_next_stack),
valist, f_next_stack); valist, f_next_stack);
/* Structures with a single member with a distinct mode are passed
like their member. This is relevant if the latter has a REAL_TYPE
or COMPLEX_TYPE type. */
if (TREE_CODE (type) == RECORD_TYPE
&& TYPE_FIELDS (type)
&& TREE_CODE (TYPE_FIELDS (type)) == FIELD_DECL
&& (TREE_CODE (TREE_TYPE (TYPE_FIELDS (type))) == REAL_TYPE
|| TREE_CODE (TREE_TYPE (TYPE_FIELDS (type))) == COMPLEX_TYPE)
&& TREE_CHAIN (TYPE_FIELDS (type)) == NULL_TREE)
type = TREE_TYPE (TYPE_FIELDS (type));
if (TARGET_SH4) if (TARGET_SH4)
{ {
pass_as_float = ((TREE_CODE (type) == REAL_TYPE && size <= 8) pass_as_float = ((TREE_CODE (type) == REAL_TYPE && size <= 8)
@ -5989,6 +6000,9 @@ sh_va_arg (valist, type)
lab_false = gen_label_rtx (); lab_false = gen_label_rtx ();
lab_over = gen_label_rtx (); lab_over = gen_label_rtx ();
tmp = make_tree (pptr_type_node, addr_rtx);
valist = build1 (INDIRECT_REF, ptr_type_node, tmp);
if (pass_as_float) if (pass_as_float)
{ {
int first_floatreg int first_floatreg
@ -6018,6 +6032,37 @@ sh_va_arg (valist, type)
if (r != addr_rtx) if (r != addr_rtx)
emit_move_insn (addr_rtx, r); emit_move_insn (addr_rtx, r);
#ifdef FUNCTION_ARG_SCmode_WART
if (TYPE_MODE (type) == SCmode && TARGET_SH4 && TARGET_LITTLE_ENDIAN)
{
rtx addr, real, imag, result_value, slot;
tree subtype = TREE_TYPE (type);
addr = std_expand_builtin_va_arg (valist, subtype);
#ifdef POINTERS_EXTEND_UNSIGNED
if (GET_MODE (addr) != Pmode)
addr = convert_memory_address (Pmode, addr);
#endif
imag = gen_rtx_MEM (TYPE_MODE (type), addr);
set_mem_alias_set (imag, get_varargs_alias_set ());
addr = std_expand_builtin_va_arg (valist, subtype);
#ifdef POINTERS_EXTEND_UNSIGNED
if (GET_MODE (addr) != Pmode)
addr = convert_memory_address (Pmode, addr);
#endif
real = gen_rtx_MEM (TYPE_MODE (type), addr);
set_mem_alias_set (real, get_varargs_alias_set ());
result_value = gen_rtx_CONCAT (SCmode, real, imag);
/* ??? this interface is stupid - why require a pointer? */
result = gen_reg_rtx (Pmode);
slot = assign_stack_temp (SCmode, 8, 0);
emit_move_insn (slot, result_value);
emit_move_insn (result, XEXP (slot, 0));
}
#endif /* FUNCTION_ARG_SCmode_WART */
emit_jump_insn (gen_jump (lab_over)); emit_jump_insn (gen_jump (lab_over));
emit_barrier (); emit_barrier ();
emit_label (lab_false); emit_label (lab_false);
@ -6060,16 +6105,22 @@ sh_va_arg (valist, type)
emit_move_insn (addr_rtx, r); emit_move_insn (addr_rtx, r);
} }
emit_label (lab_over); if (! result)
emit_label (lab_over);
tmp = make_tree (pptr_type_node, addr_rtx);
valist = build1 (INDIRECT_REF, ptr_type_node, tmp);
} }
/* ??? In va-sh.h, there had been code to make values larger than /* ??? In va-sh.h, there had been code to make values larger than
size 8 indirect. This does not match the FUNCTION_ARG macros. */ size 8 indirect. This does not match the FUNCTION_ARG macros. */
result = std_expand_builtin_va_arg (valist, type); result_ptr = std_expand_builtin_va_arg (valist, type);
if (result)
{
emit_move_insn (result, result_ptr);
emit_label (lab_over);
}
else
result = result_ptr;
if (pass_by_ref) if (pass_by_ref)
{ {
#ifdef POINTERS_EXTEND_UNSIGNED #ifdef POINTERS_EXTEND_UNSIGNED

View File

@ -1867,20 +1867,12 @@ struct sh_args {
(CUM).outgoing = 0; \ (CUM).outgoing = 0; \
} while (0) } while (0)
#define OLD_ARG_MODE(MODE, TYPE) \
(((TYPE) \
&& (TREE_CODE (TYPE) == RECORD_TYPE || TREE_CODE (TYPE) == UNION_TYPE) \
&& (MODE) != BLKmode && GET_MODE_CLASS (MODE) != MODE_INT) \
? int_mode_for_mode (MODE) : (MODE))
/* Update the data in CUM to advance over an argument /* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE. of mode MODE and data type TYPE.
(TYPE is null for libcalls where that information may not be (TYPE is null for libcalls where that information may not be
available.) */ available.) */
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
do { \
enum machine_mode MODE_ = OLD_ARG_MODE ((MODE), (TYPE));\
if ((CUM).force_mem) \ if ((CUM).force_mem) \
(CUM).force_mem = 0; \ (CUM).force_mem = 0; \
else if (TARGET_SH5) \ else if (TARGET_SH5) \
@ -1888,17 +1880,17 @@ do { \
tree TYPE_ = ((CUM).byref && (TYPE) \ tree TYPE_ = ((CUM).byref && (TYPE) \
? TREE_TYPE (TYPE) \ ? TREE_TYPE (TYPE) \
: (TYPE)); \ : (TYPE)); \
int dwords, numregs; \ enum machine_mode MODE_ = ((CUM).byref && (TYPE) \
? TYPE_MODE (TYPE_) \
: (MODE)); \
int dwords = (((CUM).byref \
? (CUM).byref \
: (MODE_) == BLKmode \
? int_size_in_bytes (TYPE_) \
: GET_MODE_SIZE (MODE_)) + 7) / 8; \
int numregs = MIN (dwords, NPARM_REGS (SImode) \
- (CUM).arg_count[(int) SH_ARG_INT]); \
\ \
MODE_ = ((CUM).byref && (TYPE) \
? TYPE_MODE (TYPE_) : (MODE_)); \
dwords = (((CUM).byref \
? (CUM).byref \
: (MODE_) == BLKmode \
? int_size_in_bytes (TYPE_) \
: GET_MODE_SIZE (MODE_)) + 7) / 8; \
numregs = MIN (dwords, NPARM_REGS (SImode) \
- (CUM).arg_count[(int) SH_ARG_INT]); \
if (numregs) \ if (numregs) \
{ \ { \
(CUM).arg_count[(int) SH_ARG_INT] += numregs; \ (CUM).arg_count[(int) SH_ARG_INT] += numregs; \
@ -1990,13 +1982,12 @@ do { \
} \ } \
} \ } \
} \ } \
else if (! TARGET_SH4 || PASS_IN_REG_P ((CUM), (MODE_), (TYPE))) \ else if (! TARGET_SH4 || PASS_IN_REG_P ((CUM), (MODE), (TYPE))) \
((CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE_)] \ ((CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE)] \
= (ROUND_REG ((CUM), (MODE_)) \ = (ROUND_REG ((CUM), (MODE)) \
+ ((MODE_) == BLKmode \ + ((MODE) == BLKmode \
? ROUND_ADVANCE (int_size_in_bytes (TYPE)) \ ? ROUND_ADVANCE (int_size_in_bytes (TYPE)) \
: ROUND_ADVANCE (GET_MODE_SIZE (MODE_))))); \ : ROUND_ADVANCE (GET_MODE_SIZE (MODE)))))
} while (0)
/* Return boolean indicating arg of mode MODE will be passed in a reg. /* Return boolean indicating arg of mode MODE will be passed in a reg.
This macro is only used in this file. */ This macro is only used in this file. */
@ -2016,6 +2007,24 @@ do { \
<= NPARM_REGS (MODE))) \ <= NPARM_REGS (MODE))) \
: ROUND_REG ((CUM), (MODE)) < NPARM_REGS (MODE))) : ROUND_REG ((CUM), (MODE)) < NPARM_REGS (MODE)))
/* By accident we got stuck with passing SCmode on SH4 little endian
in two registers that are nominally successive - which is different from
two single SFmode values, where we take endianness translation into
account. That does not work at all if an odd number of registers is
already in use, so that got fixed, but library functions are still more
likely to use complex numbers without mixing them with SFmode arguments
(which in C would have to be structures), so for the sake of ABI
compatibility the way SCmode values are passed when an even number of
FP registers is in use remains different from a pair of SFmode values for
now.
I.e.:
foo (double); a: fr5,fr4
foo (float a, float b); a: fr5 b: fr4
foo (__complex float a); a.real fr4 a.imag: fr5 - for consistency,
this should be the other way round...
foo (float a, __complex float b); a: fr5 b.real: fr4 b.imag: fr7 */
#define FUNCTION_ARG_SCmode_WART 1
/* Define where to put the arguments to a function. /* Define where to put the arguments to a function.
Value is zero to push the argument on the stack, Value is zero to push the argument on the stack,
or a hard register in which to store the argument. or a hard register in which to store the argument.
@ -2035,29 +2044,44 @@ do { \
its data type forbids. */ its data type forbids. */
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
FUNCTION_ARG_1 ((CUM), OLD_ARG_MODE ((MODE), (TYPE)), (MODE), (TYPE), (NAMED))
#define FUNCTION_ARG_1(CUM, MODE, NEW_MODE, TYPE, NAMED) \
((! TARGET_SH5 \ ((! TARGET_SH5 \
&& PASS_IN_REG_P ((CUM), (MODE), (TYPE)) \ && PASS_IN_REG_P ((CUM), (MODE), (TYPE)) \
&& ((NAMED) || !TARGET_HITACHI)) \ && ((NAMED) || !TARGET_HITACHI)) \
? gen_rtx_REG ((NEW_MODE), \ ? (((MODE) == SCmode && TARGET_SH4 && TARGET_LITTLE_ENDIAN \
((BASE_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE))) \ && (! FUNCTION_ARG_SCmode_WART || (ROUND_REG ((CUM), (MODE)) & 1)))\
^ ((MODE) == SFmode && TARGET_SH4 \ ? (gen_rtx_PARALLEL \
&& TARGET_LITTLE_ENDIAN != 0))) \ (SCmode, \
(gen_rtvec \
(2, \
(gen_rtx_EXPR_LIST \
(VOIDmode, \
gen_rtx_REG (SFmode, \
BASE_ARG_REG (MODE) \
+ ROUND_REG ((CUM), (MODE)) ^ 1), \
const0_rtx)), \
(gen_rtx_EXPR_LIST \
(VOIDmode, \
gen_rtx_REG (SFmode, \
BASE_ARG_REG (MODE) \
+ (ROUND_REG ((CUM), (MODE)) + 1) ^ 1), \
GEN_INT (4))))))) \
: gen_rtx_REG ((MODE), \
((BASE_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE))) \
^ ((MODE) == SFmode && TARGET_SH4 \
&& TARGET_LITTLE_ENDIAN != 0)))) \
: TARGET_SH5 \ : TARGET_SH5 \
? ((MODE) == VOIDmode && TARGET_SHCOMPACT \ ? ((MODE) == VOIDmode && TARGET_SHCOMPACT \
? GEN_INT ((CUM).call_cookie) \ ? GEN_INT ((CUM).call_cookie) \
/* The following test assumes unnamed arguments are promoted to \ /* The following test assumes unnamed arguments are promoted to \
DFmode. */ \ DFmode. */ \
: (MODE) == SFmode && (CUM).free_single_fp_reg \ : (MODE) == SFmode && (CUM).free_single_fp_reg \
? SH5_PROTOTYPED_FLOAT_ARG ((CUM), (NEW_MODE), (CUM).free_single_fp_reg) \ ? SH5_PROTOTYPED_FLOAT_ARG ((CUM), (MODE), (CUM).free_single_fp_reg) \
: (GET_SH_ARG_CLASS (MODE) == SH_ARG_FLOAT \ : (GET_SH_ARG_CLASS (MODE) == SH_ARG_FLOAT \
&& ((NAMED) || ! (CUM).prototype_p) \ && ((NAMED) || ! (CUM).prototype_p) \
&& (CUM).arg_count[(int) SH_ARG_FLOAT] < NPARM_REGS (SFmode)) \ && (CUM).arg_count[(int) SH_ARG_FLOAT] < NPARM_REGS (SFmode)) \
? ((! (CUM).prototype_p && TARGET_SHMEDIA) \ ? ((! (CUM).prototype_p && TARGET_SHMEDIA) \
? SH5_PROTOTYPELESS_FLOAT_ARG ((CUM), (NEW_MODE)) \ ? SH5_PROTOTYPELESS_FLOAT_ARG ((CUM), (MODE)) \
: SH5_PROTOTYPED_FLOAT_ARG ((CUM), (NEW_MODE), \ : SH5_PROTOTYPED_FLOAT_ARG ((CUM), (MODE), \
FIRST_FP_PARM_REG \ FIRST_FP_PARM_REG \
+ (CUM).arg_count[(int) SH_ARG_FLOAT])) \ + (CUM).arg_count[(int) SH_ARG_FLOAT])) \
: ((CUM).arg_count[(int) SH_ARG_INT] < NPARM_REGS (SImode) \ : ((CUM).arg_count[(int) SH_ARG_INT] < NPARM_REGS (SImode) \
@ -2065,7 +2089,7 @@ do { \
|| (! SHCOMPACT_FORCE_ON_STACK ((MODE), (TYPE)) \ || (! SHCOMPACT_FORCE_ON_STACK ((MODE), (TYPE)) \
&& ! SH5_WOULD_BE_PARTIAL_NREGS ((CUM), (MODE), \ && ! SH5_WOULD_BE_PARTIAL_NREGS ((CUM), (MODE), \
(TYPE), (NAMED))))) \ (TYPE), (NAMED))))) \
? gen_rtx_REG ((NEW_MODE), (FIRST_PARM_REG \ ? gen_rtx_REG ((MODE), (FIRST_PARM_REG \
+ (CUM).arg_count[(int) SH_ARG_INT])) \ + (CUM).arg_count[(int) SH_ARG_INT])) \
: 0) \ : 0) \
: 0) : 0)
@ -2076,7 +2100,7 @@ do { \
loads them into the full 64-bits registers. */ loads them into the full 64-bits registers. */
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM,MODE,TYPE,NAMED) \ #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM,MODE,TYPE,NAMED) \
(MUST_PASS_IN_STACK ((MODE), (TYPE)) \ (MUST_PASS_IN_STACK ((MODE), (TYPE)) \
|| SHCOMPACT_BYREF ((CUM), OLD_ARG_MODE ((MODE), (TYPE)), (TYPE), (NAMED))) || SHCOMPACT_BYREF ((CUM), (MODE), (TYPE), (NAMED)))
#define SHCOMPACT_BYREF(CUM, MODE, TYPE, NAMED) \ #define SHCOMPACT_BYREF(CUM, MODE, TYPE, NAMED) \
((CUM).byref \ ((CUM).byref \