/// Return true if the target has BitExtract instructions.
bool hasExtractBitsInsn() const { return HasExtractBitsInsn; }
- /// Return true if a vector of the given type should be split
- /// (TypeSplitVector) instead of promoted (TypePromoteInteger) during type
- /// legalization.
- virtual bool shouldSplitVectorType(EVT /*VT*/) const { return false; }
+ /// Return the preferred vector type legalization action.
+ virtual TargetLoweringBase::LegalizeTypeAction
+ getPreferredVectorAction(EVT VT) const {
+ // The default action for one element vectors is to scalarize
+ if (VT.getVectorNumElements() == 1)
+ return TypeScalarizeVector;
+ // The default action for other vectors is to promote
+ return TypePromoteInteger;
+ }
// There are two general methods for expanding a BUILD_VECTOR node:
// 1. Use SCALAR_TO_VECTOR on the defined scalar values and then shuffle
/// selects between the two kinds. For example on X86 a scalar boolean should
/// be zero extended from i1, while the elements of a vector of booleans
/// should be sign extended from i1.
- BooleanContent getBooleanContents(bool isVec) const {
- return isVec ? BooleanVectorContents : BooleanContents;
+ ///
+ /// Some cpus also treat floating point types the same way as they treat
+ /// vectors instead of the way they treat scalars.
+ BooleanContent getBooleanContents(bool isVec, bool isFloat) const {
+ if (isVec)
+ return BooleanVectorContents;
+ return isFloat ? BooleanFloatContents : BooleanContents;
+ }
+
+ BooleanContent getBooleanContents(EVT Type) const {
+ return getBooleanContents(Type.isVector(), Type.isFloatingPoint());
}
/// Return target scheduling preference.
/// Return how this load with extension should be treated: either it is legal,
/// needs to be promoted to a larger size, needs to be expanded to some other
/// code sequence, or the target has a custom expander for it.
- LegalizeAction getLoadExtAction(unsigned ExtType, MVT VT) const {
- assert(ExtType < ISD::LAST_LOADEXT_TYPE && VT < MVT::LAST_VALUETYPE &&
+ LegalizeAction getLoadExtAction(unsigned ExtType, EVT VT) const {
+ if (VT.isExtended()) return Expand;
+ unsigned I = (unsigned) VT.getSimpleVT().SimpleTy;
+ assert(ExtType < ISD::LAST_LOADEXT_TYPE && I < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)LoadExtActions[VT.SimpleTy][ExtType];
+ return (LegalizeAction)LoadExtActions[I][ExtType];
}
/// Return true if the specified load with extension is legal on this target.
/// Return how this store with truncation should be treated: either it is
/// legal, needs to be promoted to a larger size, needs to be expanded to some
/// other code sequence, or the target has a custom expander for it.
- LegalizeAction getTruncStoreAction(MVT ValVT, MVT MemVT) const {
- assert(ValVT < MVT::LAST_VALUETYPE && MemVT < MVT::LAST_VALUETYPE &&
+ LegalizeAction getTruncStoreAction(EVT ValVT, EVT MemVT) const {
+ if (ValVT.isExtended() || MemVT.isExtended()) return Expand;
+ unsigned ValI = (unsigned) ValVT.getSimpleVT().SimpleTy;
+ unsigned MemI = (unsigned) MemVT.getSimpleVT().SimpleTy;
+ assert(ValI < MVT::LAST_VALUETYPE && MemI < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)TruncStoreActions[ValVT.SimpleTy]
- [MemVT.SimpleTy];
+ return (LegalizeAction)TruncStoreActions[ValI][MemI];
}
/// Return true if the specified store with truncation is legal on this
/// reduce runtime.
virtual bool ShouldShrinkFPConstant(EVT) const { return true; }
+ /// When splitting a value of the specified type into parts, does the Lo
+ /// or Hi part come first? This usually follows the endianness, except
+ /// for ppcf128, where the Hi part always comes first.
+ bool hasBigEndianPartOrdering(EVT VT) const {
+ return isBigEndian() || VT == MVT::ppcf128;
+ }
+
/// If true, the target has custom DAG combine transformations that it can
/// perform for the specified node.
bool hasTargetDAGCombine(ISD::NodeType NT) const {
///
/// This function returns true if the target allows unaligned memory accesses
/// of the specified type in the given address space. If true, it also returns
- /// whether the unaligned memory access is "fast" in the third argument by
+ /// whether the unaligned memory access is "fast" in the last argument by
/// reference. This is used, for example, in situations where an array
/// copy/move/set is converted to a sequence of store operations. Its use
/// helps to ensure that such replacements don't generate code that causes an
/// alignment error (trap) on the target machine.
- virtual bool allowsUnalignedMemoryAccesses(EVT,
- unsigned AddrSpace = 0,
- bool * /*Fast*/ = nullptr) const {
+ virtual bool allowsMisalignedMemoryAccesses(EVT,
+ unsigned AddrSpace = 0,
+ unsigned Align = 1,
+ bool * /*Fast*/ = nullptr) const {
return false;
}
return UseUnderscoreLongJmp;
}
- /// Return whether the target can generate code for jump tables.
- bool supportJumpTables() const {
- return SupportJumpTables;
- }
-
/// Return integer threshold on number of blocks to use jump tables rather
/// than if sequence.
int getMinimumJumpTableEntries() const {
virtual void resetOperationActions() {}
protected:
- /// Specify how the target extends the result of a boolean value from i1 to a
- /// wider type. See getBooleanContents.
- void setBooleanContents(BooleanContent Ty) { BooleanContents = Ty; }
+ /// Specify how the target extends the result of integer and floating point
+ /// boolean values from i1 to a wider type. See getBooleanContents.
+ void setBooleanContents(BooleanContent Ty) {
+ BooleanContents = Ty;
+ BooleanFloatContents = Ty;
+ }
+
+ /// Specify how the target extends the result of integer and floating point
+ /// boolean values from i1 to a wider type. See getBooleanContents.
+ void setBooleanContents(BooleanContent IntTy, BooleanContent FloatTy) {
+ BooleanContents = IntTy;
+ BooleanFloatContents = FloatTy;
+ }
/// Specify how the target extends the result of a vector boolean value from a
/// vector of i1 to a wider type. See getBooleanContents.
UseUnderscoreLongJmp = Val;
}
- /// Indicate whether the target can generate code for jump tables.
- void setSupportJumpTables(bool Val) {
- SupportJumpTables = Val;
- }
-
/// Indicate the number of blocks to generate jump tables rather than if
/// sequence.
void setMinimumJumpTableEntries(int Val) {
/// Defaults to false.
bool UseUnderscoreLongJmp;
- /// Whether the target can generate code for jumptables. If it's not true,
- /// then each jumptable must be lowered into if-then-else's.
- bool SupportJumpTables;
-
/// Number of blocks threshold to use jump tables.
int MinimumJumpTableEntries;
/// a type wider than i1. See getBooleanContents.
BooleanContent BooleanContents;
+ /// Information about the contents of the high-bits in boolean values held in
+ /// a type wider than i1. See getBooleanContents.
+ BooleanContent BooleanFloatContents;
+
/// Information about the contents of the high-bits in boolean vector values
/// when the element type is wider than i1. See getBooleanContents.
BooleanContent BooleanVectorContents;
LegalizeTypeAction LA = ValueTypeActions.getTypeAction(SVT);
assert(
- (LA == TypeLegal ||
+ (LA == TypeLegal || LA == TypeSoftenFloat ||
ValueTypeActions.getTypeAction(NVT) != TypePromoteInteger)
&& "Promote may not follow Expand or Promote");
SDValue BuildUDIV(SDNode *N, const APInt &Divisor, SelectionDAG &DAG,
bool IsAfterLegalization,
std::vector<SDNode *> *Created) const;
+ virtual SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor,
+ SelectionDAG &DAG,
+ std::vector<SDNode *> *Created) const {
+ return SDValue();
+ }
//===--------------------------------------------------------------------===//
// Legalization utility functions
SDValue LH = SDValue(), SDValue RL = SDValue(),
SDValue RH = SDValue()) const;
+ /// Expand float(f32) to SINT(i64) conversion
+ /// \param N Node to expand
+ /// \param Result output after conversion
+ /// \returns True, if the expansion was successful, false otherwise
+ bool expandFP_TO_SINT(SDNode *N, SDValue &Result, SelectionDAG &DAG) const;
+
//===--------------------------------------------------------------------===//
// Instruction Emitting Hooks
//
/// ARM 's' setting instructions.
virtual void
AdjustInstrPostInstrSelection(MachineInstr *MI, SDNode *Node) const;
+
+ /// If this function returns true, SelectionDAGBuilder emits a
+ /// LOAD_STACK_GUARD node when it is lowering Intrinsic::stackprotector.
+ virtual bool useLoadStackGuardNode() const {
+ return false;
+ }
};
/// Given an LLVM IR type and return type attributes, compute the return value