mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-18 12:29:21 +00:00
Revamp supported ops. Instead of just being supported or not, we now keep
track of how to deal with it, and provide the target with a hook that they can use to legalize arbitrary operations in arbitrary ways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19609 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cd7c1cae1c
commit
7e5ee40979
@ -66,15 +66,29 @@ class TargetLowering {
|
||||
/// by the system, this holds the same type (e.g. i32 -> i32).
|
||||
MVT::ValueType TransformToType[MVT::LAST_VALUETYPE];
|
||||
|
||||
unsigned short UnsupportedOps[128];
|
||||
/// OpActions - For each operation and each value type, keep a LegalizeAction
|
||||
/// that indicates how instruction selection should deal with the operation.
|
||||
/// Most operations are Legal (aka, supported natively by the target), but
|
||||
/// operations that are not should be described. Note that operations on
|
||||
/// non-legal value types are not described here.
|
||||
unsigned OpActions[128];
|
||||
|
||||
std::vector<double> LegalFPImmediates;
|
||||
|
||||
std::vector<std::pair<MVT::ValueType,
|
||||
TargetRegisterClass*> > AvailableRegClasses;
|
||||
public:
|
||||
/// LegalizeAction - This enum indicates whether operations are valid for a
|
||||
/// target, and if not, what action should be used to make them valid.
|
||||
enum LegalizeAction {
|
||||
Legal, // The target natively supports this operation.
|
||||
Promote, // This operation should be executed in a larger type.
|
||||
Expand, // Try to expand this to other ops, otherwise use a libcall.
|
||||
Custom, // Use the LowerOperation hook to implement custom lowering.
|
||||
};
|
||||
|
||||
TargetLowering(TargetMachine &TM);
|
||||
virtual ~TargetLowering() {}
|
||||
virtual ~TargetLowering();
|
||||
|
||||
TargetMachine &getTargetMachine() const { return TM; }
|
||||
const TargetData &getTargetData() const { return TD; }
|
||||
@ -82,7 +96,7 @@ public:
|
||||
bool isLittleEndian() const { return IsLittleEndian; }
|
||||
MVT::ValueType getPointerTy() const { return PointerTy; }
|
||||
|
||||
TargetRegisterClass *getRegClassFor(MVT::ValueType VT) {
|
||||
TargetRegisterClass *getRegClassFor(MVT::ValueType VT) const {
|
||||
TargetRegisterClass *RC = RegClassForVT[VT];
|
||||
assert(RC && "This value type is not natively supported!");
|
||||
return RC;
|
||||
@ -91,16 +105,16 @@ public:
|
||||
/// hasNativeSupportFor - Return true if the target has native support for the
|
||||
/// specified value type. This means that it has a register that directly
|
||||
/// holds it without promotions or expansions.
|
||||
bool hasNativeSupportFor(MVT::ValueType VT) {
|
||||
bool hasNativeSupportFor(MVT::ValueType VT) const {
|
||||
return RegClassForVT[VT] != 0;
|
||||
}
|
||||
|
||||
/// getTypeAction - Return how we should legalize values of this type, either
|
||||
/// it is already legal (return 0) or we need to promote it to a larger type
|
||||
/// (return 1), or we need to expand it into multiple registers of smaller
|
||||
/// integer type (return 2).
|
||||
unsigned getTypeAction(MVT::ValueType VT) const {
|
||||
return (ValueTypeActions >> (2*VT)) & 3;
|
||||
/// it is already legal (return 'Legal') or we need to promote it to a larger
|
||||
/// type (return 'Promote'), or we need to expand it into multiple registers
|
||||
/// of smaller integer type (return 'Expand'). 'Custom' is not an option.
|
||||
LegalizeAction getTypeAction(MVT::ValueType VT) const {
|
||||
return (LegalizeAction)((ValueTypeActions >> (2*VT)) & 3);
|
||||
}
|
||||
unsigned getValueTypeActions() const { return ValueTypeActions; }
|
||||
|
||||
@ -109,7 +123,7 @@ public:
|
||||
/// returns the larger type to promote to. For types that are larger than the
|
||||
/// largest integer register, this contains one step in the expansion to get
|
||||
/// to the smaller register.
|
||||
MVT::ValueType getTypeToTransformTo(MVT::ValueType VT) {
|
||||
MVT::ValueType getTypeToTransformTo(MVT::ValueType VT) const {
|
||||
return TransformToType[VT];
|
||||
}
|
||||
|
||||
@ -120,12 +134,37 @@ public:
|
||||
legal_fpimm_iterator legal_fpimm_end() const {
|
||||
return LegalFPImmediates.end();
|
||||
}
|
||||
|
||||
bool isOperationSupported(unsigned Op, MVT::ValueType VT) {
|
||||
return (UnsupportedOps[Op] & (1 << VT)) == 0;
|
||||
|
||||
/// getOperationAction - Return how this operation should be
|
||||
LegalizeAction getOperationAction(unsigned Op, MVT::ValueType VT) const {
|
||||
return (LegalizeAction)((OpActions[Op] >> (2*VT)) & 3);
|
||||
}
|
||||
|
||||
MVT::ValueType getValueType(const Type *Ty) {
|
||||
/// hasNativeSupportForOperation - Return true if this operation is legal for
|
||||
/// this type.
|
||||
///
|
||||
bool hasNativeSupportForOperation(unsigned Op, MVT::ValueType VT) const {
|
||||
return getOperationAction(Op, VT) == Legal;
|
||||
}
|
||||
|
||||
/// getTypeToPromoteTo - If the action for this operation is to promote, this
|
||||
/// method returns the ValueType to promote to.
|
||||
MVT::ValueType getTypeToPromoteTo(unsigned Op, MVT::ValueType VT) const {
|
||||
assert(getOperationAction(Op, VT) == Promote &&
|
||||
"This operation isn't promoted!");
|
||||
MVT::ValueType NVT = VT;
|
||||
do {
|
||||
NVT = (MVT::ValueType)(NVT+1);
|
||||
assert(MVT::isInteger(NVT) == MVT::isInteger(VT) && NVT != MVT::isVoid &&
|
||||
"Didn't find type to promote to!");
|
||||
} while (!hasNativeSupportFor(NVT) ||
|
||||
getOperationAction(Op, NVT) == Promote);
|
||||
return NVT;
|
||||
}
|
||||
|
||||
/// getValueType - Return the MVT::ValueType corresponding to this LLVM type.
|
||||
/// This is fixed by the LLVM operations except for the pointer size.
|
||||
MVT::ValueType getValueType(const Type *Ty) const {
|
||||
switch (Ty->getTypeID()) {
|
||||
default: assert(0 && "Unknown type!");
|
||||
case Type::VoidTyID: return MVT::isVoid;
|
||||
@ -171,10 +210,13 @@ protected:
|
||||
/// this allows us to compute derived properties we expose.
|
||||
void computeRegisterProperties();
|
||||
|
||||
|
||||
void setOperationUnsupported(unsigned Op, MVT::ValueType VT) {
|
||||
assert(VT < 16 && "Too many value types!");
|
||||
UnsupportedOps[Op] |= 1 << VT;
|
||||
/// setOperationAction - Indicate that the specified operation does not work
|
||||
/// with the specified type and indicate what to do about it.
|
||||
void setOperationAction(unsigned Op, MVT::ValueType VT,
|
||||
LegalizeAction Action) {
|
||||
assert(VT < 16 && Op < sizeof(OpActions)/sizeof(OpActions[0]) &&
|
||||
"Table isn't big enough!");
|
||||
OpActions[Op] |= Action << VT*2;
|
||||
}
|
||||
|
||||
/// addLegalFPImmediate - Indicate that this target can instruction select
|
||||
@ -182,7 +224,6 @@ protected:
|
||||
void addLegalFPImmediate(double Imm) {
|
||||
LegalFPImmediates.push_back(Imm);
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
@ -235,6 +276,12 @@ public:
|
||||
virtual std::pair<SDOperand, SDOperand>
|
||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||
SelectionDAG &DAG);
|
||||
|
||||
/// LowerOperation - For operations that are unsupported by the target, and
|
||||
/// which are registered to use 'custom' lowering. This callback is invoked.
|
||||
/// If the target has no operations that require custom lowering, it need not
|
||||
/// implement this. The default implementation of this aborts.
|
||||
virtual SDOperand LowerOperation(SDOperand Op);
|
||||
};
|
||||
} // end llvm namespace
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user