Commit 460b171d by Julian Brown Committed by Julian Brown

calls.c (emit_library_call_value_1): Support padding for libcall arguments and return values.

	gcc/
	* calls.c (emit_library_call_value_1): Support padding for libcall
	arguments and return values.
	* config/arm/arm.c (arm_pad_arg_upward): Pad half-float values
	downwards in big-endian mode.

From-SVN: r177022
parent c228a069
2011-08-01 Julian Brown <julian@codesourcery.com>
* calls.c (emit_library_call_value_1): Support padding for libcall
arguments and return values.
* config/arm/arm.c (arm_pad_arg_upward): Pad half-float values
downwards in big-endian mode.
2011-08-01 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> 2011-08-01 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR debug/49887 PR debug/49887
......
...@@ -3829,13 +3829,41 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, ...@@ -3829,13 +3829,41 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
rtx val = argvec[argnum].value; rtx val = argvec[argnum].value;
rtx reg = argvec[argnum].reg; rtx reg = argvec[argnum].reg;
int partial = argvec[argnum].partial; int partial = argvec[argnum].partial;
int size = 0;
/* Handle calls that pass values in multiple non-contiguous /* Handle calls that pass values in multiple non-contiguous
locations. The PA64 has examples of this for library calls. */ locations. The PA64 has examples of this for library calls. */
if (reg != 0 && GET_CODE (reg) == PARALLEL) if (reg != 0 && GET_CODE (reg) == PARALLEL)
emit_group_load (reg, val, NULL_TREE, GET_MODE_SIZE (mode)); emit_group_load (reg, val, NULL_TREE, GET_MODE_SIZE (mode));
else if (reg != 0 && partial == 0) else if (reg != 0 && partial == 0)
emit_move_insn (reg, val); {
emit_move_insn (reg, val);
#ifdef BLOCK_REG_PADDING
size = GET_MODE_SIZE (argvec[argnum].mode);
/* Copied from load_register_parameters. */
/* Handle case where we have a value that needs shifting
up to the msb. eg. a QImode value and we're padding
upward on a BYTES_BIG_ENDIAN machine. */
if (size < UNITS_PER_WORD
&& (argvec[argnum].locate.where_pad
== (BYTES_BIG_ENDIAN ? upward : downward)))
{
rtx x;
int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
/* Assigning REG here rather than a temp makes CALL_FUSAGE
report the whole reg as used. Strictly speaking, the
call only uses SIZE bytes at the msb end, but it doesn't
seem worth generating rtl to say that. */
reg = gen_rtx_REG (word_mode, REGNO (reg));
x = expand_shift (LSHIFT_EXPR, word_mode, reg, shift, reg, 1);
if (x != reg)
emit_move_insn (reg, x);
}
#endif
}
NO_DEFER_POP; NO_DEFER_POP;
} }
...@@ -3901,6 +3929,15 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, ...@@ -3901,6 +3929,15 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
valreg, valreg,
old_inhibit_defer_pop + 1, call_fusage, flags, args_so_far); old_inhibit_defer_pop + 1, call_fusage, flags, args_so_far);
/* Right-shift returned value if necessary. */
if (!pcc_struct_value
&& TYPE_MODE (tfom) != BLKmode
&& targetm.calls.return_in_msb (tfom))
{
shift_return_value (TYPE_MODE (tfom), false, valreg);
valreg = gen_rtx_REG (TYPE_MODE (tfom), REGNO (valreg));
}
/* For calls to `setjmp', etc., inform function.c:setjmp_warnings /* For calls to `setjmp', etc., inform function.c:setjmp_warnings
that it should complain if nonvolatile values are live. For that it should complain if nonvolatile values are live. For
functions that cannot return, inform flow that control does not functions that cannot return, inform flow that control does not
......
...@@ -11261,6 +11261,15 @@ arm_pad_arg_upward (enum machine_mode mode, const_tree type) ...@@ -11261,6 +11261,15 @@ arm_pad_arg_upward (enum machine_mode mode, const_tree type)
if (type && BYTES_BIG_ENDIAN && INTEGRAL_TYPE_P (type)) if (type && BYTES_BIG_ENDIAN && INTEGRAL_TYPE_P (type))
return false; return false;
/* Half-float values are only passed to libcalls, not regular functions.
They should be passed and returned as "short"s (see RTABI). To achieve
that effect in big-endian mode, pad downwards so the value is passed in
the least-significant end of the register. ??? This needs to be here
rather than in arm_pad_reg_upward due to peculiarity in the handling of
libcall arguments. */
if (BYTES_BIG_ENDIAN && mode == HFmode)
return false;
return true; return true;
} }
......
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