From: Bob Wilson Date: Tue, 19 May 2009 05:53:42 +0000 (+0000) Subject: Fix pr4091: Add support for "m" constraint in ARM inline assembly. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=224c244f56025c10e70e4204daceadfb3cdd2c06;p=oota-llvm.git Fix pr4091: Add support for "m" constraint in ARM inline assembly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72105 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 3bc5ae91467..ca3a9cb4032 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -89,6 +89,13 @@ public: // Include the pieces autogenerated from the target description. #include "ARMGenDAGISel.inc" + +private: + /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for + /// inline asm expressions. + virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, + char ConstraintCode, + std::vector &OutOps); }; } @@ -881,6 +888,21 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { return SelectCode(Op); } +bool ARMDAGToDAGISel:: +SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, + std::vector &OutOps) { + assert(ConstraintCode == 'm' && "unexpected asm memory constraint"); + + SDValue Base, Offset, Opc; + if (!SelectAddrMode2(Op, Op, Base, Offset, Opc)) + return true; + + OutOps.push_back(Base); + OutOps.push_back(Offset); + OutOps.push_back(Opc); + return false; +} + /// createARMISelDag - This pass converts a legalized DAG into a /// ARM-specific DAG, ready for instruction scheduling. /// diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp index 062423a04e6..bfe9a011719 100644 --- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp @@ -124,6 +124,9 @@ namespace { virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode); + virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, + const char *ExtraCode); void printModuleLevelGV(const GlobalVariable* GVar); bool printInstruction(const MachineInstr *MI); // autogenerated. @@ -769,6 +772,15 @@ bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, return false; } +bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, + unsigned OpNo, unsigned AsmVariant, + const char *ExtraCode) { + if (ExtraCode && ExtraCode[0]) + return true; // Unknown modifier. + printAddrMode2Operand(MI, OpNo); + return false; +} + void ARMAsmPrinter::printMachineInstruction(const MachineInstr *MI) { ++EmittedInsts; diff --git a/test/CodeGen/ARM/2009-05-18-InlineAsmMem.ll b/test/CodeGen/ARM/2009-05-18-InlineAsmMem.ll new file mode 100644 index 00000000000..f942c9fc221 --- /dev/null +++ b/test/CodeGen/ARM/2009-05-18-InlineAsmMem.ll @@ -0,0 +1,7 @@ +; RUN: llvm-as < %s | llc -march=arm | grep swp +; PR4091 + +define void @foo(i32 %i, i32* %p) nounwind { + %asmtmp = call i32 asm sideeffect "swp $0, $2, $3", "=&r,=*m,r,*m,~{memory}"(i32* %p, i32 %i, i32* %p) nounwind + ret void +}