re PR target/78597 (test case gcc.dg/torture/fp-int-convert-float128-ieee.c (and others) fail starting with r242780)
2017-01-31 Michael Meissner <meissner@linux.vnet.ibm.com> PR target/78597 PR target/79038 * config/rs6000/rs6000-protos.h (convert_float128_to_int): Delete, no longer used. (convert_int_to_float128): Likewise. * config/rs6000/rs6000.c (convert_float128_to_int): Likewise. (convert_int_to_float128): Likewise. * config/rs6000/rs6000.md (UNSPEC_IEEE128_MOVE): Likewise. (UNSPEC_IEEE128_CONVERT): Likewise. (floatsi<mode>2, FLOAT128 iterator): Bypass calling rs6000_expand_float128_convert if we have IEEE 128-bit hardware. Use local variables for IBM extended format. (fix_trunc<mode>si2, FLOAT128 iterator): Likewise. (fix_trunc<mode>si2_fprs): Likewise. (fixuns_trunc<IEEE128:mode><SDI:mode>2): Likewise. (floatuns<IEEE128:mode>2, IEEE128 iterator): Likewise. (fix<uns>_<mode>si2_hw): Rework the IEEE 128-bt hardware support to know that we can now have integers of all sizes in vector registers. (fix<uns>_<mode>di2_hw): Likewise. (float<uns>_<mode>si2_hw): Likewise. (fix_<mode>si2_hw): Likewise. (fixuns_<mode>si2_hw): Likewise. (float<uns>_<mode>di2_hw): Likewise. (float_<mode>di2_hw): Likewise. (float_<mode>si2_hw): Likewise. (floatuns_<mode>di2_hw): Likewise. (floatuns_<mode>si2_hw): Likewise. (xscvqp<su>wz_<mode>): Delete, no longer used. (xscvqp<su>dz_<mode>): Likewise. (xscv<su>dqp_<mode>): Likewise. (ieee128_mfvsrd_64bit): Likewise. (ieee128_mfvsrd_32bit): Likewise. (ieee128_mfvsrwz): Likewise. (ieee128_mtvsrw): Likewise. (ieee128_mtvsrd_64bit): Likewise. (ieee128_mtvsrd_32bit): Likewise. From-SVN: r245059
This commit is contained in:
parent
a0a348b167
commit
c6eb38f3ea
4 changed files with 187 additions and 264 deletions
|
@ -1,3 +1,43 @@
|
|||
2017-01-31 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
|
||||
PR target/78597
|
||||
PR target/79038
|
||||
* config/rs6000/rs6000-protos.h (convert_float128_to_int): Delete,
|
||||
no longer used.
|
||||
(convert_int_to_float128): Likewise.
|
||||
* config/rs6000/rs6000.c (convert_float128_to_int): Likewise.
|
||||
(convert_int_to_float128): Likewise.
|
||||
* config/rs6000/rs6000.md (UNSPEC_IEEE128_MOVE): Likewise.
|
||||
(UNSPEC_IEEE128_CONVERT): Likewise.
|
||||
(floatsi<mode>2, FLOAT128 iterator): Bypass calling
|
||||
rs6000_expand_float128_convert if we have IEEE 128-bit hardware.
|
||||
Use local variables for IBM extended format.
|
||||
(fix_trunc<mode>si2, FLOAT128 iterator): Likewise.
|
||||
(fix_trunc<mode>si2_fprs): Likewise.
|
||||
(fixuns_trunc<IEEE128:mode><SDI:mode>2): Likewise.
|
||||
(floatuns<IEEE128:mode>2, IEEE128 iterator): Likewise.
|
||||
(fix<uns>_<mode>si2_hw): Rework the IEEE 128-bt hardware support
|
||||
to know that we can now have integers of all sizes in vector
|
||||
registers.
|
||||
(fix<uns>_<mode>di2_hw): Likewise.
|
||||
(float<uns>_<mode>si2_hw): Likewise.
|
||||
(fix_<mode>si2_hw): Likewise.
|
||||
(fixuns_<mode>si2_hw): Likewise.
|
||||
(float<uns>_<mode>di2_hw): Likewise.
|
||||
(float_<mode>di2_hw): Likewise.
|
||||
(float_<mode>si2_hw): Likewise.
|
||||
(floatuns_<mode>di2_hw): Likewise.
|
||||
(floatuns_<mode>si2_hw): Likewise.
|
||||
(xscvqp<su>wz_<mode>): Delete, no longer used.
|
||||
(xscvqp<su>dz_<mode>): Likewise.
|
||||
(xscv<su>dqp_<mode>): Likewise.
|
||||
(ieee128_mfvsrd_64bit): Likewise.
|
||||
(ieee128_mfvsrd_32bit): Likewise.
|
||||
(ieee128_mfvsrwz): Likewise.
|
||||
(ieee128_mtvsrw): Likewise.
|
||||
(ieee128_mtvsrd_64bit): Likewise.
|
||||
(ieee128_mtvsrd_32bit): Likewise.
|
||||
|
||||
2017-01-31 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR ipa/79285
|
||||
|
|
|
@ -57,8 +57,6 @@ extern const char *rs6000_output_move_128bit (rtx *);
|
|||
extern bool rs6000_move_128bit_ok_p (rtx []);
|
||||
extern bool rs6000_split_128bit_ok_p (rtx []);
|
||||
extern void rs6000_expand_float128_convert (rtx, rtx, bool);
|
||||
extern void convert_float128_to_int (rtx *, enum rtx_code);
|
||||
extern void convert_int_to_float128 (rtx *, enum rtx_code);
|
||||
extern void rs6000_expand_vector_init (rtx, rtx);
|
||||
extern void paired_expand_vector_init (rtx, rtx);
|
||||
extern void rs6000_expand_vector_set (rtx, rtx, int);
|
||||
|
|
|
@ -24686,92 +24686,6 @@ rs6000_expand_float128_convert (rtx dest, rtx src, bool unsigned_p)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Split a conversion from __float128 to an integer type into separate insns.
|
||||
OPERANDS points to the destination, source, and V2DI temporary
|
||||
register. CODE is either FIX or UNSIGNED_FIX. */
|
||||
|
||||
void
|
||||
convert_float128_to_int (rtx *operands, enum rtx_code code)
|
||||
{
|
||||
rtx dest = operands[0];
|
||||
rtx src = operands[1];
|
||||
rtx tmp = operands[2];
|
||||
rtx cvt;
|
||||
rtvec cvt_vec;
|
||||
rtx cvt_unspec;
|
||||
rtvec move_vec;
|
||||
rtx move_unspec;
|
||||
|
||||
if (GET_CODE (tmp) == SCRATCH)
|
||||
tmp = gen_reg_rtx (V2DImode);
|
||||
|
||||
if (MEM_P (dest))
|
||||
dest = rs6000_address_for_fpconvert (dest);
|
||||
|
||||
/* Generate the actual convert insn of the form:
|
||||
(set (tmp) (unspec:V2DI [(fix:SI (reg:KF))] UNSPEC_IEEE128_CONVERT)). */
|
||||
cvt = gen_rtx_fmt_e (code, GET_MODE (dest), src);
|
||||
cvt_vec = gen_rtvec (1, cvt);
|
||||
cvt_unspec = gen_rtx_UNSPEC (V2DImode, cvt_vec, UNSPEC_IEEE128_CONVERT);
|
||||
emit_insn (gen_rtx_SET (tmp, cvt_unspec));
|
||||
|
||||
/* Generate the move insn of the form:
|
||||
(set (dest:SI) (unspec:SI [(tmp:V2DI))] UNSPEC_IEEE128_MOVE)). */
|
||||
move_vec = gen_rtvec (1, tmp);
|
||||
move_unspec = gen_rtx_UNSPEC (GET_MODE (dest), move_vec, UNSPEC_IEEE128_MOVE);
|
||||
emit_insn (gen_rtx_SET (dest, move_unspec));
|
||||
}
|
||||
|
||||
/* Split a conversion from an integer type to __float128 into separate insns.
|
||||
OPERANDS points to the destination, source, and V2DI temporary
|
||||
register. CODE is either FLOAT or UNSIGNED_FLOAT. */
|
||||
|
||||
void
|
||||
convert_int_to_float128 (rtx *operands, enum rtx_code code)
|
||||
{
|
||||
rtx dest = operands[0];
|
||||
rtx src = operands[1];
|
||||
rtx tmp = operands[2];
|
||||
rtx cvt;
|
||||
rtvec cvt_vec;
|
||||
rtx cvt_unspec;
|
||||
rtvec move_vec;
|
||||
rtx move_unspec;
|
||||
rtx unsigned_flag;
|
||||
|
||||
if (GET_CODE (tmp) == SCRATCH)
|
||||
tmp = gen_reg_rtx (V2DImode);
|
||||
|
||||
if (MEM_P (src))
|
||||
src = rs6000_address_for_fpconvert (src);
|
||||
|
||||
/* Generate the move of the integer into the Altivec register of the form:
|
||||
(set (tmp:V2DI) (unspec:V2DI [(src:SI)
|
||||
(const_int 0)] UNSPEC_IEEE128_MOVE)).
|
||||
|
||||
or:
|
||||
(set (tmp:V2DI) (unspec:V2DI [(src:DI)] UNSPEC_IEEE128_MOVE)). */
|
||||
|
||||
if (GET_MODE (src) == SImode)
|
||||
{
|
||||
unsigned_flag = (code == UNSIGNED_FLOAT) ? const1_rtx : const0_rtx;
|
||||
move_vec = gen_rtvec (2, src, unsigned_flag);
|
||||
}
|
||||
else
|
||||
move_vec = gen_rtvec (1, src);
|
||||
|
||||
move_unspec = gen_rtx_UNSPEC (V2DImode, move_vec, UNSPEC_IEEE128_MOVE);
|
||||
emit_insn (gen_rtx_SET (tmp, move_unspec));
|
||||
|
||||
/* Generate the actual convert insn of the form:
|
||||
(set (dest:KF) (float:KF (unspec:DI [(tmp:V2DI)]
|
||||
UNSPEC_IEEE128_CONVERT))). */
|
||||
cvt_vec = gen_rtvec (1, tmp);
|
||||
cvt_unspec = gen_rtx_UNSPEC (DImode, cvt_vec, UNSPEC_IEEE128_CONVERT);
|
||||
cvt = gen_rtx_fmt_e (code, GET_MODE (dest), cvt_unspec);
|
||||
emit_insn (gen_rtx_SET (dest, cvt));
|
||||
}
|
||||
|
||||
|
||||
/* Emit the RTL for an sISEL pattern. */
|
||||
|
||||
|
|
|
@ -146,8 +146,6 @@
|
|||
UNSPEC_FUSION_P9
|
||||
UNSPEC_FUSION_ADDIS
|
||||
UNSPEC_ROUND_TO_ODD
|
||||
UNSPEC_IEEE128_MOVE
|
||||
UNSPEC_IEEE128_CONVERT
|
||||
UNSPEC_SIGNBIT
|
||||
UNSPEC_SF_FROM_SI
|
||||
UNSPEC_SI_FROM_SF
|
||||
|
@ -7690,26 +7688,35 @@
|
|||
"")
|
||||
|
||||
(define_expand "floatsi<mode>2"
|
||||
[(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
|
||||
(float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
|
||||
[(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
|
||||
(float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
|
||||
(clobber (match_scratch:DI 2))])]
|
||||
"TARGET_HARD_FLOAT
|
||||
&& (TARGET_FPRS || TARGET_E500_DOUBLE)
|
||||
&& TARGET_LONG_DOUBLE_128"
|
||||
{
|
||||
if (FLOAT128_IEEE_P (<MODE>mode))
|
||||
rs6000_expand_float128_convert (operands[0], operands[1], false);
|
||||
rtx op0 = operands[0];
|
||||
rtx op1 = operands[1];
|
||||
|
||||
if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
|
||||
;
|
||||
else if (FLOAT128_IEEE_P (<MODE>mode))
|
||||
{
|
||||
rs6000_expand_float128_convert (op0, op1, false);
|
||||
DONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx tmp = gen_reg_rtx (DFmode);
|
||||
expand_float (tmp, operands[1], false);
|
||||
expand_float (tmp, op1, false);
|
||||
if (<MODE>mode == TFmode)
|
||||
emit_insn (gen_extenddftf2 (operands[0], tmp));
|
||||
emit_insn (gen_extenddftf2 (op0, tmp));
|
||||
else if (<MODE>mode == IFmode)
|
||||
emit_insn (gen_extenddfif2 (operands[0], tmp));
|
||||
emit_insn (gen_extenddfif2 (op0, tmp));
|
||||
else
|
||||
gcc_unreachable ();
|
||||
DONE;
|
||||
}
|
||||
DONE;
|
||||
})
|
||||
|
||||
; fadd, but rounding towards zero.
|
||||
|
@ -7731,17 +7738,25 @@
|
|||
"TARGET_HARD_FLOAT
|
||||
&& (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
|
||||
{
|
||||
if (FLOAT128_IEEE_P (<MODE>mode))
|
||||
rs6000_expand_float128_convert (operands[0], operands[1], false);
|
||||
else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
|
||||
emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
|
||||
else if (<MODE>mode == TFmode)
|
||||
emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
|
||||
else if (<MODE>mode == IFmode)
|
||||
emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
|
||||
rtx op0 = operands[0];
|
||||
rtx op1 = operands[1];
|
||||
|
||||
if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
|
||||
;
|
||||
else
|
||||
gcc_unreachable ();
|
||||
DONE;
|
||||
{
|
||||
if (FLOAT128_IEEE_P (<MODE>mode))
|
||||
rs6000_expand_float128_convert (op0, op1, false);
|
||||
else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
|
||||
emit_insn (gen_spe_fix_trunctfsi2 (op0, op1));
|
||||
else if (<MODE>mode == TFmode)
|
||||
emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
|
||||
else if (<MODE>mode == IFmode)
|
||||
emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
|
||||
else
|
||||
gcc_unreachable ();
|
||||
DONE;
|
||||
}
|
||||
})
|
||||
|
||||
(define_expand "fix_trunc<mode>si2_fprs"
|
||||
|
@ -7789,8 +7804,11 @@
|
|||
(fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
|
||||
"TARGET_FLOAT128_TYPE"
|
||||
{
|
||||
rs6000_expand_float128_convert (operands[0], operands[1], false);
|
||||
DONE;
|
||||
if (!TARGET_FLOAT128_HW)
|
||||
{
|
||||
rs6000_expand_float128_convert (operands[0], operands[1], false);
|
||||
DONE;
|
||||
}
|
||||
})
|
||||
|
||||
(define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
|
||||
|
@ -7807,16 +7825,37 @@
|
|||
(float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
|
||||
"TARGET_FLOAT128_TYPE"
|
||||
{
|
||||
rs6000_expand_float128_convert (operands[0], operands[1], false);
|
||||
DONE;
|
||||
if (!TARGET_FLOAT128_HW)
|
||||
{
|
||||
rs6000_expand_float128_convert (operands[0], operands[1], false);
|
||||
DONE;
|
||||
}
|
||||
})
|
||||
|
||||
(define_expand "floatuns<SDI:mode><IEEE128:mode>2"
|
||||
(define_expand "floatunsdi<IEEE128:mode>2"
|
||||
[(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
|
||||
(unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
|
||||
(unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
|
||||
"TARGET_FLOAT128_TYPE"
|
||||
{
|
||||
rs6000_expand_float128_convert (operands[0], operands[1], true);
|
||||
if (!TARGET_FLOAT128_HW)
|
||||
{
|
||||
rs6000_expand_float128_convert (operands[0], operands[1], true);
|
||||
DONE;
|
||||
}
|
||||
})
|
||||
|
||||
(define_expand "floatuns<IEEE128:mode>2"
|
||||
[(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
|
||||
(unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))]
|
||||
"TARGET_FLOAT128_TYPE"
|
||||
{
|
||||
rtx op0 = operands[0];
|
||||
rtx op1 = operands[1];
|
||||
|
||||
if (TARGET_FLOAT128_HW)
|
||||
emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
|
||||
else
|
||||
rs6000_expand_float128_convert (op0, op1, true);
|
||||
DONE;
|
||||
})
|
||||
|
||||
|
@ -14350,170 +14389,102 @@
|
|||
[(set_attr "type" "vecfloat")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
;; At present SImode is not allowed in VSX registers at all, and DImode is only
|
||||
;; allowed in the traditional floating point registers. Use V2DImode so that
|
||||
;; we can get a value in an Altivec register.
|
||||
|
||||
(define_insn_and_split "fix<uns>_<mode>si2_hw"
|
||||
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
|
||||
(any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
|
||||
(clobber (match_scratch:V2DI 2 "=v,v"))]
|
||||
;; Conversion between IEEE 128-bit and integer types
|
||||
(define_insn "fix_<mode>di2_hw"
|
||||
[(set (match_operand:DI 0 "altivec_register_operand" "=v")
|
||||
(fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
|
||||
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
|
||||
"#"
|
||||
"&& 1"
|
||||
[(pc)]
|
||||
{
|
||||
convert_float128_to_int (operands, <CODE>);
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "type" "mftgpr,fpstore")])
|
||||
|
||||
(define_insn_and_split "fix<uns>_<mode>di2_hw"
|
||||
[(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
|
||||
(any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
|
||||
(clobber (match_scratch:V2DI 2 "=v,v,v"))]
|
||||
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
|
||||
"#"
|
||||
"&& 1"
|
||||
[(pc)]
|
||||
{
|
||||
convert_float128_to_int (operands, <CODE>);
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "type" "mftgpr,vecsimple,fpstore")])
|
||||
|
||||
(define_insn_and_split "float<uns>_<mode>si2_hw"
|
||||
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
|
||||
(any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
|
||||
(clobber (match_scratch:V2DI 2 "=v,v"))]
|
||||
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
|
||||
"#"
|
||||
"&& 1"
|
||||
[(pc)]
|
||||
{
|
||||
convert_int_to_float128 (operands, <CODE>);
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "type" "vecfloat")])
|
||||
|
||||
(define_insn_and_split "float<uns>_<mode>di2_hw"
|
||||
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
|
||||
(any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
|
||||
(clobber (match_scratch:V2DI 2 "=v,v,v"))]
|
||||
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
|
||||
"#"
|
||||
"&& 1"
|
||||
[(pc)]
|
||||
{
|
||||
convert_int_to_float128 (operands, <CODE>);
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "type" "vecfloat")])
|
||||
|
||||
;; Integer conversion instructions, using V2DImode to get an Altivec register
|
||||
(define_insn "*xscvqp<su>wz_<mode>"
|
||||
[(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
|
||||
(unspec:V2DI
|
||||
[(any_fix:SI
|
||||
(match_operand:IEEE128 1 "altivec_register_operand" "v"))]
|
||||
UNSPEC_IEEE128_CONVERT))]
|
||||
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
|
||||
"xscvqp<su>wz %0,%1"
|
||||
"xscvqpsdz %0,%1"
|
||||
[(set_attr "type" "vecfloat")
|
||||
(set_attr "size" "128")])
|
||||
|
||||
(define_insn "*xscvqp<su>dz_<mode>"
|
||||
[(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
|
||||
(unspec:V2DI
|
||||
[(any_fix:DI
|
||||
(match_operand:IEEE128 1 "altivec_register_operand" "v"))]
|
||||
UNSPEC_IEEE128_CONVERT))]
|
||||
(define_insn "fixuns_<mode>di2_hw"
|
||||
[(set (match_operand:DI 0 "altivec_register_operand" "=v")
|
||||
(unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
|
||||
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
|
||||
"xscvqp<su>dz %0,%1"
|
||||
"xscvqpudz %0,%1"
|
||||
[(set_attr "type" "vecfloat")
|
||||
(set_attr "size" "128")])
|
||||
|
||||
(define_insn "*xscv<su>dqp_<mode>"
|
||||
(define_insn "fix_<mode>si2_hw"
|
||||
[(set (match_operand:SI 0 "altivec_register_operand" "=v")
|
||||
(fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
|
||||
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
|
||||
"xscvqpswz %0,%1"
|
||||
[(set_attr "type" "vecfloat")
|
||||
(set_attr "size" "128")])
|
||||
|
||||
(define_insn "fixuns_<mode>si2_hw"
|
||||
[(set (match_operand:SI 0 "altivec_register_operand" "=v")
|
||||
(unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
|
||||
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
|
||||
"xscvqpuwz %0,%1"
|
||||
[(set_attr "type" "vecfloat")
|
||||
(set_attr "size" "128")])
|
||||
|
||||
;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit
|
||||
;; floating point value to 32-bit integer to GPR in order to save it.
|
||||
(define_insn_and_split "*fix<uns>_<mode>_mem"
|
||||
[(set (match_operand:SI 0 "memory_operand" "=Z")
|
||||
(any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))
|
||||
(clobber (match_scratch:SI 2 "=v"))]
|
||||
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(set (match_dup 2)
|
||||
(any_fix:SI (match_dup 1)))
|
||||
(set (match_dup 0)
|
||||
(match_dup 2))])
|
||||
|
||||
(define_insn "float_<mode>di2_hw"
|
||||
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
|
||||
(any_float:IEEE128
|
||||
(unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
|
||||
UNSPEC_IEEE128_CONVERT)))]
|
||||
(float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
|
||||
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
|
||||
"xscv<su>dqp %0,%1"
|
||||
"xscvsdqp %0,%1"
|
||||
[(set_attr "type" "vecfloat")
|
||||
(set_attr "size" "128")])
|
||||
|
||||
(define_insn "*ieee128_mfvsrd_64bit"
|
||||
[(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
|
||||
(unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
|
||||
UNSPEC_IEEE128_MOVE))]
|
||||
"TARGET_FLOAT128_HW && TARGET_POWERPC64"
|
||||
"@
|
||||
mfvsrd %0,%x1
|
||||
stxsdx %x1,%y0
|
||||
xxlor %x0,%x1,%x1"
|
||||
[(set_attr "type" "mftgpr,fpstore,veclogical")])
|
||||
(define_insn_and_split "float_<mode>si2_hw"
|
||||
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
|
||||
(float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
|
||||
(clobber (match_scratch:DI 2 "=v"))]
|
||||
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
|
||||
"#"
|
||||
"&& 1"
|
||||
[(set (match_dup 2)
|
||||
(sign_extend:DI (match_dup 1)))
|
||||
(set (match_dup 0)
|
||||
(float:IEEE128 (match_dup 2)))]
|
||||
{
|
||||
if (GET_CODE (operands[2]) == SCRATCH)
|
||||
operands[2] = gen_reg_rtx (DImode);
|
||||
})
|
||||
|
||||
(define_insn "floatuns_<mode>di2_hw"
|
||||
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
|
||||
(unsigned_float:IEEE128
|
||||
(match_operand:DI 1 "altivec_register_operand" "v")))]
|
||||
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
|
||||
"xscvudqp %0,%1"
|
||||
[(set_attr "type" "vecfloat")
|
||||
(set_attr "size" "128")])
|
||||
|
||||
(define_insn "*ieee128_mfvsrd_32bit"
|
||||
[(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
|
||||
(unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
|
||||
UNSPEC_IEEE128_MOVE))]
|
||||
"TARGET_FLOAT128_HW && !TARGET_POWERPC64"
|
||||
"@
|
||||
stxsdx %x1,%y0
|
||||
xxlor %x0,%x1,%x1"
|
||||
[(set_attr "type" "fpstore,veclogical")])
|
||||
|
||||
(define_insn "*ieee128_mfvsrwz"
|
||||
[(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
|
||||
(unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
|
||||
UNSPEC_IEEE128_MOVE))]
|
||||
"TARGET_FLOAT128_HW"
|
||||
"@
|
||||
mfvsrwz %0,%x1
|
||||
stxsiwx %x1,%y0"
|
||||
[(set_attr "type" "mftgpr,fpstore")])
|
||||
|
||||
;; 0 says do sign-extension, 1 says zero-extension
|
||||
(define_insn "*ieee128_mtvsrw"
|
||||
[(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
|
||||
(unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
|
||||
(match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
|
||||
UNSPEC_IEEE128_MOVE))]
|
||||
"TARGET_FLOAT128_HW"
|
||||
"@
|
||||
mtvsrwa %x0,%1
|
||||
lxsiwax %x0,%y1
|
||||
mtvsrwz %x0,%1
|
||||
lxsiwzx %x0,%y1"
|
||||
[(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
|
||||
|
||||
|
||||
(define_insn "*ieee128_mtvsrd_64bit"
|
||||
[(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
|
||||
(unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
|
||||
UNSPEC_IEEE128_MOVE))]
|
||||
"TARGET_FLOAT128_HW && TARGET_POWERPC64"
|
||||
"@
|
||||
mtvsrd %x0,%1
|
||||
lxsdx %x0,%y1
|
||||
xxlor %x0,%x1,%x1"
|
||||
[(set_attr "type" "mffgpr,fpload,veclogical")])
|
||||
|
||||
(define_insn "*ieee128_mtvsrd_32bit"
|
||||
[(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
|
||||
(unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
|
||||
UNSPEC_IEEE128_MOVE))]
|
||||
"TARGET_FLOAT128_HW && !TARGET_POWERPC64"
|
||||
"@
|
||||
lxsdx %x0,%y1
|
||||
xxlor %x0,%x1,%x1"
|
||||
[(set_attr "type" "fpload,veclogical")])
|
||||
(define_insn_and_split "floatuns_<mode>si2_hw"
|
||||
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
|
||||
(unsigned_float:IEEE128
|
||||
(match_operand:SI 1 "nonimmediate_operand" "vrZ")))
|
||||
(clobber (match_scratch:DI 2 "=v"))]
|
||||
"TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
|
||||
"#"
|
||||
"&& 1"
|
||||
[(set (match_dup 2)
|
||||
(zero_extend:DI (match_dup 1)))
|
||||
(set (match_dup 0)
|
||||
(float:IEEE128 (match_dup 2)))]
|
||||
{
|
||||
if (GET_CODE (operands[2]) == SCRATCH)
|
||||
operands[2] = gen_reg_rtx (DImode);
|
||||
})
|
||||
|
||||
;; IEEE 128-bit instructions with round to odd semantics
|
||||
(define_insn "*trunc<mode>df2_odd"
|
||||
|
|
Loading…
Add table
Reference in a new issue