Hello! x32 follows x86_64 ABI, so no MMX regs are saved/restored in __builtin_apply_args/__builtin_return, even with -mmmx. The patch also includes some cleanups in this area.
2011-09-06 Uros Bizjak <ubiz...@gmail.com> * config/i386/i386.c (ix86_function_value_regno_p): Use AX_REG. (function_value_32): Do not check TARGET_MMX, TARGET_SSE or TARGET_AVX. testsuite/ChangeLog: 2011-09-06 Uros Bizjak <ubiz...@gmail.com> * gcc.target/i386/builtin-apply-mmx.c: Require ia32 effective target. Tested on x86_64-pc-linux-gnu {,-m32}, committed to mainline SVN. Uros.
Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 178608) +++ config/i386/i386.c (working copy) @@ -7015,7 +7015,7 @@ ix86_function_value_regno_p (const unsigned int re { switch (regno) { - case 0: + case AX_REG: return true; case FIRST_FLOAT_REG: @@ -7053,18 +7053,18 @@ function_value_32 (enum machine_mode orig_mode, en we normally prevent this case when mmx is not available. However some ABIs may require the result to be returned like DImode. */ if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 8) - regno = TARGET_MMX ? FIRST_MMX_REG : 0; + regno = FIRST_MMX_REG; /* 16-byte vector modes in %xmm0. See ix86_return_in_memory for where we prevent this case when sse is not available. However some ABIs may require the result to be returned like integer TImode. */ else if (mode == TImode || (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 16)) - regno = TARGET_SSE ? FIRST_SSE_REG : 0; + regno = FIRST_SSE_REG; /* 32-byte vector modes in %ymm0. */ else if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 32) - regno = TARGET_AVX ? FIRST_SSE_REG : 0; + regno = FIRST_SSE_REG; /* Floating point return values in %st(0) (unless -mno-fp-ret-in-387). */ else if (X87_FLOAT_MODE_P (mode) && TARGET_FLOAT_RETURNS_IN_80387) @@ -7098,6 +7098,8 @@ function_value_64 (enum machine_mode orig_mode, en /* Handle libcalls, which don't provide a type node. */ if (valtype == NULL) { + unsigned int regno; + switch (mode) { case SFmode: @@ -7108,15 +7110,19 @@ function_value_64 (enum machine_mode orig_mode, en case SDmode: case DDmode: case TDmode: - return gen_rtx_REG (mode, FIRST_SSE_REG); + regno = FIRST_SSE_REG; + break; case XFmode: case XCmode: - return gen_rtx_REG (mode, FIRST_FLOAT_REG); + regno = FIRST_FLOAT_REG; + break; case TCmode: return NULL; default: - return gen_rtx_REG (mode, AX_REG); + regno = AX_REG; } + + return gen_rtx_REG (mode, regno); } else if (POINTER_TYPE_P (valtype)) { Index: testsuite/gcc.target/i386/builtin-apply-mmx.c =================================================================== --- testsuite/gcc.target/i386/builtin-apply-mmx.c (revision 178608) +++ testsuite/gcc.target/i386/builtin-apply-mmx.c (working copy) @@ -11,7 +11,7 @@ /* { dg-do run { xfail { ! *-*-darwin* } } } */ /* { dg-options "-O2 -mmmx" } */ -/* { dg-require-effective-target ilp32 } */ +/* { dg-require-effective-target ia32 } */ #include "mmx-check.h"