Commit 0f67fa83 by Wolfgang Gellerich Committed by Ulrich Weigand

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
parent b462d62d
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> 2007-07-09 Richard Guenther <rguenther@suse.de>
PR middle-end/32698 PR middle-end/32698
......
...@@ -240,6 +240,11 @@ static tree do_mpfr_remquo (tree, tree, tree); ...@@ -240,6 +240,11 @@ static tree do_mpfr_remquo (tree, tree, tree);
static tree do_mpfr_lgamma_r (tree, tree, tree); static tree do_mpfr_lgamma_r (tree, tree, tree);
#endif #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 /* Return true if NODE should be considered for inline expansion regardless
of the optimization level. This means whenever a function is invoked with of the optimization level. This means whenever a function is invoked with
its "internal" name, which normally contains the prefix "__builtin". */ its "internal" name, which normally contains the prefix "__builtin". */
...@@ -5584,12 +5589,15 @@ expand_builtin_adjust_trampoline (tree exp) ...@@ -5584,12 +5589,15 @@ expand_builtin_adjust_trampoline (tree exp)
return tramp; return tramp;
} }
/* Expand a call to the built-in signbit, signbitf, signbitl, signbitd32, /* Expand the call EXP to the built-in signbit, signbitf or signbitl
signbitd64, or signbitd128 function. function. The function first checks whether the back end provides
Return NULL_RTX if a normal call should be emitted rather than expanding an insn to implement signbit for the respective mode. If not, it
the function in-line. EXP is the expression that is a call to the builtin checks whether the floating point format of the value is such that
function; if convenient, the result should be placed in TARGET. */ 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 static rtx
expand_builtin_signbit (tree exp, rtx target) expand_builtin_signbit (tree exp, rtx target)
{ {
...@@ -5598,6 +5606,7 @@ expand_builtin_signbit (tree exp, rtx target) ...@@ -5598,6 +5606,7 @@ expand_builtin_signbit (tree exp, rtx target)
HOST_WIDE_INT hi, lo; HOST_WIDE_INT hi, lo;
tree arg; tree arg;
int word, bitpos; int word, bitpos;
enum insn_code signbit_insn_code;
rtx temp; rtx temp;
if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
...@@ -5608,6 +5617,21 @@ expand_builtin_signbit (tree exp, rtx target) ...@@ -5608,6 +5617,21 @@ expand_builtin_signbit (tree exp, rtx target)
rmode = TYPE_MODE (TREE_TYPE (exp)); rmode = TYPE_MODE (TREE_TYPE (exp));
fmt = REAL_MODE_FORMAT (fmode); 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 /* For floating point formats without a sign bit, implement signbit
as "ARG < 0.0". */ as "ARG < 0.0". */
bitpos = fmt->signbit_ro; bitpos = fmt->signbit_ro;
...@@ -5622,7 +5646,6 @@ expand_builtin_signbit (tree exp, rtx target) ...@@ -5622,7 +5646,6 @@ expand_builtin_signbit (tree exp, rtx target)
return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL); return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
} }
temp = expand_normal (arg);
if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD) if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
{ {
imode = int_mode_for_mode (fmode); imode = int_mode_for_mode (fmode);
......
...@@ -156,6 +156,13 @@ extern enum processor_flags s390_arch_flags; ...@@ -156,6 +156,13 @@ extern enum processor_flags s390_arch_flags;
#define S390_TDC_POSITIVE_SIGNALING_NAN (1 << 1) #define S390_TDC_POSITIVE_SIGNALING_NAN (1 << 1)
#define S390_TDC_NEGATIVE_SIGNALING_NAN (1 << 0) #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 \ #define S390_TDC_INFINITY (S390_TDC_POSITIVE_INFINITY \
| S390_TDC_NEGATIVE_INFINITY ) | S390_TDC_NEGATIVE_INFINITY )
......
...@@ -2308,6 +2308,18 @@ ...@@ -2308,6 +2308,18 @@
; Test data class. ; 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" (define_expand "isinf<mode>2"
[(set (reg:CCZ CC_REGNUM) [(set (reg:CCZ CC_REGNUM)
(unspec:CCZ [(match_operand:BFP 1 "register_operand" "f") (unspec:CCZ [(match_operand:BFP 1 "register_operand" "f")
......
...@@ -177,6 +177,7 @@ static const char * const optabs[] = ...@@ -177,6 +177,7 @@ static const char * const optabs[] =
"push_optab->handlers[$A].insn_code = CODE_FOR_$(push$a1$)", "push_optab->handlers[$A].insn_code = CODE_FOR_$(push$a1$)",
"reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)", "reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)",
"reload_out_optab[$A] = CODE_FOR_$(reload_out$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$)", "movmem_optab[$A] = CODE_FOR_$(movmem$a$)",
"cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)", "cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)",
"cmpstrn_optab[$A] = CODE_FOR_$(cmpstrn$a$)", "cmpstrn_optab[$A] = CODE_FOR_$(cmpstrn$a$)",
......
...@@ -5655,6 +5655,7 @@ init_optabs (void) ...@@ -5655,6 +5655,7 @@ init_optabs (void)
for (i = 0; i < NUM_MACHINE_MODES; i++) for (i = 0; i < NUM_MACHINE_MODES; i++)
{ {
movmem_optab[i] = CODE_FOR_nothing; movmem_optab[i] = CODE_FOR_nothing;
signbit_optab[i] = CODE_FOR_nothing;
cmpstr_optab[i] = CODE_FOR_nothing; cmpstr_optab[i] = CODE_FOR_nothing;
cmpstrn_optab[i] = CODE_FOR_nothing; cmpstrn_optab[i] = CODE_FOR_nothing;
cmpmem_optab[i] = CODE_FOR_nothing; cmpmem_optab[i] = CODE_FOR_nothing;
......
...@@ -553,6 +553,9 @@ extern enum insn_code vcondu_gen_code[NUM_MACHINE_MODES]; ...@@ -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. */ /* This array records the insn_code of insns to perform block moves. */
extern enum insn_code movmem_optab[NUM_MACHINE_MODES]; 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. */ /* This array records the insn_code of insns to perform block sets. */
extern enum insn_code setmem_optab[NUM_MACHINE_MODES]; extern enum insn_code setmem_optab[NUM_MACHINE_MODES];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment