[cfe-commits] r62915 - /cfe/trunk/lib/CodeGen/CGCall.cpp
Daniel Dunbar
daniel at zuster.org
Sat Jan 24 00:32:22 PST 2009
Author: ddunbar
Date: Sat Jan 24 02:32:22 2009
New Revision: 62915
URL: http://llvm.org/viewvc/llvm-project?rev=62915&view=rev
Log:
Start filling in x86_64 ABI implementation.
- No functionality change, moved behind -use-x86_64-abi option until
it becomes non-experimental.
Modified:
cfe/trunk/lib/CodeGen/CGCall.cpp
Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=62915&r1=62914&r2=62915&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Sat Jan 24 02:32:22 2009
@@ -21,9 +21,15 @@
#include "clang/AST/DeclObjC.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Attributes.h"
+#include "llvm/Support/CommandLine.h"
using namespace clang;
using namespace CodeGen;
+static llvm::cl::opt<bool>
+UseX86_64ABI("use-x86_64-abi",
+ llvm::cl::desc("Enable use of experimental x86_64 ABI."),
+ llvm::cl::init(false));
+
/***/
// FIXME: Use iterator and sidestep silly type array creation.
@@ -303,17 +309,6 @@
virtual ABIArgInfo classifyArgumentType(QualType RetTy,
ASTContext &Context) const;
};
-
-
-/// X86_32ABIInfo - The X86_64 ABI information.
-class X86_64ABIInfo : public ABIInfo {
-public:
- virtual ABIArgInfo classifyReturnType(QualType RetTy,
- ASTContext &Context) const;
-
- virtual ABIArgInfo classifyArgumentType(QualType RetTy,
- ASTContext &Context) const;
-};
}
ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
@@ -389,9 +384,159 @@
}
}
+namespace {
+/// X86_32ABIInfo - The X86_64 ABI information.
+class X86_64ABIInfo : public ABIInfo {
+ enum Class {
+ Integer = 0,
+ SSE,
+ SSEUp,
+ X87,
+ X87Up,
+ ComplexX87,
+ NoClass,
+ Memory
+ };
+
+ /// classify - Determine the x86_64 register classes in which the
+ /// given type T should be passed.
+ ///
+ /// \param Lo - The classification for the low word of the type.
+ /// \param Hi - The classification for the high word of the type.
+ ///
+ /// If a word is unused its result will be NoClass; if a type should
+ /// be passed in Memory then at least the classification of \arg Lo
+ /// will be Memory.
+ ///
+ /// The \arg Lo class will be NoClass iff the argument is ignored.
+ ///
+ /// If the \arg Lo class is ComplexX87, then the \arg Hi class will
+ /// be NoClass.
+ void classify(QualType T, ASTContext &Context,
+ Class &Lo, Class &Hi) const;
+
+public:
+ virtual ABIArgInfo classifyReturnType(QualType RetTy,
+ ASTContext &Context) const;
+
+ virtual ABIArgInfo classifyArgumentType(QualType RetTy,
+ ASTContext &Context) const;
+};
+}
+
+void X86_64ABIInfo::classify(QualType Ty,
+ ASTContext &Context,
+ Class &Lo, Class &Hi) const {
+ Lo = Memory;
+ Hi = NoClass;
+ if (const BuiltinType *BT = Ty->getAsBuiltinType()) {
+ BuiltinType::Kind k = BT->getKind();
+
+ if (k >= BuiltinType::Bool && k <= BuiltinType::LongLong) {
+ Lo = Integer;
+ } else if (k == BuiltinType::Float || k == BuiltinType::Double) {
+ Lo = SSE;
+ } else if (k == BuiltinType::LongDouble) {
+ Lo = X87;
+ Hi = X87Up;
+ }
+ // FIXME: _Decimal32, _Decimal64, and __m64 are SSE.
+ // FIXME: _float128, _Decimal128, and __m128 are (SSE, SSEUp).
+ // FIXME: __int128 is (Integer, Integer).
+ } else if (Ty->isPointerLikeType() || Ty->isBlockPointerType() ||
+ Ty->isObjCQualifiedInterfaceType()) {
+ Lo = Integer;
+ } else if (const ComplexType *CT = Ty->getAsComplexType()) {
+ QualType ET = CT->getElementType();
+
+ if (ET == Context.FloatTy)
+ Lo = SSE;
+ else if (ET == Context.DoubleTy)
+ Lo = Hi = SSE;
+ else if (ET == Context.LongDoubleTy)
+ Lo = ComplexX87;
+ }
+}
+
ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy,
ASTContext &Context) const {
- return ABIArgInfo::getDefault();
+ // AMD64-ABI 3.2.3p4: Rule 1. Classify the return type with the
+ // classification algorithm.
+ X86_64ABIInfo::Class Lo, Hi;
+ classify(RetTy, Context, Lo, Hi);
+
+ const llvm::Type *ResType = 0;
+ switch (Lo) {
+ case NoClass:
+ assert(0 && "FIXME: Handle ignored return values.");
+
+ case SSEUp:
+ case X87Up:
+ assert(0 && "Invalid classification for lo word.");
+
+ // AMD64-ABI 3.2.3p4: Rule 2. Types of class memory are returned via
+ // hidden argument, i.e. structret.
+ case Memory:
+ return ABIArgInfo::getStructRet();
+
+ // AMD64-ABI 3.2.3p4: Rule 3. If the class is INTEGER, the next
+ // available register of the sequence %rax, %rdx is used.
+ case Integer:
+ ResType = llvm::Type::Int64Ty; break;
+
+ // AMD64-ABI 3.2.3p4: Rule 4. If the class is SSE, the next
+ // available SSE register of the sequence %xmm0, %xmm1 is used.
+ case SSE:
+ ResType = llvm::Type::DoubleTy; break;
+
+ // AMD64-ABI 3.2.3p4: Rule 6. If the class is X87, the value is
+ // returned on the X87 stack in %st0 as 80-bit x87 number.
+ case X87:
+ ResType = llvm::Type::X86_FP80Ty; break;
+
+ // AMD64-ABI 3.2.3p4: Rule 8. If the class is COMPLEX_X87, the real
+ // part of the value is returned in %st0 and the imaginary part in
+ // %st1.
+ case ComplexX87:
+ assert(Hi == NoClass && "Unexpected ComplexX87 classification.");
+ ResType = llvm::VectorType::get(llvm::Type::X86_FP80Ty, 2);
+ break;
+ }
+
+ switch (Hi) {
+ // Memory was handled previously, and ComplexX87 and X87 should
+ // never occur as hi classes.
+ case Memory:
+ case X87:
+ case ComplexX87:
+ assert(0 && "Invalid classification for hi word.");
+
+ case NoClass: break;
+ case Integer:
+ assert(0 && "FIXME: Implement MRV"); break;
+ case SSE:
+ assert(0 && "FIXME: Implement MRV"); break;
+
+ // 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.
+ //
+ // SSEUP should always be preceeded by SSE, just widen.
+ case SSEUp:
+ assert(Lo == SSE && "Unexpected SSEUp classification.");
+ ResType = llvm::VectorType::get(llvm::Type::DoubleTy, 2);
+ break;
+
+ // AMD64-ABI 3.2.3p4: Rule 7. If the class is X87UP, the value is
+ // returned together with the previos X87 value in %st0.
+ //
+ // X87UP should always be preceeded by X87, so we don't need to do
+ // anything here.
+ case X87Up:
+ assert(Lo == X87 && "Unexpected X87Up classification.");
+ break;
+ }
+
+ return ABIArgInfo::getCoerce(ResType);
}
ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty,
@@ -421,7 +566,8 @@
case 32:
return *(TheABIInfo = new X86_32ABIInfo());
case 64:
- return *(TheABIInfo = new X86_64ABIInfo());
+ if (UseX86_64ABI)
+ return *(TheABIInfo = new X86_64ABIInfo());
}
}
More information about the cfe-commits
mailing list