OSDN Git Service

AArch64: allow vN to represent 64-bit registers in inline asm.
authorTim Northover <tnorthover@apple.com>
Tue, 10 May 2016 22:26:45 +0000 (22:26 +0000)
committerTim Northover <tnorthover@apple.com>
Tue, 10 May 2016 22:26:45 +0000 (22:26 +0000)
Unlike xN/wN, the size of vN is genuinely ambiguous in the assembly, so we
should try to infer what was intended from the type. But only down to 64-bits
(vN can never represent sN, hN or bN).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269132 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64ISelLowering.cpp
test/CodeGen/AArch64/arm64-inline-asm.ll

index 5b4516b..8468a83 100644 (file)
@@ -4802,11 +4802,16 @@ AArch64TargetLowering::getRegForInlineAsmConstraint(
       int RegNo;
       bool Failed = Constraint.slice(2, Size - 1).getAsInteger(10, RegNo);
       if (!Failed && RegNo >= 0 && RegNo <= 31) {
-        // v0 - v31 are aliases of q0 - q31.
+        // v0 - v31 are aliases of q0 - q31 or d0 - d31 depending on size.
         // By default we'll emit v0-v31 for this unless there's a modifier where
         // we'll emit the correct register as well.
-        Res.first = AArch64::FPR128RegClass.getRegister(RegNo);
-        Res.second = &AArch64::FPR128RegClass;
+        if (VT != MVT::Other && VT.getSizeInBits() == 64) {
+          Res.first = AArch64::FPR64RegClass.getRegister(RegNo);
+          Res.second = &AArch64::FPR64RegClass;
+        } else {
+          Res.first = AArch64::FPR128RegClass.getRegister(RegNo);
+          Res.second = &AArch64::FPR128RegClass;
+        }
       }
     }
   }
index cd87f55..4d4adb1 100644 (file)
@@ -232,3 +232,17 @@ define void @test_zero_reg(i32* %addr) {
 
   ret void
 }
+
+define <2 x float> @test_vreg_64bit(<2 x float> %in) nounwind {
+  ; CHECK-LABEL: test_vreg_64bit:
+  %1 = tail call <2 x float> asm sideeffect "fadd ${0}.2s, ${1}.2s, ${1}.2s", "={v14},w"(<2 x float> %in) nounwind
+  ; CHECK fadd v14.2s, v0.2s, v0.2s:
+  ret <2 x float> %1
+}
+
+define <4 x float> @test_vreg_128bit(<4 x float> %in) nounwind {
+  ; CHECK-LABEL: test_vreg_128bit:
+  %1 = tail call <4 x float> asm sideeffect "fadd ${0}.4s, ${1}.4s, ${1}.4s", "={v14},w"(<4 x float> %in) nounwind
+  ; CHECK fadd v14.4s, v0.4s, v0.4s:
+  ret <4 x float> %1
+}