aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorWolfgang Gellerich <gellerich@de.ibm.com>2007-07-09 20:12:51 +0000
committerUlrich Weigand <uweigand@gcc.gnu.org>2007-07-09 20:12:51 +0000
commit0f67fa83f2c26552227efc893ae27a910a40e140 (patch)
tree01bce16cd8187f0c885645cbd5419094990089a3 /gcc
parentb462d62dafaa25a4445191cd1685d2a7c343d1b6 (diff)
downloadgcc-0f67fa83f2c26552227efc893ae27a910a40e140.zip
gcc-0f67fa83f2c26552227efc893ae27a910a40e140.tar.gz
gcc-0f67fa83f2c26552227efc893ae27a910a40e140.tar.bz2
optabs.h: Added declaration for signbit_optab.
2007-07-09 Wolfgang Gellerich <gellerich@de.ibm.com> * optabs.h: Added declaration for signbit_optab. * optabs.c: (init_optabs): Added initialization for signbit_optab. * genoptinit.c (optabs): Added entry for signbit insns. * builtins.c (expand_builtin_signbit): Added code to use a signbit insn, if available. * config/s390/s390.h (S390_TDC_SIGNBIT_SET): New constant. * config/s390/s390.md (signbit<mode>2): New expander. From-SVN: r126495
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/builtins.c37
-rw-r--r--gcc/config/s390/s390.h7
-rw-r--r--gcc/config/s390/s390.md12
-rw-r--r--gcc/genopinit.c1
-rw-r--r--gcc/optabs.c1
-rw-r--r--gcc/optabs.h3
7 files changed, 64 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 802135b..51c3df3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2007-07-09 Wolfgang Gellerich <gellerich@de.ibm.com>
+
+ * optabs.h: Added declaration for signbit_optab.
+ * optabs.c: (init_optabs): Added initialization for signbit_optab.
+ * genoptinit.c (optabs): Added entry for signbit insns.
+ * builtins.c (expand_builtin_signbit): Added code to use a signbit insn,
+ if available.
+ * config/s390/s390.h (S390_TDC_SIGNBIT_SET): New constant.
+ * config/s390/s390.md (signbit<mode>2): New expander.
+
2007-07-09 Richard Guenther <rguenther@suse.de>
PR middle-end/32698
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 45dea02..c01d4d0 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -240,6 +240,11 @@ static tree do_mpfr_remquo (tree, tree, tree);
static tree do_mpfr_lgamma_r (tree, tree, tree);
#endif
+/* This array records the insn_code of insns to imlement the signbit
+ function. */
+enum insn_code signbit_optab[NUM_MACHINE_MODES];
+
+
/* Return true if NODE should be considered for inline expansion regardless
of the optimization level. This means whenever a function is invoked with
its "internal" name, which normally contains the prefix "__builtin". */
@@ -5584,12 +5589,15 @@ expand_builtin_adjust_trampoline (tree exp)
return tramp;
}
-/* Expand a call to the built-in signbit, signbitf, signbitl, signbitd32,
- signbitd64, or signbitd128 function.
- Return NULL_RTX if a normal call should be emitted rather than expanding
- the function in-line. EXP is the expression that is a call to the builtin
- function; if convenient, the result should be placed in TARGET. */
-
+/* Expand the call EXP to the built-in signbit, signbitf or signbitl
+ function. The function first checks whether the back end provides
+ an insn to implement signbit for the respective mode. If not, it
+ checks whether the floating point format of the value is such that
+ the sign bit can be extracted. If that is not the case, the
+ function returns NULL_RTX to indicate that a normal call should be
+ emitted rather than expanding the function in-line. EXP is the
+ expression that is a call to the builtin function; if convenient,
+ the result should be placed in TARGET. */
static rtx
expand_builtin_signbit (tree exp, rtx target)
{
@@ -5598,6 +5606,7 @@ expand_builtin_signbit (tree exp, rtx target)
HOST_WIDE_INT hi, lo;
tree arg;
int word, bitpos;
+ enum insn_code signbit_insn_code;
rtx temp;
if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
@@ -5608,6 +5617,21 @@ expand_builtin_signbit (tree exp, rtx target)
rmode = TYPE_MODE (TREE_TYPE (exp));
fmt = REAL_MODE_FORMAT (fmode);
+ arg = builtin_save_expr (arg);
+
+ /* Expand the argument yielding a RTX expression. */
+ temp = expand_normal (arg);
+
+ /* Check if the back end provides an insn that handles signbit for the
+ argument's mode. */
+ signbit_insn_code = signbit_optab [(int) fmode];
+ if (signbit_insn_code != CODE_FOR_nothing)
+ {
+ target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
+ emit_unop_insn (signbit_insn_code, target, temp, UNKNOWN);
+ return target;
+ }
+
/* For floating point formats without a sign bit, implement signbit
as "ARG < 0.0". */
bitpos = fmt->signbit_ro;
@@ -5622,7 +5646,6 @@ expand_builtin_signbit (tree exp, rtx target)
return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
}
- temp = expand_normal (arg);
if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
{
imode = int_mode_for_mode (fmode);
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index f95dae2..8336a8f 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -156,6 +156,13 @@ extern enum processor_flags s390_arch_flags;
#define S390_TDC_POSITIVE_SIGNALING_NAN (1 << 1)
#define S390_TDC_NEGATIVE_SIGNALING_NAN (1 << 0)
+#define S390_TDC_SIGNBIT_SET (S390_TDC_NEGATIVE_ZERO \
+ | S390_TDC_NEGATIVE_NORMALIZED_NUMBER \
+ | S390_TDC_NEGATIVE_DENORMALIZED_NUMBER\
+ | S390_TDC_NEGATIVE_INFINITY \
+ | S390_TDC_NEGATIVE_QUIET_NAN \
+ | S390_TDC_NEGATIVE_SIGNALING_NAN )
+
#define S390_TDC_INFINITY (S390_TDC_POSITIVE_INFINITY \
| S390_TDC_NEGATIVE_INFINITY )
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 3fac610..eb05553 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -2308,6 +2308,18 @@
; Test data class.
;
+(define_expand "signbit<mode>2"
+ [(set (reg:CCZ CC_REGNUM)
+ (unspec:CCZ [(match_operand:BFP 1 "register_operand" "f")
+ (match_dup 2)]
+ UNSPEC_TDC_INSN))
+ (set (match_operand:SI 0 "register_operand" "=d")
+ (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))]
+ "TARGET_HARD_FLOAT"
+{
+ operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
+})
+
(define_expand "isinf<mode>2"
[(set (reg:CCZ CC_REGNUM)
(unspec:CCZ [(match_operand:BFP 1 "register_operand" "f")
diff --git a/gcc/genopinit.c b/gcc/genopinit.c
index 0838058..3ed772e 100644
--- a/gcc/genopinit.c
+++ b/gcc/genopinit.c
@@ -177,6 +177,7 @@ static const char * const optabs[] =
"push_optab->handlers[$A].insn_code = CODE_FOR_$(push$a1$)",
"reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)",
"reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)",
+ "signbit_optab[$A] = CODE_FOR_$(signbit$F$a2$)",
"movmem_optab[$A] = CODE_FOR_$(movmem$a$)",
"cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)",
"cmpstrn_optab[$A] = CODE_FOR_$(cmpstrn$a$)",
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 9cd5507..1af4388 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -5655,6 +5655,7 @@ init_optabs (void)
for (i = 0; i < NUM_MACHINE_MODES; i++)
{
movmem_optab[i] = CODE_FOR_nothing;
+ signbit_optab[i] = CODE_FOR_nothing;
cmpstr_optab[i] = CODE_FOR_nothing;
cmpstrn_optab[i] = CODE_FOR_nothing;
cmpmem_optab[i] = CODE_FOR_nothing;
diff --git a/gcc/optabs.h b/gcc/optabs.h
index c1d57f6..aed7a54 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -553,6 +553,9 @@ extern enum insn_code vcondu_gen_code[NUM_MACHINE_MODES];
/* This array records the insn_code of insns to perform block moves. */
extern enum insn_code movmem_optab[NUM_MACHINE_MODES];
+/* This array records the insn_code of insns to implement the signbit function. */
+extern enum insn_code signbit_optab[NUM_MACHINE_MODES];
+
/* This array records the insn_code of insns to perform block sets. */
extern enum insn_code setmem_optab[NUM_MACHINE_MODES];