diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 27 | ||||
-rw-r--r-- | gcc/optabs.c | 2 | ||||
-rw-r--r-- | gcc/optabs.h | 1 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/ieee/copysign1.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/ieee/copysign2.c | 12 |
7 files changed, 67 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3ec28c7a24f..054b745832a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2005-02-01 Richard Henderson <rth@redhat.com> + + PR 19696 + * optabs.c (expand_copysign_absneg): Export. + * optabs.h (expand_copysign_absneg): Declare. + * config/rs6000/rs6000.md (copysigntf3): New. + 2005-02-01 Diego Novillo <dnovillo@redhat.com> PR tree-optimization/19633 diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 7ccdab8b5a8..c2dd678d767 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -8466,6 +8466,33 @@ operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word); operands[6] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word); }") + +(define_expand "copysigntf3" + [(match_operand:TF 0 "general_operand" "") + (match_operand:TF 1 "general_operand" "") + (match_operand:TF 2 "general_operand" "")] + "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" +{ + rtx target, op0, op1, temp; + bool op0_is_abs = false; + + target = operands[0]; + op0 = operands[1]; + op1 = operands[2]; + + if (GET_CODE (op0) == CONST_DOUBLE) + { + if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0))) + op0 = simplify_unary_operation (ABS, TFmode, op0, TFmode); + op0_is_abs = true; + } + + temp = expand_copysign_absneg (TFmode, op0, op1, target, 127, op0_is_abs); + if (temp != target) + emit_move_insn (target, temp); + DONE; +}) ;; Next come the multi-word integer load and store and the load and store ;; multiple insns. diff --git a/gcc/optabs.c b/gcc/optabs.c index dd3232b499c..889f9156dd1 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -2662,7 +2662,7 @@ expand_abs (enum machine_mode mode, rtx op0, rtx target, is that we have a split register file, and leaving op0 in fp registers, and not playing with subregs so much, will help the register allocator. */ -static rtx +rtx expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target, int bitpos, bool op0_is_abs) { diff --git a/gcc/optabs.h b/gcc/optabs.h index a378a963c72..613831a8249 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -455,6 +455,7 @@ extern rtx expand_abs (enum machine_mode, rtx, rtx, int, int); /* Expand the copysign operation. */ extern rtx expand_copysign (rtx, rtx, rtx); +extern rtx expand_copysign_absneg (enum machine_mode, rtx, rtx, rtx, int, bool); /* Generate an instruction with a given INSN_CODE with an output and an input. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a6ff8329a1f..ace5f5f5ce1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2005-02-01 Richard Henderson <rth@redhat.com> + + * gcc.c-torture/execute/ieee/copysign1.c: Special case sizeof + long double for ibm double-double format. + * gcc.c-torture/execute/ieee/copysign2.c: Likewise. + 2005-02-01 Diego Novillo <dnovillo@redhat.com> PR tree-optimization/19633 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/copysign1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/copysign1.c index 6f6a215ad48..fa4097a748d 100644 --- a/gcc/testsuite/gcc.c-torture/execute/ieee/copysign1.c +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/copysign1.c @@ -17,6 +17,19 @@ # endif #endif +/* Work around the fact that the sign of the second double in the IBM + double-double format is not strictly specified when it contains a zero. + For instance, -0.0L can be represented with either (-0.0, +0.0) or + (-0.0, -0.0). The former is what we'll get from the compiler when it + builds constants; the later is what we'll get from the negation operator + at runtime. */ +/* ??? This hack only works for big-endian, which is fortunately true for + all of AIX, Darwin, and Irix. */ +#if LDBL_MANT_DIG == 106 +# undef fpsizeofl +# define fpsizeofl sizeof(double) +#endif + #define TEST(TYPE, EXT) \ TYPE c##EXT (TYPE x, TYPE y) \ diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/copysign2.c b/gcc/testsuite/gcc.c-torture/execute/ieee/copysign2.c index a39d11574f2..fac7ab3a530 100644 --- a/gcc/testsuite/gcc.c-torture/execute/ieee/copysign2.c +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/copysign2.c @@ -17,6 +17,18 @@ # endif #endif +/* Work around the fact that the sign of the second double in the IBM + double-double format is not strictly specified when it contains a zero. + For instance, -0.0L can be represented with either (-0.0, +0.0) or + (-0.0, -0.0). The former is what we'll get from the compiler when it + builds constants; the later is what we'll get from the negation operator + at runtime. */ +/* ??? This hack only works for big-endian, which is fortunately true for + all of AIX, Darwin, and Irix. */ +#if LDBL_MANT_DIG == 106 +# undef fpsizeofl +# define fpsizeofl sizeof(double) +#endif #define TEST(TYPE, EXT) \ |