extern enum rtx_code s390_reverse_condition (machine_mode, enum rtx_code);
extern void s390_expand_vcond (rtx, rtx, rtx, enum rtx_code, rtx, rtx);
extern void s390_expand_vec_init (rtx, rtx);
+extern rtx s390_build_signbit_mask (machine_mode);
extern rtx s390_return_addr_rtx (int, rtx);
extern rtx s390_back_chain_rtx (void);
extern rtx_insn *s390_emit_call (rtx, rtx, rtx, rtx);
rtx elt;
bool b;
+ /* Handle floats by bitcasting them to ints. */
+ op = gen_lowpart (related_int_vector_mode (GET_MODE (op)).require (), op);
+
gcc_assert (!!start == !!end);
if (!const_vec_duplicate_p (op, &elt)
|| !CONST_INT_P (elt))
}
/* Use vector gen mask or vector gen byte mask if possible. */
- if (all_same && all_const_int
- && (XVECEXP (vals, 0, 0) == const0_rtx
- || s390_contiguous_bitmask_vector_p (XVECEXP (vals, 0, 0),
- NULL, NULL)
- || s390_bytemask_vector_p (XVECEXP (vals, 0, 0), NULL)))
+ if (all_same && all_const_int)
{
- emit_insn (gen_rtx_SET (target,
- gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0))));
- return;
+ rtx vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
+ if (XVECEXP (vals, 0, 0) == const0_rtx
+ || s390_contiguous_bitmask_vector_p (vec, NULL, NULL)
+ || s390_bytemask_vector_p (vec, NULL))
+ {
+ emit_insn (gen_rtx_SET (target, vec));
+ return;
+ }
}
/* Use vector replicate instructions. vlrep/vrepi/vrep */
}
}
+/* Emit a vector constant that contains 1s in each element's sign bit position
+ and 0s in other positions. MODE is the desired constant's mode. */
+extern rtx
+s390_build_signbit_mask (machine_mode mode)
+{
+ /* Generate the integral element mask value. */
+ machine_mode inner_mode = GET_MODE_INNER (mode);
+ int inner_bitsize = GET_MODE_BITSIZE (inner_mode);
+ wide_int mask_val = wi::set_bit_in_zero (inner_bitsize - 1, inner_bitsize);
+
+ /* Emit the element mask rtx. Use gen_lowpart in order to cast the integral
+ value to the desired mode. */
+ machine_mode int_mode = related_int_vector_mode (mode).require ();
+ rtx mask = immed_wide_int_const (mask_val, GET_MODE_INNER (int_mode));
+ mask = gen_lowpart (inner_mode, mask);
+
+ /* Emit the vector mask rtx by mode the element mask rtx. */
+ int nunits = GET_MODE_NUNITS (mode);
+ rtvec v = rtvec_alloc (nunits);
+ for (int i = 0; i < nunits; i++)
+ RTVEC_ELT (v, i) = mask;
+ return gen_rtx_CONST_VECTOR (mode, v);
+}
+
/* Structure to hold the initial parameters for a compare_and_swap operation
in HImode and QImode. */
; Vector copysign, implement using vector select
(define_expand "copysign<mode>3"
- [(set (match_operand:VFT 0 "register_operand" "")
- (if_then_else:VFT
- (eq (match_dup 3)
- (match_dup 4))
- (match_operand:VFT 1 "register_operand" "")
- (match_operand:VFT 2 "register_operand" "")))]
+ [(set (match_operand:VFT 0 "register_operand" "")
+ (ior:VFT
+ (and:VFT (match_operand:VFT 2 "register_operand" "")
+ (match_dup 3))
+ (and:VFT (not:VFT (match_dup 3))
+ (match_operand:VFT 1 "register_operand" ""))))]
"TARGET_VX"
{
- int sz = GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
- int prec = GET_MODE_PRECISION (GET_MODE_INNER (<tointvec>mode));
- wide_int mask_val = wi::shwi (1l << (sz - 1), prec);
-
- rtx mask = gen_reg_rtx (<tointvec>mode);
-
- int nunits = GET_MODE_NUNITS (<tointvec>mode);
- rtvec v = rtvec_alloc (nunits);
- for (int i = 0; i < nunits; i++)
- RTVEC_ELT (v, i) = GEN_INT (mask_val.to_shwi ());
-
- mask = gen_rtx_CONST_VECTOR (<tointvec>mode, v);
- operands[3] = force_reg (<tointvec>mode, mask);
- operands[4] = CONST0_RTX (<tointvec>mode);
+ rtx mask = s390_build_signbit_mask (<MODE>mode);
+ operands[3] = force_reg (<MODE>mode, mask);
})
;;