aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/TargetInfo.cpp
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2010-10-17 07:38:01 +0000
committerBill Wendling <isanbard@gmail.com>2010-10-17 07:38:01 +0000
commit51a9f5309a025f5c54e7dc373eb7d11daabee6df (patch)
tree07422e47d709251ec8566b95234e0426eaf40d0f /lib/CodeGen/TargetInfo.cpp
parenta7d2f19e6b77330e27f03a446093700df74b652d (diff)
The "gcc.dg/compat/vector-1 -m32" test was broken after the MMX rewrite. The
function parameters weren't converted to use the correct type (x86_mmx). Add a check, similar to the one in llvm-gcc, to see if we need the x86_mmx type for that function parameter. If so, it coerces the type to be that. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116684 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/TargetInfo.cpp')
-rw-r--r--lib/CodeGen/TargetInfo.cpp59
1 files changed, 47 insertions, 12 deletions
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 38c746068d..c28f71a304 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -331,6 +331,16 @@ ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const {
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
}
+/// UseX86_MMXType - Return true if this is an MMX type that should use the special
+/// x86_mmx type.
+bool UseX86_MMXType(const llvm::Type *IRType) {
+ // If the type is an MMX type <2 x i32>, <4 x i16>, or <8 x i8>, use the
+ // special x86_mmx type.
+ return IRType->isVectorTy() && IRType->getPrimitiveSizeInBits() == 64 &&
+ cast<llvm::VectorType>(IRType)->getElementType()->isIntegerTy() &&
+ IRType->getScalarSizeInBits() != 64;
+}
+
//===----------------------------------------------------------------------===//
// X86-32 ABI Implementation
//===----------------------------------------------------------------------===//
@@ -658,6 +668,13 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty) const {
return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
Size));
}
+
+ const llvm::Type *IRType = CGT.ConvertTypeRecursive(Ty);
+ if (UseX86_MMXType(IRType)) {
+ ABIArgInfo AAI = ABIArgInfo::getDirect(IRType);
+ AAI.setCoerceToType(llvm::Type::getX86_MMXTy(getVMContext()));
+ return AAI;
+ }
return ABIArgInfo::getDirect();
}
@@ -814,8 +831,10 @@ class X86_64ABIInfo : public ABIInfo {
ABIArgInfo classifyReturnType(QualType RetTy) const;
- ABIArgInfo classifyArgumentType(QualType Ty, unsigned &neededInt,
- unsigned &neededSSE) const;
+ ABIArgInfo classifyArgumentType(QualType Ty,
+ unsigned &neededInt,
+ unsigned &neededSSE,
+ unsigned &neededMMX) const;
public:
X86_64ABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}
@@ -1662,7 +1681,8 @@ classifyReturnType(QualType RetTy) const {
}
ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned &neededInt,
- unsigned &neededSSE) const {
+ unsigned &neededSSE,
+ unsigned &neededMMX) const {
X86_64ABIInfo::Class Lo, Hi;
classify(Ty, 0, Lo, Hi);
@@ -1673,6 +1693,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned &neededInt,
neededInt = 0;
neededSSE = 0;
+ neededMMX = 0;
const llvm::Type *ResType = 0;
switch (Lo) {
case NoClass:
@@ -1724,11 +1745,20 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned &neededInt,
// AMD64-ABI 3.2.3p3: Rule 3. If the class is SSE, the next
// available SSE register is used, the registers are taken in the
// order from %xmm0 to %xmm7.
- case SSE:
- ++neededSSE;
- ResType = GetSSETypeAtOffset(CGT.ConvertTypeRecursive(Ty), 0, Ty, 0);
+ case SSE: {
+ const llvm::Type *IRType = CGT.ConvertTypeRecursive(Ty);
+ if (Hi != NoClass || !UseX86_MMXType(IRType)) {
+ ResType = GetSSETypeAtOffset(IRType, 0, Ty, 0);
+ ++neededSSE;
+ } else {
+ // This is an MMX type. Treat it as such.
+ ResType = llvm::Type::getX86_MMXTy(getVMContext());
+ ++neededMMX;
+ }
+
break;
}
+ }
const llvm::Type *HighPart = 0;
switch (Hi) {
@@ -1787,7 +1817,7 @@ void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
// Keep track of the number of assigned registers.
- unsigned freeIntRegs = 6, freeSSERegs = 8;
+ unsigned freeIntRegs = 6, freeSSERegs = 8, freeMMXRegs = 8;
// If the return value is indirect, then the hidden argument is consuming one
// integer register.
@@ -1798,16 +1828,18 @@ void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
// get assigned (in left-to-right order) for passing as follows...
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
it != ie; ++it) {
- unsigned neededInt, neededSSE;
- it->info = classifyArgumentType(it->type, neededInt, neededSSE);
+ unsigned neededInt, neededSSE, neededMMX;
+ it->info = classifyArgumentType(it->type, neededInt, neededSSE, neededMMX);
// AMD64-ABI 3.2.3p3: If there are no registers available for any
// eightbyte of an argument, the whole argument is passed on the
// stack. If registers have already been assigned for some
// eightbytes of such an argument, the assignments get reverted.
- if (freeIntRegs >= neededInt && freeSSERegs >= neededSSE) {
+ if (freeIntRegs >= neededInt && freeSSERegs >= neededSSE &&
+ freeMMXRegs >= neededMMX) {
freeIntRegs -= neededInt;
freeSSERegs -= neededSSE;
+ freeMMXRegs -= neededMMX;
} else {
it->info = getIndirectResult(it->type);
}
@@ -1876,10 +1908,13 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
// i8* overflow_arg_area;
// i8* reg_save_area;
// };
- unsigned neededInt, neededSSE;
+ unsigned neededInt, neededSSE, neededMMX;
Ty = CGF.getContext().getCanonicalType(Ty);
- ABIArgInfo AI = classifyArgumentType(Ty, neededInt, neededSSE);
+ ABIArgInfo AI = classifyArgumentType(Ty, neededInt, neededSSE, neededMMX);
+
+ // Lump the MMX in with SSE.
+ neededSSE += neededMMX;
// AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed
// in the registers. If not go to step 7.