|
@@ -915,14 +915,6 @@ ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const {
|
|
|
: ABIArgInfo::getDirect());
|
|
|
}
|
|
|
|
|
|
-/// IsX86_MMXType - Return true if this is an MMX type.
|
|
|
-bool IsX86_MMXType(llvm::Type *IRType) {
|
|
|
- // Return true if the type is an MMX type <2 x i32>, <4 x i16>, or <8 x i8>.
|
|
|
- return IRType->isVectorTy() && IRType->getPrimitiveSizeInBits() == 64 &&
|
|
|
- cast<llvm::VectorType>(IRType)->getElementType()->isIntegerTy() &&
|
|
|
- IRType->getScalarSizeInBits() != 64;
|
|
|
-}
|
|
|
-
|
|
|
static llvm::Type* X86AdjustInlineAsmType(CodeGen::CodeGenFunction &CGF,
|
|
|
StringRef Constraint,
|
|
|
llvm::Type* Ty) {
|
|
@@ -1011,6 +1003,7 @@ class X86_32ABIInfo : public SwiftABIInfo {
|
|
|
bool IsSoftFloatABI;
|
|
|
bool IsMCUABI;
|
|
|
unsigned DefaultNumRegisterParameters;
|
|
|
+ bool IsMMXEnabled;
|
|
|
|
|
|
static bool isRegisterSize(unsigned Size) {
|
|
|
return (Size == 8 || Size == 16 || Size == 32 || Size == 64);
|
|
@@ -1070,13 +1063,15 @@ public:
|
|
|
|
|
|
X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool DarwinVectorABI,
|
|
|
bool RetSmallStructInRegABI, bool Win32StructABI,
|
|
|
- unsigned NumRegisterParameters, bool SoftFloatABI)
|
|
|
+ unsigned NumRegisterParameters, bool SoftFloatABI,
|
|
|
+ bool MMXEnabled)
|
|
|
: SwiftABIInfo(CGT), IsDarwinVectorABI(DarwinVectorABI),
|
|
|
IsRetSmallStructInRegABI(RetSmallStructInRegABI),
|
|
|
IsWin32StructABI(Win32StructABI),
|
|
|
IsSoftFloatABI(SoftFloatABI),
|
|
|
IsMCUABI(CGT.getTarget().getTriple().isOSIAMCU()),
|
|
|
- DefaultNumRegisterParameters(NumRegisterParameters) {}
|
|
|
+ DefaultNumRegisterParameters(NumRegisterParameters),
|
|
|
+ IsMMXEnabled(MMXEnabled) {}
|
|
|
|
|
|
bool shouldPassIndirectlyForSwift(ArrayRef<llvm::Type*> scalars,
|
|
|
bool asReturnValue) const override {
|
|
@@ -1091,16 +1086,30 @@ public:
|
|
|
// x86-32 lowering does not support passing swifterror in a register.
|
|
|
return false;
|
|
|
}
|
|
|
+
|
|
|
+ bool isPassInMMXRegABI() const {
|
|
|
+ // The System V i386 psABI requires __m64 to be passed in MMX registers.
|
|
|
+ // Clang historically had a bug where it failed to apply this rule, and
|
|
|
+ // some platforms (e.g. Darwin, PS4, and FreeBSD) have opted to maintain
|
|
|
+ // compatibility with the old Clang behavior, so we only apply it on
|
|
|
+ // platforms that have specifically requested it (currently just Linux and
|
|
|
+ // NetBSD).
|
|
|
+ const llvm::Triple &T = getTarget().getTriple();
|
|
|
+ if (IsMMXEnabled && (T.isOSLinux() || T.isOSNetBSD()))
|
|
|
+ return true;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
class X86_32TargetCodeGenInfo : public TargetCodeGenInfo {
|
|
|
public:
|
|
|
X86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool DarwinVectorABI,
|
|
|
bool RetSmallStructInRegABI, bool Win32StructABI,
|
|
|
- unsigned NumRegisterParameters, bool SoftFloatABI)
|
|
|
+ unsigned NumRegisterParameters, bool SoftFloatABI,
|
|
|
+ bool MMXEnabled = false)
|
|
|
: TargetCodeGenInfo(new X86_32ABIInfo(
|
|
|
CGT, DarwinVectorABI, RetSmallStructInRegABI, Win32StructABI,
|
|
|
- NumRegisterParameters, SoftFloatABI)) {}
|
|
|
+ NumRegisterParameters, SoftFloatABI, MMXEnabled)) {}
|
|
|
|
|
|
static bool isStructReturnInRegABI(
|
|
|
const llvm::Triple &Triple, const CodeGenOptions &Opts);
|
|
@@ -1386,10 +1395,9 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
|
|
|
}
|
|
|
|
|
|
if (const VectorType *VT = RetTy->getAs<VectorType>()) {
|
|
|
+ uint64_t Size = getContext().getTypeSize(RetTy);
|
|
|
// On Darwin, some vectors are returned in registers.
|
|
|
if (IsDarwinVectorABI) {
|
|
|
- uint64_t Size = getContext().getTypeSize(RetTy);
|
|
|
-
|
|
|
// 128-bit vectors are a special case; they are returned in
|
|
|
// registers and we need to make sure to pick a type the LLVM
|
|
|
// backend will like.
|
|
@@ -1407,6 +1415,10 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
|
|
|
return getIndirectReturnResult(RetTy, State);
|
|
|
}
|
|
|
|
|
|
+ if (VT->getElementType()->isIntegerType() && Size == 64 &&
|
|
|
+ isPassInMMXRegABI())
|
|
|
+ return ABIArgInfo::getDirect(llvm::Type::getX86_MMXTy(getVMContext()));
|
|
|
+
|
|
|
return ABIArgInfo::getDirect();
|
|
|
}
|
|
|
|
|
@@ -1701,23 +1713,26 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
|
|
|
}
|
|
|
|
|
|
if (const VectorType *VT = Ty->getAs<VectorType>()) {
|
|
|
+ uint64_t Size = getContext().getTypeSize(Ty);
|
|
|
// On Darwin, some vectors are passed in memory, we handle this by passing
|
|
|
// it as an i8/i16/i32/i64.
|
|
|
if (IsDarwinVectorABI) {
|
|
|
- uint64_t Size = getContext().getTypeSize(Ty);
|
|
|
if ((Size == 8 || Size == 16 || Size == 32) ||
|
|
|
(Size == 64 && VT->getNumElements() == 1))
|
|
|
return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
|
|
|
Size));
|
|
|
}
|
|
|
|
|
|
- if (IsX86_MMXType(CGT.ConvertType(Ty)))
|
|
|
- return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), 64));
|
|
|
-
|
|
|
+ if (VT->getElementType()->isIntegerType() && Size == 64) {
|
|
|
+ if (isPassInMMXRegABI())
|
|
|
+ return ABIArgInfo::getDirect(llvm::Type::getX86_MMXTy(getVMContext()));
|
|
|
+ else
|
|
|
+ return ABIArgInfo::getDirect(
|
|
|
+ llvm::IntegerType::get(getVMContext(), 64));
|
|
|
+ }
|
|
|
return ABIArgInfo::getDirect();
|
|
|
}
|
|
|
|
|
|
-
|
|
|
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
|
|
|
Ty = EnumTy->getDecl()->getIntegerType();
|
|
|
|
|
@@ -9460,10 +9475,11 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
|
|
|
Types, IsDarwinVectorABI, RetSmallStructInRegABI,
|
|
|
IsWin32FloatStructABI, CodeGenOpts.NumRegisterParameters));
|
|
|
} else {
|
|
|
+ bool EnableMMX = getContext().getTargetInfo().getABI() != "no-mmx";
|
|
|
return SetCGInfo(new X86_32TargetCodeGenInfo(
|
|
|
Types, IsDarwinVectorABI, RetSmallStructInRegABI,
|
|
|
IsWin32FloatStructABI, CodeGenOpts.NumRegisterParameters,
|
|
|
- CodeGenOpts.FloatABI == "soft"));
|
|
|
+ CodeGenOpts.FloatABI == "soft", EnableMMX));
|
|
|
}
|
|
|
}
|
|
|
|