mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-10-20 09:24:58 +00:00
Lower target intrinsics into an INTRINSIC node
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27035 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
019a0a9725
commit
0eade319cd
@ -481,6 +481,7 @@ public:
|
|||||||
void visitCall(CallInst &I);
|
void visitCall(CallInst &I);
|
||||||
void visitInlineAsm(CallInst &I);
|
void visitInlineAsm(CallInst &I);
|
||||||
const char *visitIntrinsicCall(CallInst &I, unsigned Intrinsic);
|
const char *visitIntrinsicCall(CallInst &I, unsigned Intrinsic);
|
||||||
|
void visitTargetIntrinsic(CallInst &I, unsigned Intrinsic);
|
||||||
|
|
||||||
void visitVAStart(CallInst &I);
|
void visitVAStart(CallInst &I);
|
||||||
void visitVAArg(VAArgInst &I);
|
void visitVAArg(VAArgInst &I);
|
||||||
@ -1001,12 +1002,91 @@ void SelectionDAGLowering::visitStore(StoreInst &I) {
|
|||||||
DAG.getSrcValue(I.getOperand(1))));
|
DAG.getSrcValue(I.getOperand(1))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// IntrinsicCannotAccessMemory - Return true if the specified intrinsic cannot
|
||||||
|
/// access memory and has no other side effects at all.
|
||||||
|
static bool IntrinsicCannotAccessMemory(unsigned IntrinsicID) {
|
||||||
|
#define GET_NO_MEMORY_INTRINSICS
|
||||||
|
#include "llvm/Intrinsics.gen"
|
||||||
|
#undef GET_NO_MEMORY_INTRINSICS
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC
|
||||||
|
/// node.
|
||||||
|
void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I,
|
||||||
|
unsigned Intrinsic) {
|
||||||
|
bool HasChain = IntrinsicCannotAccessMemory(Intrinsic);
|
||||||
|
|
||||||
|
// Build the operand list.
|
||||||
|
std::vector<SDOperand> Ops;
|
||||||
|
if (HasChain) // If this intrinsic has side-effects, chainify it.
|
||||||
|
Ops.push_back(getRoot());
|
||||||
|
|
||||||
|
// Add the intrinsic ID as an integer operand.
|
||||||
|
Ops.push_back(DAG.getConstant(Intrinsic, TLI.getPointerTy()));
|
||||||
|
|
||||||
|
// Add all operands of the call to the operand list.
|
||||||
|
for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) {
|
||||||
|
SDOperand Op = getValue(I.getOperand(i));
|
||||||
|
|
||||||
|
// If this is a vector type, force it to the right packed type.
|
||||||
|
if (Op.getValueType() == MVT::Vector) {
|
||||||
|
const PackedType *OpTy = cast<PackedType>(I.getOperand(i)->getType());
|
||||||
|
MVT::ValueType EltVT = TLI.getValueType(OpTy->getElementType());
|
||||||
|
|
||||||
|
MVT::ValueType VVT = MVT::getVectorType(EltVT, OpTy->getNumElements());
|
||||||
|
assert(VVT != MVT::Other && "Intrinsic uses a non-legal type?");
|
||||||
|
Op = DAG.getNode(ISD::VBIT_CONVERT, VVT, Op);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(TLI.isTypeLegal(Op.getValueType()) &&
|
||||||
|
"Intrinsic uses a non-legal type?");
|
||||||
|
Ops.push_back(Op);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<MVT::ValueType> VTs;
|
||||||
|
if (I.getType() != Type::VoidTy) {
|
||||||
|
MVT::ValueType VT = TLI.getValueType(I.getType());
|
||||||
|
if (VT == MVT::Vector) {
|
||||||
|
const PackedType *DestTy = cast<PackedType>(I.getType());
|
||||||
|
MVT::ValueType EltVT = TLI.getValueType(DestTy->getElementType());
|
||||||
|
|
||||||
|
VT = MVT::getVectorType(EltVT, DestTy->getNumElements());
|
||||||
|
assert(VT != MVT::Other && "Intrinsic uses a non-legal type?");
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(TLI.isTypeLegal(VT) && "Intrinsic uses a non-legal type?");
|
||||||
|
VTs.push_back(VT);
|
||||||
|
}
|
||||||
|
if (HasChain)
|
||||||
|
VTs.push_back(MVT::Other);
|
||||||
|
|
||||||
|
// Create the node.
|
||||||
|
SDOperand Result = DAG.getNode(ISD::INTRINSIC, VTs, Ops);
|
||||||
|
|
||||||
|
if (HasChain)
|
||||||
|
DAG.setRoot(Result.getValue(Result.Val->getNumValues()-1));
|
||||||
|
if (I.getType() != Type::VoidTy) {
|
||||||
|
if (const PackedType *PTy = dyn_cast<PackedType>(I.getType())) {
|
||||||
|
MVT::ValueType EVT = TLI.getValueType(PTy->getElementType());
|
||||||
|
Result = DAG.getNode(ISD::VBIT_CONVERT, MVT::Vector, Result,
|
||||||
|
DAG.getConstant(PTy->getNumElements(), MVT::i32),
|
||||||
|
DAG.getValueType(EVT));
|
||||||
|
}
|
||||||
|
setValue(&I, Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// visitIntrinsicCall - Lower the call to the specified intrinsic function. If
|
/// visitIntrinsicCall - Lower the call to the specified intrinsic function. If
|
||||||
/// we want to emit this as a call to a named external function, return the name
|
/// we want to emit this as a call to a named external function, return the name
|
||||||
/// otherwise lower it and return null.
|
/// otherwise lower it and return null.
|
||||||
const char *
|
const char *
|
||||||
SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
||||||
switch (Intrinsic) {
|
switch (Intrinsic) {
|
||||||
|
default:
|
||||||
|
// By default, turn this into a target intrinsic node.
|
||||||
|
visitTargetIntrinsic(I, Intrinsic);
|
||||||
|
return 0;
|
||||||
case Intrinsic::vastart: visitVAStart(I); return 0;
|
case Intrinsic::vastart: visitVAStart(I); return 0;
|
||||||
case Intrinsic::vaend: visitVAEnd(I); return 0;
|
case Intrinsic::vaend: visitVAEnd(I); return 0;
|
||||||
case Intrinsic::vacopy: visitVACopy(I); return 0;
|
case Intrinsic::vacopy: visitVACopy(I); return 0;
|
||||||
@ -1194,10 +1274,6 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
|||||||
case Intrinsic::prefetch:
|
case Intrinsic::prefetch:
|
||||||
// FIXME: Currently discarding prefetches.
|
// FIXME: Currently discarding prefetches.
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
|
||||||
std::cerr << I;
|
|
||||||
assert(0 && "This intrinsic is not implemented yet!");
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user