summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2017-04-21 17:03:48 +0000
committerdim <dim@FreeBSD.org>2017-04-21 17:03:48 +0000
commit2293bd95f40a0fe681ecb0225a94b47e488bf1d3 (patch)
tree69bf2ad25f43c3fc29d1612271a7e2152109078c
parent6f316887c2028b872e5b5ca10825c7c2737f4c7e (diff)
downloadFreeBSD-src-2293bd95f40a0fe681ecb0225a94b47e488bf1d3.zip
FreeBSD-src-2293bd95f40a0fe681ecb0225a94b47e488bf1d3.tar.gz
MFC r316989:
Pull in r300404 from upstream llvm trunk (by me): Use correct registers for "A" inline asm constraint Summary: In PR32594, inline assembly using the 'A' constraint on x86_64 causes llvm to crash with a "Cannot select" stack trace. This is because `X86TargetLowering::getRegForInlineAsmConstraint` hardcodes that 'A' means the EAX and EDX registers. However, on x86_64 it means the RAX and RDX registers, and on 16-bit x86 (ia16?) it means the old AX and DX registers. Add new register classes in `X86RegisterInfo.td` to support these cases, and amend the logic in `getRegForInlineAsmConstraint` to cope with different subtargets. Also add a test case, derived from PR32594. Reviewers: craig.topper, qcolombet, RKSimon, ab Reviewed By: ab Subscribers: ab, emaste, royger, llvm-commits Differential Revision: https://reviews.llvm.org/D31902 This should fix crashes when using the 'A' constraint on amd64, for example as it is being used in Xen. Reported by: royger MFC r317079: Pull in r300429 from upstream llvm trunk (by Benjamin Kramer): [X86] Remove special handling for 16 bit for A asm constraints. Our 16 bit support is assembler-only + the terrible hack that is .code16gcc. Simply using 32 bit registers does the right thing for the latter. Fixes PR32681. This fixes some cases of assembling 16 bit code (i.e. SeaBIOS) that uses the 'A' inline asm constraint, after r316989.
-rw-r--r--contrib/llvm/lib/Target/X86/X86ISelLowering.cpp13
-rw-r--r--contrib/llvm/lib/Target/X86/X86RegisterInfo.td3
2 files changed, 12 insertions, 4 deletions
diff --git a/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp b/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp
index 08fe2ba..de6c9a6 100644
--- a/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -34717,10 +34717,17 @@ X86TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
return Res;
}
- // 'A' means EAX + EDX.
+ // 'A' means [ER]AX + [ER]DX.
if (Constraint == "A") {
- Res.first = X86::EAX;
- Res.second = &X86::GR32_ADRegClass;
+ if (Subtarget.is64Bit()) {
+ Res.first = X86::RAX;
+ Res.second = &X86::GR64_ADRegClass;
+ } else {
+ assert((Subtarget.is32Bit() || Subtarget.is16Bit()) &&
+ "Expecting 64, 32 or 16 bit subtarget");
+ Res.first = X86::EAX;
+ Res.second = &X86::GR32_ADRegClass;
+ }
return Res;
}
return Res;
diff --git a/contrib/llvm/lib/Target/X86/X86RegisterInfo.td b/contrib/llvm/lib/Target/X86/X86RegisterInfo.td
index 372a15a..ad02a94 100644
--- a/contrib/llvm/lib/Target/X86/X86RegisterInfo.td
+++ b/contrib/llvm/lib/Target/X86/X86RegisterInfo.td
@@ -437,8 +437,9 @@ def LOW32_ADDR_ACCESS : RegisterClass<"X86", [i32], 32, (add GR32, RIP)>;
def LOW32_ADDR_ACCESS_RBP : RegisterClass<"X86", [i32], 32,
(add LOW32_ADDR_ACCESS, RBP)>;
-// A class to support the 'A' assembler constraint: EAX then EDX.
+// A class to support the 'A' assembler constraint: [ER]AX then [ER]DX.
def GR32_AD : RegisterClass<"X86", [i32], 32, (add EAX, EDX)>;
+def GR64_AD : RegisterClass<"X86", [i64], 64, (add RAX, RDX)>;
// Scalar SSE2 floating point registers.
def FR32 : RegisterClass<"X86", [f32], 32, (sequence "XMM%u", 0, 15)>;
OpenPOWER on IntegriCloud