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>
PR debug/49887
......
......@@ -3829,13 +3829,41 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
rtx val = argvec[argnum].value;
rtx reg = argvec[argnum].reg;
int partial = argvec[argnum].partial;
int size = 0;
/* Handle calls that pass values in multiple non-contiguous
locations. The PA64 has examples of this for library calls. */
if (reg != 0 && GET_CODE (reg) == PARALLEL)
emit_group_load (reg, val, NULL_TREE, GET_MODE_SIZE (mode));
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;
}
......@@ -3901,6 +3929,15 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
valreg,
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
that it should complain if nonvolatile values are live. For
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)
if (type && BYTES_BIG_ENDIAN && INTEGRAL_TYPE_P (type))
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;
}
......
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