/* Double word values on VSX can use xxpermdi or lxvdsx. */
if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
{
+ rtx op0 = XVECEXP (vals, 0, 0);
+ rtx op1 = XVECEXP (vals, 0, 1);
if (all_same)
{
- rtx element = XVECEXP (vals, 0, 0);
+ if (!MEM_P (op0) && !REG_P (op0))
+ op0 = force_reg (inner_mode, op0);
if (mode == V2DFmode)
- emit_insn (gen_vsx_splat_v2df (target, element));
+ emit_insn (gen_vsx_splat_v2df (target, op0));
else
- emit_insn (gen_vsx_splat_v2di (target, element));
+ emit_insn (gen_vsx_splat_v2di (target, op0));
}
else
{
+ op0 = force_reg (inner_mode, op0);
+ op1 = force_reg (inner_mode, op1);
if (mode == V2DFmode)
- {
- rtx op0 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 0));
- rtx op1 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 1));
- emit_insn (gen_vsx_concat_v2df (target, op0, op1));
- }
+ emit_insn (gen_vsx_concat_v2df (target, op0, op1));
else
- {
- rtx op0 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 0));
- rtx op1 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 1));
- emit_insn (gen_vsx_concat_v2di (target, op0, op1));
- }
+ emit_insn (gen_vsx_concat_v2di (target, op0, op1));
}
return;
}
if (all_same)
{
rtx freg = gen_reg_rtx (V4SFmode);
- rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
+ rtx sreg = force_reg (SFmode, XVECEXP (vals, 0, 0));
emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
rtx dbl_odd = gen_reg_rtx (V2DFmode);
rtx flt_even = gen_reg_rtx (V4SFmode);
rtx flt_odd = gen_reg_rtx (V4SFmode);
+ rtx op0 = force_reg (SFmode, XVECEXP (vals, 0, 0));
+ rtx op1 = force_reg (SFmode, XVECEXP (vals, 0, 1));
+ rtx op2 = force_reg (SFmode, XVECEXP (vals, 0, 2));
+ rtx op3 = force_reg (SFmode, XVECEXP (vals, 0, 3));
- emit_insn (gen_vsx_concat_v2sf (dbl_even,
- copy_to_reg (XVECEXP (vals, 0, 0)),
- copy_to_reg (XVECEXP (vals, 0, 1))));
- emit_insn (gen_vsx_concat_v2sf (dbl_odd,
- copy_to_reg (XVECEXP (vals, 0, 2)),
- copy_to_reg (XVECEXP (vals, 0, 3))));
+ emit_insn (gen_vsx_concat_v2sf (dbl_even, op0, op1));
+ emit_insn (gen_vsx_concat_v2sf (dbl_odd, op2, op3));
emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
rs6000_expand_extract_even (target, flt_even, flt_odd);