diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 94f768f6a20..58763d81195 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2006-07-06 Roger Sayle + + PR target/27968 + * configure.ac (HAVE_AS_IX86_FFREEP): On x86 targets check whether + the configured assembler supports the x87's ffreep mnemonic. + * configure: Regenerate. + * config.in: Regenerate. + + * config/i386/i386.c (output_387_ffreep): New function. + (output_fp_compare): Use output_387_ffreep to emit ffreep insns. + (output_387_reg_move): Likewise. + 2006-07-06 Paul Eggert Port to hosts whose 'sort' and 'tail' implementations @@ -10,7 +22,8 @@ 2006-07-06 Zdenek Dvorak - * tree-ssa-loop-niter.c (scev_probably_wraps_p): Fix typo in argument name. + * tree-ssa-loop-niter.c (scev_probably_wraps_p): Fix typo in + argument name. 2006-07-06 David Edelsohn diff --git a/gcc/config.in b/gcc/config.in index d5f854ef959..47ba85080c2 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -203,6 +203,12 @@ #endif +/* Define if your assembler supports the ffreep mnemonic. */ +#ifndef USED_FOR_TARGET +#undef HAVE_AS_IX86_FFREEP +#endif + + /* Define if your assembler supports the lituse_jsrdirect relocation. */ #ifndef USED_FOR_TARGET #undef HAVE_AS_JSRDIRECT_RELOCS diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 958bd613aa8..fe0d516c05e 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -8641,6 +8641,34 @@ output_fix_trunc (rtx insn, rtx *operands, int fisttp) return ""; } +/* Output code for x87 ffreep insn. The OPNO argument, which may only + have the values zero or one, indicates the ffreep insn's operand + from the OPERANDS array. */ + +static const char * +output_387_ffreep (rtx *operands ATTRIBUTE_UNUSED, int opno) +{ + if (TARGET_USE_FFREEP) +#if HAVE_AS_IX86_FFREEP + return opno ? "ffreep\t%y1" : "ffreep\t%y0"; +#else + switch (REGNO (operands[opno])) + { + case FIRST_STACK_REG + 0: return ".word\t0xc0df"; + case FIRST_STACK_REG + 1: return ".word\t0xc1df"; + case FIRST_STACK_REG + 2: return ".word\t0xc2df"; + case FIRST_STACK_REG + 3: return ".word\t0xc3df"; + case FIRST_STACK_REG + 4: return ".word\t0xc4df"; + case FIRST_STACK_REG + 5: return ".word\t0xc5df"; + case FIRST_STACK_REG + 6: return ".word\t0xc6df"; + case FIRST_STACK_REG + 7: return ".word\t0xc7df"; + } +#endif + + return opno ? "fstp\t%y1" : "fstp\t%y0"; +} + + /* Output code for INSN to compare OPERANDS. EFLAGS_P is 1 when fcomi should be used. UNORDERED_P is true when fucom should be used. */ @@ -8685,7 +8713,7 @@ output_fp_compare (rtx insn, rtx *operands, int eflags_p, int unordered_p) if (stack_top_dies) { output_asm_insn ("ftst\n\tfnstsw\t%0", operands); - return TARGET_USE_FFREEP ? "ffreep\t%y1" : "fstp\t%y1"; + return output_387_ffreep (operands, 1); } else return "ftst\n\tfnstsw\t%0"; @@ -8708,7 +8736,7 @@ output_fp_compare (rtx insn, rtx *operands, int eflags_p, int unordered_p) output_asm_insn ("fucomip\t{%y1, %0|%0, %y1}", operands); else output_asm_insn ("fcomip\t{%y1, %0|%0, %y1}", operands); - return TARGET_USE_FFREEP ? "ffreep\t%y0" : "fstp\t%y0"; + return output_387_ffreep (operands, 0); } else { @@ -18807,9 +18835,8 @@ output_387_reg_move (rtx insn, rtx *operands) if (REG_P (operands[1]) && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) { - if (REGNO (operands[0]) == FIRST_STACK_REG - && TARGET_USE_FFREEP) - return "ffreep\t%y0"; + if (REGNO (operands[0]) == FIRST_STACK_REG) + return output_387_ffreep (operands, 0); return "fstp\t%y0"; } if (STACK_TOP_P (operands[0])) diff --git a/gcc/configure b/gcc/configure index 4ec18630eb7..507b4c3ecbe 100755 --- a/gcc/configure +++ b/gcc/configure @@ -15046,6 +15046,39 @@ cat >>confdefs.h <<\_ACEOF #define HAVE_AS_IX86_CMOV_SUN_SYNTAX 1 _ACEOF +fi + + echo "$as_me:$LINENO: checking assembler for ffreep mnemonic" >&5 +echo $ECHO_N "checking assembler for ffreep mnemonic... $ECHO_C" >&6 +if test "${gcc_cv_as_ix86_ffreep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + gcc_cv_as_ix86_ffreep=no + if test x$gcc_cv_as != x; then + echo 'ffreep %st(1)' > conftest.s + if { ac_try='$gcc_cv_as -o conftest.o conftest.s >&5' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } + then + gcc_cv_as_ix86_ffreep=yes + else + echo "configure: failed program was" >&5 + cat conftest.s >&5 + fi + rm -f conftest.o conftest.s + fi +fi +echo "$as_me:$LINENO: result: $gcc_cv_as_ix86_ffreep" >&5 +echo "${ECHO_T}$gcc_cv_as_ix86_ffreep" >&6 +if test $gcc_cv_as_ix86_ffreep = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_AS_IX86_FFREEP 1 +_ACEOF + fi # This one is used unconditionally by i386.[ch]; it is to be defined diff --git a/gcc/configure.ac b/gcc/configure.ac index 7b3a5d10e18..5841da9bc87 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -1,7 +1,7 @@ # configure.ac for GCC # Process this file with autoconf to generate a configuration script. -# Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 # Free Software Foundation, Inc. #This file is part of GCC. @@ -2815,6 +2815,12 @@ foo: nop [AC_DEFINE(HAVE_AS_IX86_CMOV_SUN_SYNTAX, 1, [Define if your assembler supports the Sun syntax for cmov.])]) + gcc_GAS_CHECK_FEATURE([ffreep mnemonic], + gcc_cv_as_ix86_ffreep,,, + [ffreep %st(1)],, + [AC_DEFINE(HAVE_AS_IX86_FFREEP, 1, + [Define if your assembler supports the ffreep mnemonic.])]) + # This one is used unconditionally by i386.[ch]; it is to be defined # to 1 if the feature is present, 0 otherwise. gcc_GAS_CHECK_FEATURE([GOTOFF in data],