From b0e7aeb69426dc14f77dfbe54533566fd68f9dfc Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Wed, 3 Jun 2015 12:33:56 +0000 Subject: [PATCH] [arm] Distinguish the /U[qytnms]/, 'Uv', 'Q', and 'm' inline assembly memory constraints. Summary: But still handle them the same way since I don't know how they differ on this target. Of these, /U[qytnms]/ do not have backend tests but are accepted by clang. No functional change intended. Reviewers: t.p.northover Reviewed By: t.p.northover Subscribers: t.p.northover, aemerson, llvm-commits Differential Revision: http://reviews.llvm.org/D8203 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238921 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/InlineAsm.h | 7 +++++++ lib/Target/ARM/ARMISelDAGToDAG.cpp | 26 +++++++++++++++++++------- lib/Target/ARM/ARMISelLowering.h | 27 +++++++++++++++++++++++++-- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h index 15942f16e67..08b51021116 100644 --- a/include/llvm/IR/InlineAsm.h +++ b/include/llvm/IR/InlineAsm.h @@ -248,6 +248,13 @@ public: Constraint_R, Constraint_S, Constraint_T, + Constraint_Um, + Constraint_Un, + Constraint_Uq, + Constraint_Us, + Constraint_Ut, + Constraint_Uv, + Constraint_Uy, Constraint_X, Constraint_Z, Constraint_ZC, diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 629244d9e68..0944f2c9e42 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -3920,13 +3920,25 @@ SDNode *ARMDAGToDAGISel::SelectInlineAsm(SDNode *N){ bool ARMDAGToDAGISel:: SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, std::vector &OutOps) { - assert(ConstraintID == InlineAsm::Constraint_m && - "unexpected asm memory constraint"); - // Require the address to be in a register. That is safe for all ARM - // variants and it is hard to do anything much smarter without knowing - // how the operand is used. - OutOps.push_back(Op); - return false; + switch(ConstraintID) { + default: + llvm_unreachable("Unexpected asm memory constraint"); + case InlineAsm::Constraint_m: + case InlineAsm::Constraint_Q: + case InlineAsm::Constraint_Um: + case InlineAsm::Constraint_Un: + case InlineAsm::Constraint_Uq: + case InlineAsm::Constraint_Us: + case InlineAsm::Constraint_Ut: + case InlineAsm::Constraint_Uv: + case InlineAsm::Constraint_Uy: + // Require the address to be in a register. That is safe for all ARM + // variants and it is hard to do anything much smarter without knowing + // how the operand is used. + OutOps.push_back(Op); + return false; + } + return true; } /// createARMISelDag - This pass converts a legalized DAG into a diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h index 88b36e28582..94b6ec62214 100644 --- a/lib/Target/ARM/ARMISelLowering.h +++ b/lib/Target/ARM/ARMISelLowering.h @@ -351,8 +351,31 @@ namespace llvm { unsigned getInlineAsmMemConstraint( const std::string &ConstraintCode) const override { - // FIXME: Map different constraints differently. - return InlineAsm::Constraint_m; + if (ConstraintCode == "Q") + return InlineAsm::Constraint_Q; + else if (ConstraintCode.size() == 2) { + if (ConstraintCode[0] == 'U') { + switch(ConstraintCode[1]) { + default: + break; + case 'm': + return InlineAsm::Constraint_Um; + case 'n': + return InlineAsm::Constraint_Un; + case 'q': + return InlineAsm::Constraint_Uq; + case 's': + return InlineAsm::Constraint_Us; + case 't': + return InlineAsm::Constraint_Ut; + case 'v': + return InlineAsm::Constraint_Uv; + case 'y': + return InlineAsm::Constraint_Uy; + } + } + } + return TargetLowering::getInlineAsmMemConstraint(ConstraintCode); } const ARMSubtarget* getSubtarget() const { -- 2.34.1