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>
PR middle-end/32698
......
......@@ -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);
......
......@@ -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 )
......
......@@ -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")
......
......@@ -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$)",
......
......@@ -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;
......
......@@ -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];
......
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