===================================================================
@@ -25170,9 +25170,7 @@ rs6000_split_signbit (rtx dest, rtx src)
rtx dest_di = (d_mode == DImode) ? dest : gen_lowpart (DImode, dest);
rtx shift_reg = dest_di;
- gcc_assert (REG_P (dest));
- gcc_assert (REG_P (src) || MEM_P (src));
- gcc_assert (s_mode == KFmode || s_mode == TFmode);
+ gcc_assert (FLOAT128_IEEE_P (s_mode) && TARGET_POWERPC64);
if (MEM_P (src))
{
@@ -25184,17 +25182,20 @@ rs6000_split_signbit (rtx dest, rtx src)
else
{
- unsigned int r = REGNO (src);
+ unsigned int r = reg_or_subregno (src);
- /* If this is a VSX register, generate the special mfvsrd instruction
- to get it in a GPR. Until we support SF and DF modes, that will
- always be true. */
- gcc_assert (VSX_REGNO_P (r));
+ if (INT_REGNO_P (r))
+ shift_reg = gen_rtx_REG (DImode, r + (BYTES_BIG_ENDIAN == 0));
- if (s_mode == KFmode)
- emit_insn (gen_signbitkf2_dm2 (dest_di, src));
else
- emit_insn (gen_signbittf2_dm2 (dest_di, src));
+ {
+ /* Generate the special mfvsrd instruction to get it in a GPR. */
+ gcc_assert (VSX_REGNO_P (r));
+ if (s_mode == KFmode)
+ emit_insn (gen_signbitkf2_dm2 (dest_di, src));
+ else
+ emit_insn (gen_signbittf2_dm2 (dest_di, src));
+ }
}
emit_insn (gen_lshrdi3 (dest_di, shift_reg, GEN_INT (63)));
===================================================================
@@ -518,9 +518,6 @@ (define_mode_iterator FLOAT128 [(KF "TAR
(define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
(TF "FLOAT128_VECTOR_P (TFmode)")])
-(define_mode_attr Fsignbit [(KF "wa")
- (TF "wa")])
-
; Iterator for ISA 3.0 supported floating point types
(define_mode_iterator FP_ISA3 [SF
DF
@@ -4744,7 +4741,7 @@ (define_expand "copysign<mode>3"
(define_insn_and_split "signbit<mode>2_dm"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
(unspec:SI
- [(match_operand:SIGNBIT 1 "input_operand" "<Fsignbit>,m,r")]
+ [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
UNSPEC_SIGNBIT))]
"TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
"#"
@@ -4754,7 +4751,24 @@ (define_insn_and_split "signbit<mode>2_d
rs6000_split_signbit (operands[0], operands[1]);
DONE;
}
- [(set_attr "length" "8,8,12")
+ [(set_attr "length" "8,8,4")
+ (set_attr "type" "mftgpr,load,integer")])
+
+(define_insn_and_split "*signbit<mode>2_dm_<su>ext"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
+ (any_extend:DI
+ (unspec:SI
+ [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
+ UNSPEC_SIGNBIT)))]
+ "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ rs6000_split_signbit (operands[0], operands[1]);
+ DONE;
+}
+ [(set_attr "length" "8,8,4")
(set_attr "type" "mftgpr,load,integer")])
;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
@@ -4762,7 +4776,7 @@ (define_insn_and_split "signbit<mode>2_d
;; special pattern to avoid using a normal movdi.
(define_insn "signbit<mode>2_dm2"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "<Fsignbit>")
+ (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
(const_int 0)]
UNSPEC_SIGNBIT))]
"TARGET_POWERPC64 && TARGET_DIRECT_MOVE"