mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-11 00:15:48 +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>
|
2005-01-30 Kazu Hirata <kazu@cs.umass.edu>
|
||||||
|
|
||||||
* optabs.c, doc/c-tree.texi, doc/install.texi, doc/md.texi,
|
* 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 rtx ix86_build_signbit_mask (enum machine_mode, bool, bool);
|
||||||
extern void ix86_expand_fp_absneg_operator (enum rtx_code, enum machine_mode,
|
extern void ix86_expand_fp_absneg_operator (enum rtx_code, enum machine_mode,
|
||||||
rtx[]);
|
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_unary_operator_ok (enum rtx_code, enum machine_mode, rtx[]);
|
||||||
extern int ix86_match_ccmode (rtx, enum machine_mode);
|
extern int ix86_match_ccmode (rtx, enum machine_mode);
|
||||||
extern rtx ix86_expand_compare (enum rtx_code, rtx *, rtx *);
|
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);
|
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
|
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;
|
enum machine_mode mode, vmode;
|
||||||
rtx dest, scratch, op0, op1, mask, nmask, x;
|
rtx dest, scratch, op0, op1, mask, nmask, x;
|
||||||
@ -8128,8 +8210,8 @@ ix86_split_copysign (rtx operands[])
|
|||||||
dest = operands[0];
|
dest = operands[0];
|
||||||
scratch = operands[1];
|
scratch = operands[1];
|
||||||
op0 = operands[2];
|
op0 = operands[2];
|
||||||
nmask = operands[3];
|
op1 = operands[3];
|
||||||
op1 = operands[4];
|
nmask = operands[4];
|
||||||
mask = operands[5];
|
mask = operands[5];
|
||||||
|
|
||||||
mode = GET_MODE (dest);
|
mode = GET_MODE (dest);
|
||||||
|
@ -9452,34 +9452,56 @@
|
|||||||
"#")
|
"#")
|
||||||
|
|
||||||
(define_expand "copysignsf3"
|
(define_expand "copysignsf3"
|
||||||
[(parallel [(set (match_operand:SF 0 "register_operand" "")
|
[(match_operand:SF 0 "register_operand" "")
|
||||||
(unspec:SF [(match_operand:SF 1 "register_operand" "")
|
(match_operand:SF 1 "nonmemory_operand" "")
|
||||||
(match_dup 4)
|
(match_operand:SF 2 "register_operand" "")]
|
||||||
(match_operand:SF 2 "register_operand" "")
|
|
||||||
(match_dup 5)]
|
|
||||||
UNSPEC_COPYSIGN))
|
|
||||||
(clobber (match_scratch:V4SF 3 ""))])]
|
|
||||||
"TARGET_SSE_MATH"
|
"TARGET_SSE_MATH"
|
||||||
{
|
{
|
||||||
operands[4] = ix86_build_signbit_mask (SFmode, 0, 1);
|
ix86_expand_copysign (operands);
|
||||||
operands[5] = ix86_build_signbit_mask (SFmode, 0, 0);
|
DONE;
|
||||||
})
|
})
|
||||||
|
|
||||||
(define_insn_and_split "*copysignsf3"
|
(define_insn_and_split "copysignsf3_const"
|
||||||
[(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
|
[(set (match_operand:SF 0 "register_operand" "=x")
|
||||||
(unspec:SF
|
(unspec:SF
|
||||||
[(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
|
[(match_operand:V4SF 1 "vector_move_operand" "xmC")
|
||||||
(match_operand:V4SF 3 "nonimmediate_operand" " X,xm,xm, 0,0")
|
(match_operand:SF 2 "register_operand" "0")
|
||||||
(match_operand:SF 4 "register_operand" " 1, 1, x, 1,x")
|
(match_operand:V4SF 3 "nonimmediate_operand" "xm")]
|
||||||
(match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
|
UNSPEC_COPYSIGN))]
|
||||||
UNSPEC_COPYSIGN))
|
|
||||||
(clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
|
|
||||||
"TARGET_SSE_MATH"
|
"TARGET_SSE_MATH"
|
||||||
"#"
|
"#"
|
||||||
"&& reload_completed"
|
"&& reload_completed"
|
||||||
[(const_int 0)]
|
[(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;
|
DONE;
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -9526,34 +9548,56 @@
|
|||||||
"#")
|
"#")
|
||||||
|
|
||||||
(define_expand "copysigndf3"
|
(define_expand "copysigndf3"
|
||||||
[(parallel [(set (match_operand:DF 0 "register_operand" "")
|
[(match_operand:DF 0 "register_operand" "")
|
||||||
(unspec:DF [(match_operand:DF 1 "register_operand" "")
|
(match_operand:DF 1 "nonmemory_operand" "")
|
||||||
(match_dup 4)
|
(match_operand:DF 2 "register_operand" "")]
|
||||||
(match_operand:DF 2 "register_operand" "")
|
|
||||||
(match_dup 5)]
|
|
||||||
UNSPEC_COPYSIGN))
|
|
||||||
(clobber (match_scratch:V2DF 3 ""))])]
|
|
||||||
"TARGET_SSE2 && TARGET_SSE_MATH"
|
"TARGET_SSE2 && TARGET_SSE_MATH"
|
||||||
{
|
{
|
||||||
operands[4] = ix86_build_signbit_mask (DFmode, 0, 1);
|
ix86_expand_copysign (operands);
|
||||||
operands[5] = ix86_build_signbit_mask (DFmode, 0, 0);
|
DONE;
|
||||||
})
|
})
|
||||||
|
|
||||||
(define_insn_and_split "*copysigndf3"
|
(define_insn_and_split "copysigndf3_const"
|
||||||
[(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
|
[(set (match_operand:DF 0 "register_operand" "=x")
|
||||||
(unspec:DF
|
(unspec:DF
|
||||||
[(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
|
[(match_operand:V2DF 1 "vector_move_operand" "xmC")
|
||||||
(match_operand:V2DF 3 "nonimmediate_operand" " X,xm,xm, 0,0")
|
(match_operand:DF 2 "register_operand" "0")
|
||||||
(match_operand:DF 4 "register_operand" " 1, 1, x, 1,x")
|
(match_operand:V2DF 3 "nonimmediate_operand" "xm")]
|
||||||
(match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
|
UNSPEC_COPYSIGN))]
|
||||||
UNSPEC_COPYSIGN))
|
|
||||||
(clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
|
|
||||||
"TARGET_SSE2 && TARGET_SSE_MATH"
|
"TARGET_SSE2 && TARGET_SSE_MATH"
|
||||||
"#"
|
"#"
|
||||||
"&& reload_completed"
|
"&& reload_completed"
|
||||||
[(const_int 0)]
|
[(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;
|
DONE;
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user