mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-22 20:05:38 +00:00
remove TargetAsmInfo::ExpandInlineAsm
llvm-svn: 76445
This commit is contained in:
parent
31022c9412
commit
1f82d9a94c
@ -562,15 +562,6 @@ namespace llvm {
|
||||
/// length.
|
||||
virtual unsigned getInlineAsmLength(const char *Str) const;
|
||||
|
||||
/// ExpandInlineAsm - This hook allows the target to expand an inline asm
|
||||
/// call to be explicit llvm code if it wants to. This is useful for
|
||||
/// turning simple inline asms into LLVM intrinsics, which gives the
|
||||
/// compiler more information about the behavior of the code.
|
||||
// FIXME: Move this to TargetLowering.
|
||||
virtual bool ExpandInlineAsm(CallInst *CI) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// emitUsedDirectiveFor - This hook allows targets to selectively decide
|
||||
/// not to emit the UsedDirective for some symbols in llvm.used.
|
||||
// FIXME: REMOVE this (rdar://7071300)
|
||||
|
@ -333,99 +333,5 @@ X86WinTargetAsmInfo::X86WinTargetAsmInfo(const X86TargetMachine &TM):
|
||||
SectionEndDirectiveSuffix = "\tends\n";
|
||||
}
|
||||
|
||||
template <class BaseTAI>
|
||||
bool X86TargetAsmInfo<BaseTAI>::LowerToBSwap(CallInst *CI) const {
|
||||
// FIXME: this should verify that we are targetting a 486 or better. If not,
|
||||
// we will turn this bswap into something that will be lowered to logical ops
|
||||
// instead of emitting the bswap asm. For now, we don't support 486 or lower
|
||||
// so don't worry about this.
|
||||
|
||||
// Verify this is a simple bswap.
|
||||
if (CI->getNumOperands() != 2 ||
|
||||
CI->getType() != CI->getOperand(1)->getType() ||
|
||||
!CI->getType()->isInteger())
|
||||
return false;
|
||||
|
||||
const IntegerType *Ty = dyn_cast<IntegerType>(CI->getType());
|
||||
if (!Ty || Ty->getBitWidth() % 16 != 0)
|
||||
return false;
|
||||
|
||||
// Okay, we can do this xform, do so now.
|
||||
const Type *Tys[] = { Ty };
|
||||
Module *M = CI->getParent()->getParent()->getParent();
|
||||
Constant *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Tys, 1);
|
||||
|
||||
Value *Op = CI->getOperand(1);
|
||||
Op = CallInst::Create(Int, Op, CI->getName(), CI);
|
||||
|
||||
CI->replaceAllUsesWith(Op);
|
||||
CI->eraseFromParent();
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class BaseTAI>
|
||||
bool X86TargetAsmInfo<BaseTAI>::ExpandInlineAsm(CallInst *CI) const {
|
||||
InlineAsm *IA = cast<InlineAsm>(CI->getCalledValue());
|
||||
std::vector<InlineAsm::ConstraintInfo> Constraints = IA->ParseConstraints();
|
||||
|
||||
std::string AsmStr = IA->getAsmString();
|
||||
|
||||
// TODO: should remove alternatives from the asmstring: "foo {a|b}" -> "foo a"
|
||||
std::vector<std::string> AsmPieces;
|
||||
SplitString(AsmStr, AsmPieces, "\n"); // ; as separator?
|
||||
|
||||
switch (AsmPieces.size()) {
|
||||
default: return false;
|
||||
case 1:
|
||||
AsmStr = AsmPieces[0];
|
||||
AsmPieces.clear();
|
||||
SplitString(AsmStr, AsmPieces, " \t"); // Split with whitespace.
|
||||
|
||||
// bswap $0
|
||||
if (AsmPieces.size() == 2 &&
|
||||
(AsmPieces[0] == "bswap" ||
|
||||
AsmPieces[0] == "bswapq" ||
|
||||
AsmPieces[0] == "bswapl") &&
|
||||
(AsmPieces[1] == "$0" ||
|
||||
AsmPieces[1] == "${0:q}")) {
|
||||
// No need to check constraints, nothing other than the equivalent of
|
||||
// "=r,0" would be valid here.
|
||||
return LowerToBSwap(CI);
|
||||
}
|
||||
// rorw $$8, ${0:w} --> llvm.bswap.i16
|
||||
if (CI->getType() == Type::Int16Ty &&
|
||||
AsmPieces.size() == 3 &&
|
||||
AsmPieces[0] == "rorw" &&
|
||||
AsmPieces[1] == "$$8," &&
|
||||
AsmPieces[2] == "${0:w}" &&
|
||||
IA->getConstraintString() == "=r,0,~{dirflag},~{fpsr},~{flags},~{cc}") {
|
||||
return LowerToBSwap(CI);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (CI->getType() == Type::Int64Ty && Constraints.size() >= 2 &&
|
||||
Constraints[0].Codes.size() == 1 && Constraints[0].Codes[0] == "A" &&
|
||||
Constraints[1].Codes.size() == 1 && Constraints[1].Codes[0] == "0") {
|
||||
// bswap %eax / bswap %edx / xchgl %eax, %edx -> llvm.bswap.i64
|
||||
std::vector<std::string> Words;
|
||||
SplitString(AsmPieces[0], Words, " \t");
|
||||
if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%eax") {
|
||||
Words.clear();
|
||||
SplitString(AsmPieces[1], Words, " \t");
|
||||
if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%edx") {
|
||||
Words.clear();
|
||||
SplitString(AsmPieces[2], Words, " \t,");
|
||||
if (Words.size() == 3 && Words[0] == "xchgl" && Words[1] == "%eax" &&
|
||||
Words[2] == "%edx") {
|
||||
return LowerToBSwap(CI);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Instantiate default implementation.
|
||||
TEMPLATE_INSTANTIATION(class X86TargetAsmInfo<TargetAsmInfo>);
|
||||
|
@ -26,18 +26,10 @@ namespace llvm {
|
||||
|
||||
template <class BaseTAI>
|
||||
struct X86TargetAsmInfo : public BaseTAI {
|
||||
explicit X86TargetAsmInfo(const X86TargetMachine &TM):
|
||||
BaseTAI(TM) {
|
||||
const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>();
|
||||
|
||||
explicit X86TargetAsmInfo(const X86TargetMachine &TM) : BaseTAI(TM) {
|
||||
BaseTAI::AsmTransCBE = x86_asm_table;
|
||||
BaseTAI::AssemblerDialect = Subtarget->getAsmFlavor();
|
||||
BaseTAI::AssemblerDialect =TM.getSubtarget<X86Subtarget>().getAsmFlavor();
|
||||
}
|
||||
|
||||
virtual bool ExpandInlineAsm(CallInst *CI) const;
|
||||
|
||||
private:
|
||||
bool LowerToBSwap(CallInst *CI) const;
|
||||
};
|
||||
|
||||
typedef X86TargetAsmInfo<TargetAsmInfo> X86GenericTargetAsmInfo;
|
||||
|
Loading…
x
Reference in New Issue
Block a user