diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3e9a2d0d1e1f..e77633305dfc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2006-09-20 Richard Sandiford + + * config/mips/mips.c (CODE_FOR_mips_abs_ps): Delete. + * config/mips/mips.md (UNSPEC_ABS_PS): New constant. + (UNSPEC_RSQRT1, UNSPEC_RSQRT2, UNSPEC_RECIP1, UNSPEC_RECIP2) + (UNSPEC_SINGLE_CC, UNSPEC_SCC): Bump values by 1. + (*nmadd, *nmadd_fastmath): Require !HONOR_NANS. + (*nmsub, *nmsub_fastmath): Likewise. + (abs2, neg2): Likewise. + * config/mips/mips-ps-3d.md (mips_abs_ps): New define_expand. + (*mips_abs_ps): New define_insn. + 2006-09-20 Josh Conner PR middle-end/25505 diff --git a/gcc/config/mips/mips-ps-3d.md b/gcc/config/mips/mips-ps-3d.md index 78c8b5c64210..c817f4df69ec 100644 --- a/gcc/config/mips/mips-ps-3d.md +++ b/gcc/config/mips/mips-ps-3d.md @@ -276,6 +276,31 @@ [(set_attr "type" "fmul") (set_attr "mode" "SF")]) +; abs.ps +(define_expand "mips_abs_ps" + [(set (match_operand:V2SF 0 "register_operand") + (unspec:V2SF [(match_operand:V2SF 1 "register_operand")] + UNSPEC_ABS_PS))] + "TARGET_PAIRED_SINGLE_FLOAT" +{ + /* If we can ignore NaNs, this operation is equivalent to the + rtl ABS code. */ + if (!HONOR_NANS (V2SFmode)) + { + emit_insn (gen_absv2sf2 (operands[0], operands[1])); + DONE; + } +}) + +(define_insn "*mips_abs_ps" + [(set (match_operand:V2SF 0 "register_operand" "=f") + (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")] + UNSPEC_ABS_PS))] + "TARGET_PAIRED_SINGLE_FLOAT" + "abs.ps\t%0,%1" + [(set_attr "type" "fabs") + (set_attr "mode" "SF")]) + ;---------------------------------------------------------------------------- ; Floating Point Comparisons for Scalars ;---------------------------------------------------------------------------- diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 91e90e0918ed..7110a2d76442 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -10084,9 +10084,6 @@ struct builtin_description CMP_4S_BUILTINS (c, COND), \ CMP_4S_BUILTINS (cabs, COND) -/* __builtin_mips_abs_ps() maps to the standard absM2 pattern. */ -#define CODE_FOR_mips_abs_ps CODE_FOR_absv2sf2 - static const struct builtin_description mips_bdesc[] = { DIRECT_BUILTIN (pll_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE_FLOAT), diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index a9b9add0dcff..969d22fa00f5 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -67,13 +67,14 @@ (UNSPEC_CVT_PW_PS 205) (UNSPEC_CVT_PS_PW 206) (UNSPEC_MULR_PS 207) + (UNSPEC_ABS_PS 208) - (UNSPEC_RSQRT1 208) - (UNSPEC_RSQRT2 209) - (UNSPEC_RECIP1 210) - (UNSPEC_RECIP2 211) - (UNSPEC_SINGLE_CC 212) - (UNSPEC_SCC 213) + (UNSPEC_RSQRT1 209) + (UNSPEC_RSQRT2 210) + (UNSPEC_RECIP1 211) + (UNSPEC_RECIP2 212) + (UNSPEC_SINGLE_CC 213) + (UNSPEC_SCC 214) ;; MIPS DSP ASE Revision 0.98 3/24/2005 (UNSPEC_ADDQ 300) @@ -1765,7 +1766,8 @@ (match_operand:ANYF 2 "register_operand" "f")) (match_operand:ANYF 3 "register_operand" "f"))))] "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (mode)" + && HONOR_SIGNED_ZEROS (mode) + && !HONOR_NANS (mode)" "nmadd.\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "")]) @@ -1777,7 +1779,8 @@ (match_operand:ANYF 2 "register_operand" "f")) (match_operand:ANYF 3 "register_operand" "f")))] "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD - && !HONOR_SIGNED_ZEROS (mode)" + && !HONOR_SIGNED_ZEROS (mode) + && !HONOR_NANS (mode)" "nmadd.\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "")]) @@ -1789,7 +1792,8 @@ (match_operand:ANYF 3 "register_operand" "f")) (match_operand:ANYF 1 "register_operand" "f"))))] "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (mode)" + && HONOR_SIGNED_ZEROS (mode) + && !HONOR_NANS (mode)" "nmsub.\t%0,%1,%2,%3" [(set_attr "type" "fmadd") (set_attr "mode" "")]) @@ -1801,7 +1805,8 @@ (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") (match_operand:ANYF 3 "register_operand" "f"))))] "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD - && !HONOR_SIGNED_ZEROS (mode)" + && !HONOR_SIGNED_ZEROS (mode) + && !HONOR_NANS (mode)" "nmsub.\t%0,%1,%2,%3" [(set_attr "type" "fmadd") (set_attr "mode" "")]) @@ -1972,10 +1977,14 @@ ;; Do not use the integer abs macro instruction, since that signals an ;; exception on -2147483648 (sigh). +;; abs.fmt is an arithmetic instruction and treats all NaN inputs as +;; invalid; it does not clear their sign bits. We therefore can't use +;; abs.fmt if the signs of NaNs matter. + (define_insn "abs2" [(set (match_operand:ANYF 0 "register_operand" "=f") (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))] - "" + "!HONOR_NANS (mode)" "abs.\t%0,%1" [(set_attr "type" "fabs") (set_attr "mode" "")]) @@ -2024,10 +2033,14 @@ [(set_attr "type" "arith") (set_attr "mode" "DI")]) +;; neg.fmt is an arithmetic instruction and treats all NaN inputs as +;; invalid; it does not flip their sign bit. We therefore can't use +;; neg.fmt if the signs of NaNs matter. + (define_insn "neg2" [(set (match_operand:ANYF 0 "register_operand" "=f") (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))] - "" + "!HONOR_NANS (mode)" "neg.\t%0,%1" [(set_attr "type" "fneg") (set_attr "mode" "")]) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5c0a4f1b7e13..0b539e6acb39 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2006-09-20 Richard Sandiford + + * gcc.target/mips/mips-ps-type.c: Add -ffinite-math-only. + * gcc.target/mips/nmadd-2.c: Likewise. + * gcc.target/mips/mips-ps-6.c: New test. + * gcc.target/mips/neg-abs-1.c: Likewise. + * gcc.target/mips/neg-abs-2.c: Likewise. + * gcc.target/mips/nmadd-3.c: New test. + 2006-09-20 Jakub Jelinek PR middle-end/28046 diff --git a/gcc/testsuite/gcc.target/mips/mips-ps-6.c b/gcc/testsuite/gcc.target/mips/mips-ps-6.c new file mode 100644 index 000000000000..75de478dc8cf --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/mips-ps-6.c @@ -0,0 +1,136 @@ +/* mips-ps-2.c with an extra -ffinite-math-only option. This option + changes the way that abs.ps is handled. */ +/* { dg-do run { target mipsisa64*-*-* } } */ +/* { dg-mips-options "-mips64 -O2 -mpaired-single -mhard-float -mgp64 -ffinite-math-only" } */ + +/* Test MIPS paired-single builtin functions */ +#include +#include + +typedef float v2sf __attribute__ ((vector_size(8))); + +int main () +{ + int little_endian; + v2sf a, b, c, d; + float e,f; + int i; + + union { long long ll; int i[2]; } endianness_test; + endianness_test.ll = 1; + little_endian = endianness_test.i[0]; + + /* pll.ps */ + a = (v2sf) {1, 2}; + b = (v2sf) {3, 4}; + c = __builtin_mips_pll_ps (a, b); + if (little_endian) // little endian + d = (v2sf) {3, 1}; + else // big endian + d = (v2sf) {2, 4}; + + if (!__builtin_mips_upper_c_eq_ps (c, d) || + !__builtin_mips_lower_c_eq_ps (c, d)) + abort (); + + /* pul.ps */ + a = (v2sf) {1, 2}; + b = (v2sf) {3, 4}; + c = __builtin_mips_pul_ps (a, b); + if (little_endian) // little endian + d = (v2sf) {3, 2}; + else // big endian + d = (v2sf) {1, 4}; + if (!__builtin_mips_upper_c_eq_ps (c, d) || + !__builtin_mips_lower_c_eq_ps (c, d)) + abort (); + + /* plu.ps */ + a = (v2sf) {1, 2}; + b = (v2sf) {3, 4}; + c = __builtin_mips_plu_ps (a, b); + if (little_endian) // little endian + d = (v2sf) {4, 1}; + else // big endian + d = (v2sf) {2, 3}; + if (!__builtin_mips_upper_c_eq_ps (c, d) || + !__builtin_mips_lower_c_eq_ps (c, d)) + abort (); + + /* puu.ps */ + a = (v2sf) {1, 2}; + b = (v2sf) {3, 4}; + c = __builtin_mips_puu_ps (a, b); + if (little_endian) // little endian + d = (v2sf) {4, 2}; + else // big endian + d = (v2sf) {1, 3}; + if (!__builtin_mips_upper_c_eq_ps (c, d) || + !__builtin_mips_lower_c_eq_ps (c, d)) + abort (); + + /* cvt.ps.s */ + e = 3.4; + f = 4.5; + a = __builtin_mips_cvt_ps_s (e, f); + if (little_endian) // little endian + b = (v2sf) {4.5, 3.4}; + else // big endian + b = (v2sf) {3.4, 4.5}; + if (!__builtin_mips_upper_c_eq_ps (a, b) || + !__builtin_mips_lower_c_eq_ps (a, b)) + abort (); + + /* cvt.s.pl */ + a = (v2sf) {35.1, 120.2}; + e = __builtin_mips_cvt_s_pl (a); + if (little_endian) // little endian + f = 35.1; + else // big endian + f = 120.2; + if (e != f) + abort (); + + /* cvt.s.pu */ + a = (v2sf) {30.0, 100.0}; + e = __builtin_mips_cvt_s_pu (a); + if (little_endian) // little endian + f = 100.0; + else // big endian + f = 30.0; + if (e != f) + abort (); + + /* abs.ps */ + a = (v2sf) {-3.4, -5.8}; + b = __builtin_mips_abs_ps (a); + c = (v2sf) {3.4, 5.8}; + if (!__builtin_mips_upper_c_eq_ps (b, c) || + !__builtin_mips_lower_c_eq_ps (b, c)) + abort (); + + /* alnv.ps with rs = 4*/ + a = (v2sf) {1, 2}; + b = (v2sf) {3, 4}; + i = 4; + c = __builtin_mips_alnv_ps (a, b, i); + d = (v2sf) {2, 3}; + + if (!__builtin_mips_upper_c_eq_ps (c, d) || + !__builtin_mips_lower_c_eq_ps (c, d)) + abort (); + + /* alnv.ps with rs = 0 */ + a = (v2sf) {5, 6}; + b = (v2sf) {7, 8}; + i = 0; + c = __builtin_mips_alnv_ps (a, b, i); + d = (v2sf) {5, 6}; + + if (!__builtin_mips_upper_c_eq_ps (c, d) || + !__builtin_mips_lower_c_eq_ps (c, d)) + abort (); + + printf ("Test Passes\n"); + exit (0); +} diff --git a/gcc/testsuite/gcc.target/mips/mips-ps-type.c b/gcc/testsuite/gcc.target/mips/mips-ps-type.c index cd5566fcbfa3..aca3625ab78a 100644 --- a/gcc/testsuite/gcc.target/mips/mips-ps-type.c +++ b/gcc/testsuite/gcc.target/mips/mips-ps-type.c @@ -1,6 +1,7 @@ -/* Test v2sf calculations */ +/* Test v2sf calculations. The nmadd and nmsub patterns need + -ffinite-math-only. */ /* { dg-do compile } */ -/* { dg-mips-options "-mips64 -O2 -mpaired-single -mhard-float -mgp64" } */ +/* { dg-mips-options "-mips64 -O2 -mpaired-single -mhard-float -mgp64 -ffinite-math-only" } */ /* { dg-final { scan-assembler "cvt.ps.s" } } */ /* { dg-final { scan-assembler "mov.ps" } } */ /* { dg-final { scan-assembler "ldc1" } } */ diff --git a/gcc/testsuite/gcc.target/mips/neg-abs-1.c b/gcc/testsuite/gcc.target/mips/neg-abs-1.c new file mode 100644 index 000000000000..038b8983cb74 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/neg-abs-1.c @@ -0,0 +1,13 @@ +/* Make sure that we use abs.fmt and neg.fmt when the signs of NaNs don't + matter. */ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -mhard-float -ffinite-math-only" } */ +/* { dg-final { scan-assembler "neg.s" } } */ +/* { dg-final { scan-assembler "neg.d" } } */ +/* { dg-final { scan-assembler "abs.s" } } */ +/* { dg-final { scan-assembler "abs.d" } } */ + +float f1 (float f) { return -f; } +float f2 (float f) { return __builtin_fabsf (f); } +double d1 (double d) { return -d; } +double d2 (double d) { return __builtin_fabs (d); } diff --git a/gcc/testsuite/gcc.target/mips/neg-abs-2.c b/gcc/testsuite/gcc.target/mips/neg-abs-2.c new file mode 100644 index 000000000000..5ef08da6f349 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/neg-abs-2.c @@ -0,0 +1,13 @@ +/* Make sure that we avoid abs.fmt and neg.fmt when the signs of NaNs + matter. */ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -mhard-float -fno-finite-math-only" } */ +/* { dg-final { scan-assembler-not "neg.s" } } */ +/* { dg-final { scan-assembler-not "neg.d" } } */ +/* { dg-final { scan-assembler-not "abs.s" } } */ +/* { dg-final { scan-assembler-not "abs.d" } } */ + +float f1 (float f) { return -f; } +float f2 (float f) { return __builtin_fabsf (f); } +double d1 (double d) { return -d; } +double d2 (double d) { return __builtin_fabs (d); } diff --git a/gcc/testsuite/gcc.target/mips/nmadd-2.c b/gcc/testsuite/gcc.target/mips/nmadd-2.c index 522407a5119b..df84a76aad59 100644 --- a/gcc/testsuite/gcc.target/mips/nmadd-2.c +++ b/gcc/testsuite/gcc.target/mips/nmadd-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-mips-options "-O2 -fno-fast-math -mips4 -mhard-float" } */ +/* { dg-mips-options "-O2 -fno-fast-math -ffinite-math-only -mips4 -mhard-float" } */ /* { dg-final { scan-assembler "nmadd.s" } } */ /* { dg-final { scan-assembler "nmadd.d" } } */ /* { dg-final { scan-assembler "nmsub.s" } } */ diff --git a/gcc/testsuite/gcc.target/mips/nmadd-3.c b/gcc/testsuite/gcc.target/mips/nmadd-3.c new file mode 100644 index 000000000000..381fdef08fb4 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/nmadd-3.c @@ -0,0 +1,32 @@ +/* The same code as nmadd-2.c, but compiled with -fno-finite-math-only. + We can't use nmadd and nmsub in that case. */ +/* { dg-do compile } */ +/* { dg-mips-options "-O2 -fno-fast-math -fno-finite-math-only -mips4 -mhard-float" } */ +/* { dg-final { scan-assembler-not "nmadd.s" } } */ +/* { dg-final { scan-assembler-not "nmadd.d" } } */ +/* { dg-final { scan-assembler-not "nmsub.s" } } */ +/* { dg-final { scan-assembler-not "nmsub.d" } } */ + +float +sub1 (float f, float g, float h) +{ + return -((f * g) + h); +} + +double +sub2 (double f, double g, double h) +{ + return -((f * g) + h); +} + +float +sub3 (float f, float g, float h) +{ + return -((f * g) - h); +} + +double +sub4 (double f, double g, double h) +{ + return -((f * g) - h); +}