From bccc6f89b7a15abda5593a30c101ae85d1dc3b77 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Thu, 22 Aug 2013 06:51:04 +0000 Subject: [PATCH] ARM: respect tied 64-bit inlineasm operands when printing The code for 'Q' and 'R' operand modifiers needs to look through tied operands to discover the register class. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188990 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMAsmPrinter.cpp | 17 +++++++++++++++++ test/CodeGen/ARM/inlineasm-64bit.ll | 10 ++++++++++ 2 files changed, 27 insertions(+) diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 13a22b1c3fb..485b1c55006 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -496,6 +496,23 @@ bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, if (!FlagsOP.isImm()) return true; unsigned Flags = FlagsOP.getImm(); + + // This operand may not be the one that actually provides the register. If + // it's tied to a previous one then we should refer instead to that one + // for registers and their classes. + unsigned TiedIdx; + if (InlineAsm::isUseOperandTiedToDef(Flags, TiedIdx)) { + for (OpNum = InlineAsm::MIOp_FirstOperand; TiedIdx; --TiedIdx) { + unsigned OpFlags = MI->getOperand(OpNum).getImm(); + OpNum += InlineAsm::getNumOperandRegisters(OpFlags) + 1; + } + Flags = MI->getOperand(OpNum).getImm(); + + // Later code expects OpNum to be pointing at the register rather than + // the flags. + OpNum += 1; + } + unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); unsigned RC; InlineAsm::hasRegClassConstraint(Flags, RC); diff --git a/test/CodeGen/ARM/inlineasm-64bit.ll b/test/CodeGen/ARM/inlineasm-64bit.ll index 69b3860305f..683a0c4b7d3 100644 --- a/test/CodeGen/ARM/inlineasm-64bit.ll +++ b/test/CodeGen/ARM/inlineasm-64bit.ll @@ -94,3 +94,13 @@ define i64 @tied_64bit_test(i64 %in) nounwind { call void asm "OUT($0), IN($1)", "=*rm,0"(i64* %addr, i64 %in) ret i64 %in } + +; If we explicitly name a tied operand, then the code should lookup the operand +; we were tied to for information about register class and so on. +define i64 @tied_64bit_lookback_test(i64 %in) nounwind { +; CHECK-LABEL: tied_64bit_lookback_test: +; CHECK: OUTLO([[LO:r[0-9]+]]) OUTHI([[HI:r[0-9]+]]) INLO([[LO]]) INHI([[HI]]) + %vars = call {i64, i32, i64} asm "OUTLO(${2:Q}) OUTHI(${2:R}) INLO(${3:Q}) INHI(${3:R})", "=r,=r,=r,2"(i64 %in) + %res = extractvalue {i64, i32, i64} %vars, 2 + ret i64 %res +} -- 2.34.1