Skip to content

Commit

Permalink
Fix "Q" and "R" inline assembly template modifiers for big-endian Arm
Browse files Browse the repository at this point in the history
Consider the endianness of the target when printing register names.  This is in line with the documentation at http://llvm.org/docs/LangRef.html#asm-template-argument-modifiers

Patch by Jackson Woodruff <jackson.woodruff@arm.com>

Reviewers: t.p.northover, echristo, javed.absar, efriedma

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D49778

llvm-svn: 341052
  • Loading branch information
fhahn committed Aug 30, 2018
1 parent ec9b386 commit 521dc4d
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
16 changes: 14 additions & 2 deletions llvm/lib/Target/ARM/ARMAsmPrinter.cpp
Expand Up @@ -367,6 +367,18 @@ bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,

unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
unsigned RC;
bool FirstHalf;
const ARMBaseTargetMachine &ATM =
static_cast<const ARMBaseTargetMachine &>(TM);

// 'Q' should correspond to the low order register and 'R' to the high
// order register. Whether this corresponds to the upper or lower half
// depends on the endianess mode.
if (ExtraCode[0] == 'Q')
FirstHalf = ATM.isLittleEndian();
else
// ExtraCode[0] == 'R'.
FirstHalf = !ATM.isLittleEndian();
const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
if (InlineAsm::hasRegClassConstraint(Flags, RC) &&
ARM::GPRPairRegClass.hasSubClassEq(TRI->getRegClass(RC))) {
Expand All @@ -376,14 +388,14 @@ bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
if (!MO.isReg())
return true;
const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
unsigned Reg = TRI->getSubReg(MO.getReg(), ExtraCode[0] == 'Q' ?
unsigned Reg = TRI->getSubReg(MO.getReg(), FirstHalf ?
ARM::gsub_0 : ARM::gsub_1);
O << ARMInstPrinter::getRegisterName(Reg);
return false;
}
if (NumVals != 2)
return true;
unsigned RegOp = ExtraCode[0] == 'Q' ? OpNum : OpNum + 1;
unsigned RegOp = FirstHalf ? OpNum : OpNum + 1;
if (RegOp >= MI->getNumOperands())
return true;
const MachineOperand &MO = MI->getOperand(RegOp);
Expand Down
10 changes: 10 additions & 0 deletions llvm/test/CodeGen/ARM/print-registers.ll
@@ -0,0 +1,10 @@
; RUN: llc -mtriple=armeb-arm-none-eabi < %s -o -| FileCheck %s -check-prefixes=CHECK-BE
; RUN: llc -mtriple=arm-arm-none-eabi < %s -o -| FileCheck %s -check-prefixes=CHECK-LE

define dso_local void @_Z3fooi(i32 %a) local_unnamed_addr #0 {
entry:
; CHECK-BE: @ plain: [[LOW_REG:r[0-9]+]] Q: [[HIGH_REG:r[0-9]+]] R: [[LOW_REG]] H: [[HIGH_REG]]
; CHECK-LE: @ plain: [[LOW_REG:r[0-9]+]] Q: [[LOW_REG]] R: [[HIGH_REG:r[0-9]+]] H: [[HIGH_REG]]
tail call void asm sideeffect "// plain: $0 Q: ${0:Q} R: ${0:R} H: ${0:H}", "r"(i64 1) #1
ret void
}

0 comments on commit 521dc4d

Please sign in to comment.