Hello!
The list of possible return registers in ix86_function_value_regno_p
is incomplete. 32bit and 64bit targets use %[er]dx register for
DImode and TImode values respectively and %st(1) and %xmm1 for
imaginary part of complex values. Additionally, 64bit SYSV targets use
%rdi and %rsi registers to pass structures (as declared in
x86_64_int_return_registers array).
function_value_regno_p is mainly used in (obsolete) __builtin_apply
and __builtin_return builtins, but it is also used in mode-switching
pass to check if regno is OK as multiple register value return.
Attached patch fixes PR 58792 by adding missing registers to
function_value_regno_p.
2013-10-19 Uros Bizjak <[email protected]>
PR target/58792
* config/i386/i386.c (ix86_function_value_regno): Add DX_REG,
ST1_REG and XMM1_REG for 32bit and 64bit targets. Also add DI_REG
and SI_REG for 64bit SYSV ABI targets.
The patch was tested on x86_64-pc-linux-gnu {,-m32}, also with
'--with-arch=core-avx-i --with-cpu=core-avx-i --with-fpmath=avx'
configured compiler for all default languages, plus obj-c++ and go.
I plan to commit the patch to all release branches after a week in mainline.
Patch was committed to mainline, so automatic SPEC testers will pick
it for additional testing.
Uros.
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c (revision 203845)
+++ config/i386/i386.c (working copy)
@@ -7406,9 +7406,15 @@ ix86_function_value_regno_p (const unsigned int re
switch (regno)
{
case AX_REG:
+ case DX_REG:
return true;
+ case DI_REG:
+ case SI_REG:
+ return TARGET_64BIT && ix86_abi != MS_ABI;
- case FIRST_FLOAT_REG:
+ /* Complex values are returned in %st(0)/%st(1) pair. */
+ case ST0_REG:
+ case ST1_REG:
/* TODO: The function should depend on current function ABI but
builtins.c would need updating then. Therefore we use the
default ABI. */
@@ -7416,10 +7422,12 @@ ix86_function_value_regno_p (const unsigned int re
return false;
return TARGET_FLOAT_RETURNS_IN_80387;
- case FIRST_SSE_REG:
+ /* Complex values are returned in %xmm0/%xmm1 pair. */
+ case XMM0_REG:
+ case XMM1_REG:
return TARGET_SSE;
- case FIRST_MMX_REG:
+ case MM0_REG:
if (TARGET_MACHO || TARGET_64BIT)
return false;
return TARGET_MMX;