Implement 'e' and 'f' modifiers for Neon inline asm. <rdar://problem/10551006>

These modifiers simply select either the low or high D subregister of a Neon
Q register.  I've also removed the unimplemented 'p' modifier, which turns out
to be a bit different than the comment here suggests and as far as I can tell
was only intended for internal use in Apple's version of gcc.

llvm-svn: 146417
This commit is contained in:
Bob Wilson 2011-12-12 21:45:15 +00:00
parent 0586df4a00
commit fadc2c83e5
2 changed files with 24 additions and 4 deletions

View File

@ -493,11 +493,21 @@ bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
return false;
}
// These modifiers are not yet supported.
case 'p': // The high single-precision register of a VFP double-precision
// register.
case 'e': // The low doubleword register of a NEON quad register.
case 'f': // The high doubleword register of a NEON quad register.
case 'f': { // The high doubleword register of a NEON quad register.
if (!MI->getOperand(OpNum).isReg())
return true;
unsigned Reg = MI->getOperand(OpNum).getReg();
if (!ARM::QPRRegClass.contains(Reg))
return true;
const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo();
unsigned SubReg = TRI->getSubReg(Reg, ExtraCode[0] == 'e' ?
ARM::dsub_0 : ARM::dsub_1);
O << ARMInstPrinter::getRegisterName(SubReg);
return false;
}
// These modifiers are not yet supported.
case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1.
case 'H': // The highest-numbered register of a pair.
return true;

View File

@ -110,3 +110,13 @@ entry:
call void asm "str $1, $0", "=*Q,r"(i8** %f.addr, i32 %g) nounwind
ret void
}
; Radar 10551006
define <4 x i32> @t11(i32* %p) nounwind {
entry:
; CHECK: t11
; CHECK: vld1.s32 {d16[], d17[]}, [r0]
%0 = tail call <4 x i32> asm "vld1.s32 {${0:e}[], ${0:f}[]}, [$1]", "=w,r"(i32* %p) nounwind
ret <4 x i32> %0
}