&& TARGET_HARD_FLOAT
&& !TARGET_IEEEQUAD) ? RS6000_BTM_LDBL128 : 0)
| ((TARGET_FLOAT128_TYPE) ? RS6000_BTM_FLOAT128 : 0)
- | ((TARGET_FLOAT128_HW) ? RS6000_BTM_FLOAT128_HW : 0));
+ | ((TARGET_FLOAT128_HW) ? RS6000_BTM_FLOAT128_HW : 0)
+ | ((TARGET_FUTURE) ? RS6000_BTM_FUTURE : 0));
}
/* Implement TARGET_MD_ASM_ADJUST. All asm statements are considered
static unsigned
rs6000_add_stmt_cost (class vec_info *vinfo, void *data, int count,
enum vect_cost_for_stmt kind,
- struct _stmt_vec_info *stmt_info, int misalign,
- enum vect_cost_model_location where)
+ struct _stmt_vec_info *stmt_info, tree vectype,
+ int misalign, enum vect_cost_model_location where)
{
rs6000_cost_data *cost_data = (rs6000_cost_data*) data;
unsigned retval = 0;
if (flag_vect_cost_model)
{
- tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE;
int stmt_cost = rs6000_builtin_vectorization_cost (kind, vectype,
misalign);
stmt_cost += adjust_vectorization_cost (kind, stmt_info);
return INSN_FORM_BAD;
}
+/* Helper function to see if we're potentially looking at lfs/stfs.
+ - PARALLEL containing a SET and a CLOBBER
+ - stfs:
+ - SET is from UNSPEC_SI_FROM_SF to MEM:SI
+ - CLOBBER is a V4SF
+ - lfs:
+ - SET is from UNSPEC_SF_FROM_SI to REG:SF
+ - CLOBBER is a DI
+ */
+
+static bool
+is_lfs_stfs_insn (rtx_insn *insn)
+{
+ rtx pattern = PATTERN (insn);
+ if (GET_CODE (pattern) != PARALLEL)
+ return false;
+
+ /* This should be a parallel with exactly one set and one clobber. */
+ if (XVECLEN (pattern, 0) != 2)
+ return false;
+
+ rtx set = XVECEXP (pattern, 0, 0);
+ if (GET_CODE (set) != SET)
+ return false;
+
+ rtx clobber = XVECEXP (pattern, 0, 1);
+ if (GET_CODE (clobber) != CLOBBER)
+ return false;
+
+ /* All we care is that the destination of the SET is a mem:SI,
+ the source should be an UNSPEC_SI_FROM_SF, and the clobber
+ should be a scratch:V4SF. */
+
+ rtx dest = SET_DEST (set);
+ rtx src = SET_SRC (set);
+ rtx scratch = SET_DEST (clobber);
+
+ if (GET_CODE (src) != UNSPEC)
+ return false;
+
+ /* stfs case. */
+ if (XINT (src, 1) == UNSPEC_SI_FROM_SF
+ && GET_CODE (dest) == MEM && GET_MODE (dest) == SImode
+ && GET_CODE (scratch) == SCRATCH && GET_MODE (scratch) == V4SFmode)
+ return true;
+
+ /* lfs case. */
+ if (XINT (src, 1) == UNSPEC_SF_FROM_SI
+ && GET_CODE (dest) == REG && GET_MODE (dest) == SFmode
+ && GET_CODE (scratch) == SCRATCH && GET_MODE (scratch) == DImode)
+ return true;
+
+ return false;
+}
+
/* Helper function to take a REG and a MODE and turn it into the non-prefixed
instruction format (D/DS/DQ) used for offset memory. */
else
non_prefixed = reg_to_non_prefixed (reg, mem_mode);
- return address_is_prefixed (XEXP (mem, 0), mem_mode, non_prefixed);
+ if (non_prefixed == NON_PREFIXED_X && is_lfs_stfs_insn (insn))
+ return address_is_prefixed (XEXP (mem, 0), mem_mode, NON_PREFIXED_DEFAULT);
+ else
+ return address_is_prefixed (XEXP (mem, 0), mem_mode, non_prefixed);
}
/* Whether a store instruction is a prefixed instruction. This is called from
return false;
machine_mode mem_mode = GET_MODE (mem);
+ rtx addr = XEXP (mem, 0);
enum non_prefixed_form non_prefixed = reg_to_non_prefixed (reg, mem_mode);
- return address_is_prefixed (XEXP (mem, 0), mem_mode, non_prefixed);
+
+ /* Need to make sure we aren't looking at a stfs which doesn't look
+ like the other things reg_to_non_prefixed/address_is_prefixed
+ looks for. */
+ if (non_prefixed == NON_PREFIXED_X && is_lfs_stfs_insn (insn))
+ return address_is_prefixed (addr, mem_mode, NON_PREFIXED_DEFAULT);
+ else
+ return address_is_prefixed (addr, mem_mode, non_prefixed);
}
/* Whether a load immediate or add instruction is a prefixed instruction. This