start setting up infrastructure for passing multi-floats

as <2 x float> instead of as double.  The backend isn't ready
yet, but infrastructure in the frontend can come up.

llvm-svn: 109768
This commit is contained in:
Chris Lattner 2010-07-29 17:49:08 +00:00
parent a3e0ddb564
commit c95a398947
1 changed files with 33 additions and 15 deletions

View File

@ -718,7 +718,8 @@ class X86_64ABIInfo : public ABIInfo {
void classify(QualType T, uint64_t OffsetBase, Class &Lo, Class &Hi) const; void classify(QualType T, uint64_t OffsetBase, Class &Lo, Class &Hi) const;
const llvm::Type *Get16ByteVectorType(QualType Ty) const; const llvm::Type *Get16ByteVectorType(QualType Ty) const;
const llvm::Type *GetSSETypeAtOffset(const llvm::Type *IRType,
unsigned IROffset) const;
const llvm::Type *GetINTEGERTypeAtOffset(const llvm::Type *IRType, const llvm::Type *GetINTEGERTypeAtOffset(const llvm::Type *IRType,
unsigned IROffset, QualType SourceTy, unsigned IROffset, QualType SourceTy,
unsigned SourceOffset) const; unsigned SourceOffset) const;
@ -1211,6 +1212,20 @@ const llvm::Type *X86_64ABIInfo::Get16ByteVectorType(QualType Ty) const {
} }
/// GetSSETypeAtOffset - Return a type that will be passed by the backend in the
/// low 8 bytes of an XMM register, corresponding to the SSE class.
const llvm::Type *X86_64ABIInfo::GetSSETypeAtOffset(const llvm::Type *IRType,
unsigned IROffset) const {
// The only two choices we have are either double or <2 x float>.
// FIXME: <2 x float> doesn't pass as one XMM register yet. Don't enable this
// code until it does.
return llvm::Type::getDoubleTy(getVMContext());
}
/// BitsContainNoUserData - Return true if the specified [start,end) bit range /// BitsContainNoUserData - Return true if the specified [start,end) bit range
/// is known to either be off the end of the specified type or being in /// is known to either be off the end of the specified type or being in
/// alignment padding. The user type specified is known to be at most 128 bits /// alignment padding. The user type specified is known to be at most 128 bits
@ -1405,7 +1420,7 @@ classifyReturnType(QualType RetTy) const {
// AMD64-ABI 3.2.3p4: Rule 4. If the class is SSE, the next // AMD64-ABI 3.2.3p4: Rule 4. If the class is SSE, the next
// available SSE register of the sequence %xmm0, %xmm1 is used. // available SSE register of the sequence %xmm0, %xmm1 is used.
case SSE: case SSE:
ResType = llvm::Type::getDoubleTy(getVMContext()); ResType = GetSSETypeAtOffset(CGT.ConvertTypeRecursive(RetTy), 0);
break; break;
// AMD64-ABI 3.2.3p4: Rule 6. If the class is X87, the value is // AMD64-ABI 3.2.3p4: Rule 6. If the class is X87, the value is
@ -1443,11 +1458,12 @@ classifyReturnType(QualType RetTy) const {
ResType = llvm::StructType::get(getVMContext(), ResType, HiType, NULL); ResType = llvm::StructType::get(getVMContext(), ResType, HiType, NULL);
break; break;
} }
case SSE: case SSE: {
ResType = llvm::StructType::get(getVMContext(), ResType, const llvm::Type *HiType =
llvm::Type::getDoubleTy(getVMContext()), GetSSETypeAtOffset(CGT.ConvertTypeRecursive(RetTy), 8);
NULL); ResType = llvm::StructType::get(getVMContext(), ResType, HiType,NULL);
break; break;
}
// AMD64-ABI 3.2.3p4: Rule 5. If the class is SSEUP, the eightbyte // AMD64-ABI 3.2.3p4: Rule 5. If the class is SSEUP, the eightbyte
// is passed in the upper half of the last used SSE register. // is passed in the upper half of the last used SSE register.
@ -1465,10 +1481,11 @@ classifyReturnType(QualType RetTy) const {
// anything. However, in some cases with unions it may not be // anything. However, in some cases with unions it may not be
// preceeded by X87. In such situations we follow gcc and pass the // preceeded by X87. In such situations we follow gcc and pass the
// extra bits in an SSE reg. // extra bits in an SSE reg.
if (Lo != X87) if (Lo != X87) {
ResType = llvm::StructType::get(getVMContext(), ResType, const llvm::Type *HiType =
llvm::Type::getDoubleTy(getVMContext()), GetSSETypeAtOffset(CGT.ConvertTypeRecursive(RetTy), 8);
NULL); ResType = llvm::StructType::get(getVMContext(), ResType, HiType, NULL);
}
break; break;
} }
@ -1522,7 +1539,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned &neededInt,
// order from %xmm0 to %xmm7. // order from %xmm0 to %xmm7.
case SSE: case SSE:
++neededSSE; ++neededSSE;
ResType = llvm::Type::getDoubleTy(getVMContext()); ResType = GetSSETypeAtOffset(CGT.ConvertTypeRecursive(Ty), 0);
break; break;
} }
@ -1550,12 +1567,13 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned &neededInt,
// X87Up generally doesn't occur here (long double is passed in // X87Up generally doesn't occur here (long double is passed in
// memory), except in situations involving unions. // memory), except in situations involving unions.
case X87Up: case X87Up:
case SSE: case SSE: {
ResType = llvm::StructType::get(getVMContext(), ResType, const llvm::Type *HiType =
llvm::Type::getDoubleTy(getVMContext()), GetSSETypeAtOffset(CGT.ConvertTypeRecursive(Ty), 8);
NULL); ResType = llvm::StructType::get(getVMContext(), ResType, HiType, NULL);
++neededSSE; ++neededSSE;
break; break;
}
// AMD64-ABI 3.2.3p3: Rule 4. If the class is SSEUP, the // AMD64-ABI 3.2.3p3: Rule 4. If the class is SSEUP, the
// eightbyte is passed in the upper half of the last used SSE // eightbyte is passed in the upper half of the last used SSE