mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-10 20:55:23 +08:00
re PR target/19700 (ICE in final_scan_insn with O1 -g -march=athlon-xp -mfpmath=sse)
PR target/19700 * config/i386/i386.c (ix86_expand_copysign): New. (ix86_split_copysign_const): New. (ix86_split_copysign_var): Rename from ix86_split_copysign, rearrange op1/nmask operands. * config/i386/i386-protos.h: Update. * config/i386/i386.md (copysignsf3): Use ix86_expand_copysign. (copysigndf3): Likewise. (copysignsf3_const, copysigndf3_const): New. (copysignsf3_var): Rename from copysignsf3, split out splitter and fix split predicate for X constraint. (copysigndf3_var): Similarly. From-SVN: r94442
This commit is contained in:
parent
c5c367ac3d
commit
b99d6d2b80
@ -1,3 +1,18 @@
|
||||
2005-01-30 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR target/19700
|
||||
* config/i386/i386.c (ix86_expand_copysign): New.
|
||||
(ix86_split_copysign_const): New.
|
||||
(ix86_split_copysign_var): Rename from ix86_split_copysign,
|
||||
rearrange op1/nmask operands.
|
||||
* config/i386/i386-protos.h: Update.
|
||||
* config/i386/i386.md (copysignsf3): Use ix86_expand_copysign.
|
||||
(copysigndf3): Likewise.
|
||||
(copysignsf3_const, copysigndf3_const): New.
|
||||
(copysignsf3_var): Rename from copysignsf3, split out splitter
|
||||
and fix split predicate for X constraint.
|
||||
(copysigndf3_var): Similarly.
|
||||
|
||||
2005-01-30 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
* optabs.c, doc/c-tree.texi, doc/install.texi, doc/md.texi,
|
||||
|
@ -139,7 +139,9 @@ extern void ix86_expand_unary_operator (enum rtx_code, enum machine_mode,
|
||||
extern rtx ix86_build_signbit_mask (enum machine_mode, bool, bool);
|
||||
extern void ix86_expand_fp_absneg_operator (enum rtx_code, enum machine_mode,
|
||||
rtx[]);
|
||||
extern void ix86_split_copysign (rtx []);
|
||||
extern void ix86_expand_copysign (rtx []);
|
||||
extern void ix86_split_copysign_const (rtx []);
|
||||
extern void ix86_split_copysign_var (rtx []);
|
||||
extern int ix86_unary_operator_ok (enum rtx_code, enum machine_mode, rtx[]);
|
||||
extern int ix86_match_ccmode (rtx, enum machine_mode);
|
||||
extern rtx ix86_expand_compare (enum rtx_code, rtx *, rtx *);
|
||||
|
@ -8117,10 +8117,92 @@ ix86_expand_fp_absneg_operator (enum rtx_code code, enum machine_mode mode,
|
||||
emit_move_insn (operands[0], dst);
|
||||
}
|
||||
|
||||
/* Deconstruct a copysign operation into bit masks. */
|
||||
/* Expand a copysign operation. Special case operand 0 being a constant. */
|
||||
|
||||
void
|
||||
ix86_split_copysign (rtx operands[])
|
||||
ix86_expand_copysign (rtx operands[])
|
||||
{
|
||||
enum machine_mode mode, vmode;
|
||||
rtx dest, op0, op1, mask, nmask;
|
||||
|
||||
dest = operands[0];
|
||||
op0 = operands[1];
|
||||
op1 = operands[2];
|
||||
|
||||
mode = GET_MODE (dest);
|
||||
vmode = mode == SFmode ? V4SFmode : V2DFmode;
|
||||
|
||||
if (GET_CODE (op0) == CONST_DOUBLE)
|
||||
{
|
||||
rtvec v;
|
||||
|
||||
if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
|
||||
op0 = simplify_unary_operation (ABS, mode, op0, mode);
|
||||
|
||||
if (op0 == CONST0_RTX (mode))
|
||||
op0 = CONST0_RTX (vmode);
|
||||
else
|
||||
{
|
||||
if (mode == SFmode)
|
||||
v = gen_rtvec (4, op0, CONST0_RTX (SFmode),
|
||||
CONST0_RTX (SFmode), CONST0_RTX (SFmode));
|
||||
else
|
||||
v = gen_rtvec (2, op0, CONST0_RTX (DFmode));
|
||||
op0 = force_reg (vmode, gen_rtx_CONST_VECTOR (vmode, v));
|
||||
}
|
||||
|
||||
mask = ix86_build_signbit_mask (mode, 0, 0);
|
||||
|
||||
if (mode == SFmode)
|
||||
emit_insn (gen_copysignsf3_const (dest, op0, op1, mask));
|
||||
else
|
||||
emit_insn (gen_copysigndf3_const (dest, op0, op1, mask));
|
||||
}
|
||||
else
|
||||
{
|
||||
nmask = ix86_build_signbit_mask (mode, 0, 1);
|
||||
mask = ix86_build_signbit_mask (mode, 0, 0);
|
||||
|
||||
if (mode == SFmode)
|
||||
emit_insn (gen_copysignsf3_var (dest, NULL, op0, op1, nmask, mask));
|
||||
else
|
||||
emit_insn (gen_copysigndf3_var (dest, NULL, op0, op1, nmask, mask));
|
||||
}
|
||||
}
|
||||
|
||||
/* Deconstruct a copysign operation into bit masks. Operand 0 is known to
|
||||
be a constant, and so has already been expanded into a vector constant. */
|
||||
|
||||
void
|
||||
ix86_split_copysign_const (rtx operands[])
|
||||
{
|
||||
enum machine_mode mode, vmode;
|
||||
rtx dest, op0, op1, mask, x;
|
||||
|
||||
dest = operands[0];
|
||||
op0 = operands[1];
|
||||
op1 = operands[2];
|
||||
mask = operands[3];
|
||||
|
||||
mode = GET_MODE (dest);
|
||||
vmode = GET_MODE (mask);
|
||||
|
||||
dest = simplify_gen_subreg (vmode, dest, mode, 0);
|
||||
x = gen_rtx_AND (vmode, dest, mask);
|
||||
emit_insn (gen_rtx_SET (VOIDmode, dest, x));
|
||||
|
||||
if (op0 != CONST0_RTX (vmode))
|
||||
{
|
||||
x = gen_rtx_IOR (vmode, dest, op0);
|
||||
emit_insn (gen_rtx_SET (VOIDmode, dest, x));
|
||||
}
|
||||
}
|
||||
|
||||
/* Deconstruct a copysign operation into bit masks. Operand 0 is variable,
|
||||
so we have to do two masks. */
|
||||
|
||||
void
|
||||
ix86_split_copysign_var (rtx operands[])
|
||||
{
|
||||
enum machine_mode mode, vmode;
|
||||
rtx dest, scratch, op0, op1, mask, nmask, x;
|
||||
@ -8128,8 +8210,8 @@ ix86_split_copysign (rtx operands[])
|
||||
dest = operands[0];
|
||||
scratch = operands[1];
|
||||
op0 = operands[2];
|
||||
nmask = operands[3];
|
||||
op1 = operands[4];
|
||||
op1 = operands[3];
|
||||
nmask = operands[4];
|
||||
mask = operands[5];
|
||||
|
||||
mode = GET_MODE (dest);
|
||||
|
@ -9452,34 +9452,56 @@
|
||||
"#")
|
||||
|
||||
(define_expand "copysignsf3"
|
||||
[(parallel [(set (match_operand:SF 0 "register_operand" "")
|
||||
(unspec:SF [(match_operand:SF 1 "register_operand" "")
|
||||
(match_dup 4)
|
||||
(match_operand:SF 2 "register_operand" "")
|
||||
(match_dup 5)]
|
||||
UNSPEC_COPYSIGN))
|
||||
(clobber (match_scratch:V4SF 3 ""))])]
|
||||
[(match_operand:SF 0 "register_operand" "")
|
||||
(match_operand:SF 1 "nonmemory_operand" "")
|
||||
(match_operand:SF 2 "register_operand" "")]
|
||||
"TARGET_SSE_MATH"
|
||||
{
|
||||
operands[4] = ix86_build_signbit_mask (SFmode, 0, 1);
|
||||
operands[5] = ix86_build_signbit_mask (SFmode, 0, 0);
|
||||
ix86_expand_copysign (operands);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn_and_split "*copysignsf3"
|
||||
[(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
|
||||
(define_insn_and_split "copysignsf3_const"
|
||||
[(set (match_operand:SF 0 "register_operand" "=x")
|
||||
(unspec:SF
|
||||
[(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
|
||||
(match_operand:V4SF 3 "nonimmediate_operand" " X,xm,xm, 0,0")
|
||||
(match_operand:SF 4 "register_operand" " 1, 1, x, 1,x")
|
||||
(match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
|
||||
UNSPEC_COPYSIGN))
|
||||
(clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
|
||||
[(match_operand:V4SF 1 "vector_move_operand" "xmC")
|
||||
(match_operand:SF 2 "register_operand" "0")
|
||||
(match_operand:V4SF 3 "nonimmediate_operand" "xm")]
|
||||
UNSPEC_COPYSIGN))]
|
||||
"TARGET_SSE_MATH"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(const_int 0)]
|
||||
{
|
||||
ix86_split_copysign (operands);
|
||||
ix86_split_copysign_const (operands);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "copysignsf3_var"
|
||||
[(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
|
||||
(unspec:SF
|
||||
[(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
|
||||
(match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
|
||||
(match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
|
||||
(match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
|
||||
UNSPEC_COPYSIGN))
|
||||
(clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
|
||||
"TARGET_SSE_MATH"
|
||||
"#")
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:SF 0 "register_operand" "")
|
||||
(unspec:SF
|
||||
[(match_operand:SF 2 "register_operand" "")
|
||||
(match_operand:SF 3 "register_operand" "")
|
||||
(match_operand:V4SF 4 "" "")
|
||||
(match_operand:V4SF 5 "" "")]
|
||||
UNSPEC_COPYSIGN))
|
||||
(clobber (match_scratch:V4SF 1 ""))]
|
||||
"TARGET_SSE_MATH && reload_completed"
|
||||
[(const_int 0)]
|
||||
{
|
||||
ix86_split_copysign_var (operands);
|
||||
DONE;
|
||||
})
|
||||
|
||||
@ -9526,34 +9548,56 @@
|
||||
"#")
|
||||
|
||||
(define_expand "copysigndf3"
|
||||
[(parallel [(set (match_operand:DF 0 "register_operand" "")
|
||||
(unspec:DF [(match_operand:DF 1 "register_operand" "")
|
||||
(match_dup 4)
|
||||
(match_operand:DF 2 "register_operand" "")
|
||||
(match_dup 5)]
|
||||
UNSPEC_COPYSIGN))
|
||||
(clobber (match_scratch:V2DF 3 ""))])]
|
||||
[(match_operand:DF 0 "register_operand" "")
|
||||
(match_operand:DF 1 "nonmemory_operand" "")
|
||||
(match_operand:DF 2 "register_operand" "")]
|
||||
"TARGET_SSE2 && TARGET_SSE_MATH"
|
||||
{
|
||||
operands[4] = ix86_build_signbit_mask (DFmode, 0, 1);
|
||||
operands[5] = ix86_build_signbit_mask (DFmode, 0, 0);
|
||||
ix86_expand_copysign (operands);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn_and_split "*copysigndf3"
|
||||
[(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
|
||||
(define_insn_and_split "copysigndf3_const"
|
||||
[(set (match_operand:DF 0 "register_operand" "=x")
|
||||
(unspec:DF
|
||||
[(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
|
||||
(match_operand:V2DF 3 "nonimmediate_operand" " X,xm,xm, 0,0")
|
||||
(match_operand:DF 4 "register_operand" " 1, 1, x, 1,x")
|
||||
(match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
|
||||
UNSPEC_COPYSIGN))
|
||||
(clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
|
||||
[(match_operand:V2DF 1 "vector_move_operand" "xmC")
|
||||
(match_operand:DF 2 "register_operand" "0")
|
||||
(match_operand:V2DF 3 "nonimmediate_operand" "xm")]
|
||||
UNSPEC_COPYSIGN))]
|
||||
"TARGET_SSE2 && TARGET_SSE_MATH"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(const_int 0)]
|
||||
{
|
||||
ix86_split_copysign (operands);
|
||||
ix86_split_copysign_const (operands);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "copysigndf3_var"
|
||||
[(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
|
||||
(unspec:DF
|
||||
[(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
|
||||
(match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
|
||||
(match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
|
||||
(match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
|
||||
UNSPEC_COPYSIGN))
|
||||
(clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
|
||||
"TARGET_SSE2 && TARGET_SSE_MATH"
|
||||
"#")
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:DF 0 "register_operand" "")
|
||||
(unspec:DF
|
||||
[(match_operand:DF 2 "register_operand" "")
|
||||
(match_operand:DF 3 "register_operand" "")
|
||||
(match_operand:V2DF 4 "" "")
|
||||
(match_operand:V2DF 5 "" "")]
|
||||
UNSPEC_COPYSIGN))
|
||||
(clobber (match_scratch:V2DF 1 ""))]
|
||||
"TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
|
||||
[(const_int 0)]
|
||||
{
|
||||
ix86_split_copysign_var (operands);
|
||||
DONE;
|
||||
})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user