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.

llvm-svn: 188990
This commit is contained in:
Tim Northover 2013-08-22 06:51:04 +00:00
parent e5ccfcac27
commit 7e34f41ef8
2 changed files with 27 additions and 0 deletions

View File

@ -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);

View File

@ -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
}