aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/ARM/ARMAsmPrinter.cpp12
-rw-r--r--test/CodeGen/ARM/arm-modifier.ll15
2 files changed, 27 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp
index ff8f8a8a8e..680680b240 100644
--- a/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -404,6 +404,18 @@ bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
case 'q': // Print a NEON quad precision register.
printOperand(MI, OpNum, O);
return false;
+ case 'y': // Print a VFP single precision register as indexed double.
+ // This uses the ordering of the alias table to get the first 'd' register
+ // that overlaps the 's' register. Also, s0 is an odd register, hence the
+ // odd modulus check below.
+ if (MI->getOperand(OpNum).isReg()) {
+ unsigned Reg = MI->getOperand(OpNum).getReg();
+ const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo();
+ O << ARMInstPrinter::getRegisterName(TRI->getAliasSet(Reg)[0]) <<
+ (((Reg % 2) == 1) ? "[0]" : "[1]");
+ return false;
+ }
+ // Fallthrough to unsupported.
case 'Q':
case 'R':
case 'H':
diff --git a/test/CodeGen/ARM/arm-modifier.ll b/test/CodeGen/ARM/arm-modifier.ll
new file mode 100644
index 0000000000..051d7e7780
--- /dev/null
+++ b/test/CodeGen/ARM/arm-modifier.ll
@@ -0,0 +1,15 @@
+; RUN: llc < %s -march=arm -mattr=+vfp2
+
+define i32 @foo(float %scale, float %scale2) nounwind ssp {
+entry:
+ %scale.addr = alloca float, align 4
+ %scale2.addr = alloca float, align 4
+ store float %scale, float* %scale.addr, align 4
+ store float %scale2, float* %scale2.addr, align 4
+ %tmp = load float* %scale.addr, align 4
+ %tmp1 = load float* %scale2.addr, align 4
+ call void asm sideeffect "vmul.f32 q0, q0, ${0:y} \0A\09vmul.f32 q1, q1, ${0:y} \0A\09vmul.f32 q1, q0, ${1:y} \0A\09", "w,w,~{q0},~{q1}"(float %tmp, float %tmp1) nounwind, !srcloc !0
+ ret i32 0
+}
+
+!0 = metadata !{i32 56, i32 89, i32 128, i32 168}