;; when little-endian.
(define_expand "signbit<mode>2"
[(set (match_dup 2)
- (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
+ (float_truncate:DF (match_operand:FLOAT128 1 "reg_or_mem_operand")))
(set (match_dup 3)
(subreg:DI (match_dup 2) 0))
(set (match_dup 4)
rtx dest = operands[0];
rtx src = operands[1];
rtx tmp = gen_reg_rtx (DImode);
+ /* For P8 LE, we generate memory access with subreg:V1TI which
+ prevents the related gen_signbitkf2_dm_mem being matched so
+ directly emit it here and leave the other cases alone. */
+ if (!BYTES_BIG_ENDIAN
+ && !TARGET_P9_VECTOR
+ && memory_operand (src, <MODE>mode))
+ emit_insn (gen_signbitkf2_dm_mem (tmp, src));
+ else
+ {
+ if (!gpc_reg_operand (src, <MODE>mode))
+ src = copy_to_mode_reg (<MODE>mode, src);
+ gcc_assert (gpc_reg_operand (src, <MODE>mode));
+ emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
+ }
rtx dest_di = gen_lowpart (DImode, dest);
-
- emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
DONE;
}
+ if (!gpc_reg_operand (operands[1], <MODE>mode))
+ operands[1] = copy_to_mode_reg (<MODE>mode, operands[1]);
operands[2] = gen_reg_rtx (DFmode);
operands[3] = gen_reg_rtx (DImode);
if (TARGET_POWERPC64)
;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
;; register and then doing a direct move if the value comes from memory. On
;; little endian, we have to load the 2nd double-word to get the sign bit.
-(define_insn_and_split "*signbit<mode>2_dm_mem"
+(define_insn_and_split "signbit<mode>2_dm_mem"
[(set (match_operand:DI 0 "gpc_reg_operand" "=b")
(unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
UNSPEC_SIGNBIT))]
--- /dev/null
+/* { dg-options "-O2 -mabi=ibmlongdouble -Wno-psabi" } */
+/* { dg-additional-options "-mdejagnu-cpu=power8" { target { ! has_arch_pwr8 } } } */
+/* { dg-require-effective-target powerpc_vsx } */
+/* { dg-require-effective-target float128 } */
+
+/* Verify there is no lxv.*x? and mfvsrd (vector load and move). */
+
+int
+sbm (_Float128 *a)
+{
+ return __builtin_signbit (*a);
+}
+
+/* { dg-final { scan-assembler-times {\ml(d|wz)\M} 1 } } */
+/* { dg-final { scan-assembler-not {\mlxv\M} } } */
+/* { dg-final { scan-assembler-not {\mlxvd2x\M} } } */
+/* { dg-final { scan-assembler-not {\mmfvsrd\M} } } */