| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 1 | //===---- TargetInfo.cpp - Encapsulate target details -----------*- C++ -*-===// | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 2 | // | 
 | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
 | 5 | // This file is distributed under the University of Illinois Open Source | 
 | 6 | // License. See LICENSE.TXT for details. | 
 | 7 | // | 
 | 8 | //===----------------------------------------------------------------------===// | 
 | 9 | // | 
 | 10 | // These classes wrap the information about a call or function | 
 | 11 | // definition used to handle ABI compliancy. | 
 | 12 | // | 
 | 13 | //===----------------------------------------------------------------------===// | 
 | 14 |  | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 15 | #include "TargetInfo.h" | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 16 | #include "ABIInfo.h" | 
 | 17 | #include "CodeGenFunction.h" | 
| Anders Carlsson | 19cc4ab | 2009-07-18 19:43:29 +0000 | [diff] [blame] | 18 | #include "clang/AST/RecordLayout.h" | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 19 | #include "llvm/Type.h" | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 20 | #include "llvm/ADT/StringExtras.h" | 
| Daniel Dunbar | 2c0843f | 2009-08-24 08:52:16 +0000 | [diff] [blame] | 21 | #include "llvm/ADT/Triple.h" | 
| Daniel Dunbar | 28df7a5 | 2009-12-03 09:13:49 +0000 | [diff] [blame] | 22 | #include "llvm/Support/raw_ostream.h" | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 23 | using namespace clang; | 
 | 24 | using namespace CodeGen; | 
 | 25 |  | 
| John McCall | aeeb701 | 2010-05-27 06:19:26 +0000 | [diff] [blame] | 26 | static void AssignToArrayRange(CodeGen::CGBuilderTy &Builder, | 
 | 27 |                                llvm::Value *Array, | 
 | 28 |                                llvm::Value *Value, | 
 | 29 |                                unsigned FirstIndex, | 
 | 30 |                                unsigned LastIndex) { | 
 | 31 |   // Alternatively, we could emit this as a loop in the source. | 
 | 32 |   for (unsigned I = FirstIndex; I <= LastIndex; ++I) { | 
 | 33 |     llvm::Value *Cell = Builder.CreateConstInBoundsGEP1_32(Array, I); | 
 | 34 |     Builder.CreateStore(Value, Cell); | 
 | 35 |   } | 
 | 36 | } | 
 | 37 |  | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 38 | ABIInfo::~ABIInfo() {} | 
 | 39 |  | 
 | 40 | void ABIArgInfo::dump() const { | 
| Daniel Dunbar | 28df7a5 | 2009-12-03 09:13:49 +0000 | [diff] [blame] | 41 |   llvm::raw_ostream &OS = llvm::errs(); | 
 | 42 |   OS << "(ABIArgInfo Kind="; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 43 |   switch (TheKind) { | 
 | 44 |   case Direct: | 
| Daniel Dunbar | 28df7a5 | 2009-12-03 09:13:49 +0000 | [diff] [blame] | 45 |     OS << "Direct"; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 46 |     break; | 
| Anton Korobeynikov | cc6fa88 | 2009-06-06 09:36:29 +0000 | [diff] [blame] | 47 |   case Extend: | 
| Daniel Dunbar | 28df7a5 | 2009-12-03 09:13:49 +0000 | [diff] [blame] | 48 |     OS << "Extend"; | 
| Anton Korobeynikov | cc6fa88 | 2009-06-06 09:36:29 +0000 | [diff] [blame] | 49 |     break; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 50 |   case Ignore: | 
| Daniel Dunbar | 28df7a5 | 2009-12-03 09:13:49 +0000 | [diff] [blame] | 51 |     OS << "Ignore"; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 52 |     break; | 
 | 53 |   case Coerce: | 
| Daniel Dunbar | 28df7a5 | 2009-12-03 09:13:49 +0000 | [diff] [blame] | 54 |     OS << "Coerce Type="; | 
 | 55 |     getCoerceToType()->print(OS); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 56 |     break; | 
 | 57 |   case Indirect: | 
| Daniel Dunbar | dc6d574 | 2010-04-21 19:10:51 +0000 | [diff] [blame] | 58 |     OS << "Indirect Align=" << getIndirectAlign() | 
 | 59 |        << " Byal=" << getIndirectByVal(); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 60 |     break; | 
 | 61 |   case Expand: | 
| Daniel Dunbar | 28df7a5 | 2009-12-03 09:13:49 +0000 | [diff] [blame] | 62 |     OS << "Expand"; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 63 |     break; | 
 | 64 |   } | 
| Daniel Dunbar | 28df7a5 | 2009-12-03 09:13:49 +0000 | [diff] [blame] | 65 |   OS << ")\n"; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 66 | } | 
 | 67 |  | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 68 | TargetCodeGenInfo::~TargetCodeGenInfo() { delete Info; } | 
 | 69 |  | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 70 | static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 71 |  | 
 | 72 | /// isEmptyField - Return true iff a the field is "empty", that is it | 
 | 73 | /// is an unnamed bit-field or an (array of) empty record(s). | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 74 | static bool isEmptyField(ASTContext &Context, const FieldDecl *FD, | 
 | 75 |                          bool AllowArrays) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 76 |   if (FD->isUnnamedBitfield()) | 
 | 77 |     return true; | 
 | 78 |  | 
 | 79 |   QualType FT = FD->getType(); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 80 |  | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 81 |     // Constant arrays of empty records count as empty, strip them off. | 
 | 82 |   if (AllowArrays) | 
 | 83 |     while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) | 
 | 84 |       FT = AT->getElementType(); | 
 | 85 |  | 
| Daniel Dunbar | 5ea6861 | 2010-05-17 16:46:00 +0000 | [diff] [blame] | 86 |   const RecordType *RT = FT->getAs<RecordType>(); | 
 | 87 |   if (!RT) | 
 | 88 |     return false; | 
 | 89 |  | 
 | 90 |   // C++ record fields are never empty, at least in the Itanium ABI. | 
 | 91 |   // | 
 | 92 |   // FIXME: We should use a predicate for whether this behavior is true in the | 
 | 93 |   // current ABI. | 
 | 94 |   if (isa<CXXRecordDecl>(RT->getDecl())) | 
 | 95 |     return false; | 
 | 96 |  | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 97 |   return isEmptyRecord(Context, FT, AllowArrays); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 98 | } | 
 | 99 |  | 
 | 100 | /// isEmptyRecord - Return true iff a structure contains only empty | 
 | 101 | /// fields. Note that a structure with a flexible array member is not | 
 | 102 | /// considered empty. | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 103 | static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays) { | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 104 |   const RecordType *RT = T->getAs<RecordType>(); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 105 |   if (!RT) | 
 | 106 |     return 0; | 
 | 107 |   const RecordDecl *RD = RT->getDecl(); | 
 | 108 |   if (RD->hasFlexibleArrayMember()) | 
 | 109 |     return false; | 
| Daniel Dunbar | 5ea6861 | 2010-05-17 16:46:00 +0000 | [diff] [blame] | 110 |  | 
 | 111 |   // If this is a C++ record, check the bases first. | 
 | 112 |   if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) | 
 | 113 |     for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(), | 
 | 114 |            e = CXXRD->bases_end(); i != e; ++i) | 
 | 115 |       if (!isEmptyRecord(Context, i->getType(), true)) | 
 | 116 |         return false; | 
 | 117 |  | 
| Argyrios Kyrtzidis | 17945a0 | 2009-06-30 02:36:12 +0000 | [diff] [blame] | 118 |   for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); | 
 | 119 |          i != e; ++i) | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 120 |     if (!isEmptyField(Context, *i, AllowArrays)) | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 121 |       return false; | 
 | 122 |   return true; | 
 | 123 | } | 
 | 124 |  | 
| Anders Carlsson | 0a8f847 | 2009-09-16 15:53:40 +0000 | [diff] [blame] | 125 | /// hasNonTrivialDestructorOrCopyConstructor - Determine if a type has either | 
 | 126 | /// a non-trivial destructor or a non-trivial copy constructor. | 
 | 127 | static bool hasNonTrivialDestructorOrCopyConstructor(const RecordType *RT) { | 
 | 128 |   const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); | 
 | 129 |   if (!RD) | 
 | 130 |     return false; | 
 | 131 |    | 
 | 132 |   return !RD->hasTrivialDestructor() || !RD->hasTrivialCopyConstructor(); | 
 | 133 | } | 
 | 134 |  | 
 | 135 | /// isRecordWithNonTrivialDestructorOrCopyConstructor - Determine if a type is | 
 | 136 | /// a record type with either a non-trivial destructor or a non-trivial copy | 
 | 137 | /// constructor. | 
 | 138 | static bool isRecordWithNonTrivialDestructorOrCopyConstructor(QualType T) { | 
 | 139 |   const RecordType *RT = T->getAs<RecordType>(); | 
 | 140 |   if (!RT) | 
 | 141 |     return false; | 
 | 142 |  | 
 | 143 |   return hasNonTrivialDestructorOrCopyConstructor(RT); | 
 | 144 | } | 
 | 145 |  | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 146 | /// isSingleElementStruct - Determine if a structure is a "single | 
 | 147 | /// element struct", i.e. it has exactly one non-empty field or | 
 | 148 | /// exactly one field which is itself a single element | 
 | 149 | /// struct. Structures with flexible array members are never | 
 | 150 | /// considered single element structs. | 
 | 151 | /// | 
 | 152 | /// \return The field declaration for the single non-empty field, if | 
 | 153 | /// it exists. | 
 | 154 | static const Type *isSingleElementStruct(QualType T, ASTContext &Context) { | 
 | 155 |   const RecordType *RT = T->getAsStructureType(); | 
 | 156 |   if (!RT) | 
 | 157 |     return 0; | 
 | 158 |  | 
 | 159 |   const RecordDecl *RD = RT->getDecl(); | 
 | 160 |   if (RD->hasFlexibleArrayMember()) | 
 | 161 |     return 0; | 
 | 162 |  | 
 | 163 |   const Type *Found = 0; | 
| Daniel Dunbar | 9430d5a | 2010-05-11 21:15:36 +0000 | [diff] [blame] | 164 |    | 
 | 165 |   // If this is a C++ record, check the bases first. | 
 | 166 |   if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { | 
 | 167 |     for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(), | 
 | 168 |            e = CXXRD->bases_end(); i != e; ++i) { | 
| Daniel Dunbar | 9430d5a | 2010-05-11 21:15:36 +0000 | [diff] [blame] | 169 |       // Ignore empty records. | 
| Daniel Dunbar | 5ea6861 | 2010-05-17 16:46:00 +0000 | [diff] [blame] | 170 |       if (isEmptyRecord(Context, i->getType(), true)) | 
| Daniel Dunbar | 9430d5a | 2010-05-11 21:15:36 +0000 | [diff] [blame] | 171 |         continue; | 
 | 172 |  | 
 | 173 |       // If we already found an element then this isn't a single-element struct. | 
 | 174 |       if (Found) | 
 | 175 |         return 0; | 
 | 176 |  | 
 | 177 |       // If this is non-empty and not a single element struct, the composite | 
 | 178 |       // cannot be a single element struct. | 
 | 179 |       Found = isSingleElementStruct(i->getType(), Context); | 
 | 180 |       if (!Found) | 
 | 181 |         return 0; | 
 | 182 |     } | 
 | 183 |   } | 
 | 184 |  | 
 | 185 |   // Check for single element. | 
| Argyrios Kyrtzidis | 17945a0 | 2009-06-30 02:36:12 +0000 | [diff] [blame] | 186 |   for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); | 
 | 187 |          i != e; ++i) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 188 |     const FieldDecl *FD = *i; | 
 | 189 |     QualType FT = FD->getType(); | 
 | 190 |  | 
 | 191 |     // Ignore empty fields. | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 192 |     if (isEmptyField(Context, FD, true)) | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 193 |       continue; | 
 | 194 |  | 
 | 195 |     // If we already found an element then this isn't a single-element | 
 | 196 |     // struct. | 
 | 197 |     if (Found) | 
 | 198 |       return 0; | 
 | 199 |  | 
 | 200 |     // Treat single element arrays as the element. | 
 | 201 |     while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) { | 
 | 202 |       if (AT->getSize().getZExtValue() != 1) | 
 | 203 |         break; | 
 | 204 |       FT = AT->getElementType(); | 
 | 205 |     } | 
 | 206 |  | 
 | 207 |     if (!CodeGenFunction::hasAggregateLLVMType(FT)) { | 
 | 208 |       Found = FT.getTypePtr(); | 
 | 209 |     } else { | 
 | 210 |       Found = isSingleElementStruct(FT, Context); | 
 | 211 |       if (!Found) | 
 | 212 |         return 0; | 
 | 213 |     } | 
 | 214 |   } | 
 | 215 |  | 
 | 216 |   return Found; | 
 | 217 | } | 
 | 218 |  | 
 | 219 | static bool is32Or64BitBasicType(QualType Ty, ASTContext &Context) { | 
| Daniel Dunbar | a1842d3 | 2010-05-14 03:40:53 +0000 | [diff] [blame] | 220 |   if (!Ty->getAs<BuiltinType>() && !Ty->hasPointerRepresentation() && | 
| Daniel Dunbar | 55e59e1 | 2009-09-24 05:12:36 +0000 | [diff] [blame] | 221 |       !Ty->isAnyComplexType() && !Ty->isEnumeralType() && | 
 | 222 |       !Ty->isBlockPointerType()) | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 223 |     return false; | 
 | 224 |  | 
 | 225 |   uint64_t Size = Context.getTypeSize(Ty); | 
 | 226 |   return Size == 32 || Size == 64; | 
 | 227 | } | 
 | 228 |  | 
| Daniel Dunbar | 53012f4 | 2009-11-09 01:33:53 +0000 | [diff] [blame] | 229 | /// canExpandIndirectArgument - Test whether an argument type which is to be | 
 | 230 | /// passed indirectly (on the stack) would have the equivalent layout if it was | 
 | 231 | /// expanded into separate arguments. If so, we prefer to do the latter to avoid | 
 | 232 | /// inhibiting optimizations. | 
 | 233 | /// | 
 | 234 | // FIXME: This predicate is missing many cases, currently it just follows | 
 | 235 | // llvm-gcc (checks that all fields are 32-bit or 64-bit primitive types). We | 
 | 236 | // should probably make this smarter, or better yet make the LLVM backend | 
 | 237 | // capable of handling it. | 
 | 238 | static bool canExpandIndirectArgument(QualType Ty, ASTContext &Context) { | 
 | 239 |   // We can only expand structure types. | 
 | 240 |   const RecordType *RT = Ty->getAs<RecordType>(); | 
 | 241 |   if (!RT) | 
 | 242 |     return false; | 
 | 243 |  | 
 | 244 |   // We can only expand (C) structures. | 
 | 245 |   // | 
 | 246 |   // FIXME: This needs to be generalized to handle classes as well. | 
 | 247 |   const RecordDecl *RD = RT->getDecl(); | 
 | 248 |   if (!RD->isStruct() || isa<CXXRecordDecl>(RD)) | 
 | 249 |     return false; | 
 | 250 |  | 
| Argyrios Kyrtzidis | 17945a0 | 2009-06-30 02:36:12 +0000 | [diff] [blame] | 251 |   for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); | 
 | 252 |          i != e; ++i) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 253 |     const FieldDecl *FD = *i; | 
 | 254 |  | 
 | 255 |     if (!is32Or64BitBasicType(FD->getType(), Context)) | 
 | 256 |       return false; | 
 | 257 |  | 
 | 258 |     // FIXME: Reject bit-fields wholesale; there are two problems, we don't know | 
 | 259 |     // how to expand them yet, and the predicate for telling if a bitfield still | 
 | 260 |     // counts as "basic" is more complicated than what we were doing previously. | 
 | 261 |     if (FD->isBitField()) | 
 | 262 |       return false; | 
 | 263 |   } | 
 | 264 |  | 
 | 265 |   return true; | 
 | 266 | } | 
 | 267 |  | 
 | 268 | namespace { | 
 | 269 | /// DefaultABIInfo - The default implementation for ABI specific | 
 | 270 | /// details. This implementation provides information which results in | 
 | 271 | /// self-consistent and sensible LLVM IR generation, but does not | 
 | 272 | /// conform to any particular ABI. | 
 | 273 | class DefaultABIInfo : public ABIInfo { | 
 | 274 |   ABIArgInfo classifyReturnType(QualType RetTy, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 275 |                                 ASTContext &Context, | 
 | 276 |                                 llvm::LLVMContext &VMContext) const; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 277 |  | 
 | 278 |   ABIArgInfo classifyArgumentType(QualType RetTy, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 279 |                                   ASTContext &Context, | 
 | 280 |                                   llvm::LLVMContext &VMContext) const; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 281 |  | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 282 |   virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context, | 
| Chris Lattner | 8640cd6 | 2010-06-29 01:08:48 +0000 | [diff] [blame^] | 283 |                            llvm::LLVMContext &VMContext, | 
 | 284 |                            const llvm::Type *const *PrefTypes, | 
 | 285 |                            unsigned NumPrefTypes) const { | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 286 |     FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), Context, | 
 | 287 |                                             VMContext); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 288 |     for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); | 
 | 289 |          it != ie; ++it) | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 290 |       it->info = classifyArgumentType(it->type, Context, VMContext); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 291 |   } | 
 | 292 |  | 
 | 293 |   virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, | 
 | 294 |                                  CodeGenFunction &CGF) const; | 
 | 295 | }; | 
 | 296 |  | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 297 | class DefaultTargetCodeGenInfo : public TargetCodeGenInfo { | 
 | 298 | public: | 
| Douglas Gregor | 568bb2d | 2010-01-22 15:41:14 +0000 | [diff] [blame] | 299 |   DefaultTargetCodeGenInfo():TargetCodeGenInfo(new DefaultABIInfo()) {} | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 300 | }; | 
 | 301 |  | 
 | 302 | llvm::Value *DefaultABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, | 
 | 303 |                                        CodeGenFunction &CGF) const { | 
 | 304 |   return 0; | 
 | 305 | } | 
 | 306 |  | 
 | 307 | ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty, | 
 | 308 |                                                 ASTContext &Context, | 
 | 309 |                                           llvm::LLVMContext &VMContext) const { | 
| Chris Lattner | a14db75 | 2010-03-11 18:19:55 +0000 | [diff] [blame] | 310 |   if (CodeGenFunction::hasAggregateLLVMType(Ty)) | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 311 |     return ABIArgInfo::getIndirect(0); | 
| Daniel Dunbar | dc6d574 | 2010-04-21 19:10:51 +0000 | [diff] [blame] | 312 |  | 
| Chris Lattner | a14db75 | 2010-03-11 18:19:55 +0000 | [diff] [blame] | 313 |   // Treat an enum type as its underlying type. | 
 | 314 |   if (const EnumType *EnumTy = Ty->getAs<EnumType>()) | 
 | 315 |     Ty = EnumTy->getDecl()->getIntegerType(); | 
| Douglas Gregor | aa74a1e | 2010-02-02 20:10:50 +0000 | [diff] [blame] | 316 |  | 
| Chris Lattner | a14db75 | 2010-03-11 18:19:55 +0000 | [diff] [blame] | 317 |   return (Ty->isPromotableIntegerType() ? | 
 | 318 |           ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 319 | } | 
 | 320 |  | 
| Chris Lattner | dce5ad0 | 2010-06-28 20:05:43 +0000 | [diff] [blame] | 321 | //===----------------------------------------------------------------------===// | 
 | 322 | // X86-32 ABI Implementation | 
 | 323 | //===----------------------------------------------------------------------===// | 
 | 324 |    | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 325 | /// X86_32ABIInfo - The X86-32 ABI information. | 
 | 326 | class X86_32ABIInfo : public ABIInfo { | 
 | 327 |   ASTContext &Context; | 
| David Chisnall | 1e4249c | 2009-08-17 23:08:21 +0000 | [diff] [blame] | 328 |   bool IsDarwinVectorABI; | 
 | 329 |   bool IsSmallStructInRegABI; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 330 |  | 
 | 331 |   static bool isRegisterSize(unsigned Size) { | 
 | 332 |     return (Size == 8 || Size == 16 || Size == 32 || Size == 64); | 
 | 333 |   } | 
 | 334 |  | 
 | 335 |   static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context); | 
 | 336 |  | 
| Daniel Dunbar | dc6d574 | 2010-04-21 19:10:51 +0000 | [diff] [blame] | 337 |   /// getIndirectResult - Give a source type \arg Ty, return a suitable result | 
 | 338 |   /// such that the argument will be passed in memory. | 
 | 339 |   ABIArgInfo getIndirectResult(QualType Ty, ASTContext &Context, | 
 | 340 |                                bool ByVal = true) const; | 
 | 341 |  | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 342 | public: | 
 | 343 |   ABIArgInfo classifyReturnType(QualType RetTy, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 344 |                                 ASTContext &Context, | 
 | 345 |                                 llvm::LLVMContext &VMContext) const; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 346 |  | 
 | 347 |   ABIArgInfo classifyArgumentType(QualType RetTy, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 348 |                                   ASTContext &Context, | 
 | 349 |                                   llvm::LLVMContext &VMContext) const; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 350 |  | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 351 |   virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context, | 
| Chris Lattner | 8640cd6 | 2010-06-29 01:08:48 +0000 | [diff] [blame^] | 352 |                            llvm::LLVMContext &VMContext, | 
 | 353 |                            const llvm::Type *const *PrefTypes, | 
 | 354 |                            unsigned NumPrefTypes) const { | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 355 |     FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), Context, | 
 | 356 |                                             VMContext); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 357 |     for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); | 
 | 358 |          it != ie; ++it) | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 359 |       it->info = classifyArgumentType(it->type, Context, VMContext); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 360 |   } | 
 | 361 |  | 
 | 362 |   virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, | 
 | 363 |                                  CodeGenFunction &CGF) const; | 
 | 364 |  | 
| David Chisnall | 1e4249c | 2009-08-17 23:08:21 +0000 | [diff] [blame] | 365 |   X86_32ABIInfo(ASTContext &Context, bool d, bool p) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 366 |     : ABIInfo(), Context(Context), IsDarwinVectorABI(d), | 
| David Chisnall | 1e4249c | 2009-08-17 23:08:21 +0000 | [diff] [blame] | 367 |       IsSmallStructInRegABI(p) {} | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 368 | }; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 369 |  | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 370 | class X86_32TargetCodeGenInfo : public TargetCodeGenInfo { | 
 | 371 | public: | 
 | 372 |   X86_32TargetCodeGenInfo(ASTContext &Context, bool d, bool p) | 
| Douglas Gregor | 568bb2d | 2010-01-22 15:41:14 +0000 | [diff] [blame] | 373 |     :TargetCodeGenInfo(new X86_32ABIInfo(Context, d, p)) {} | 
| Charles Davis | 74f7293 | 2010-02-13 15:54:06 +0000 | [diff] [blame] | 374 |  | 
 | 375 |   void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, | 
 | 376 |                            CodeGen::CodeGenModule &CGM) const; | 
| John McCall | 6374c33 | 2010-03-06 00:35:14 +0000 | [diff] [blame] | 377 |  | 
 | 378 |   int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const { | 
 | 379 |     // Darwin uses different dwarf register numbers for EH. | 
 | 380 |     if (CGM.isTargetDarwin()) return 5; | 
 | 381 |  | 
 | 382 |     return 4; | 
 | 383 |   } | 
 | 384 |  | 
 | 385 |   bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, | 
 | 386 |                                llvm::Value *Address) const; | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 387 | }; | 
 | 388 |  | 
 | 389 | } | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 390 |  | 
 | 391 | /// shouldReturnTypeInRegister - Determine if the given type should be | 
 | 392 | /// passed in a register (for the Darwin ABI). | 
 | 393 | bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty, | 
 | 394 |                                                ASTContext &Context) { | 
 | 395 |   uint64_t Size = Context.getTypeSize(Ty); | 
 | 396 |  | 
 | 397 |   // Type must be register sized. | 
 | 398 |   if (!isRegisterSize(Size)) | 
 | 399 |     return false; | 
 | 400 |  | 
 | 401 |   if (Ty->isVectorType()) { | 
 | 402 |     // 64- and 128- bit vectors inside structures are not returned in | 
 | 403 |     // registers. | 
 | 404 |     if (Size == 64 || Size == 128) | 
 | 405 |       return false; | 
 | 406 |  | 
 | 407 |     return true; | 
 | 408 |   } | 
 | 409 |  | 
| Daniel Dunbar | 7711523 | 2010-05-15 00:00:30 +0000 | [diff] [blame] | 410 |   // If this is a builtin, pointer, enum, complex type, member pointer, or | 
 | 411 |   // member function pointer it is ok. | 
| Daniel Dunbar | a1842d3 | 2010-05-14 03:40:53 +0000 | [diff] [blame] | 412 |   if (Ty->getAs<BuiltinType>() || Ty->hasPointerRepresentation() || | 
| Daniel Dunbar | 55e59e1 | 2009-09-24 05:12:36 +0000 | [diff] [blame] | 413 |       Ty->isAnyComplexType() || Ty->isEnumeralType() || | 
| Daniel Dunbar | 7711523 | 2010-05-15 00:00:30 +0000 | [diff] [blame] | 414 |       Ty->isBlockPointerType() || Ty->isMemberPointerType()) | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 415 |     return true; | 
 | 416 |  | 
 | 417 |   // Arrays are treated like records. | 
 | 418 |   if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) | 
 | 419 |     return shouldReturnTypeInRegister(AT->getElementType(), Context); | 
 | 420 |  | 
 | 421 |   // Otherwise, it must be a record type. | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 422 |   const RecordType *RT = Ty->getAs<RecordType>(); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 423 |   if (!RT) return false; | 
 | 424 |  | 
| Anders Carlsson | a887423 | 2010-01-27 03:25:19 +0000 | [diff] [blame] | 425 |   // FIXME: Traverse bases here too. | 
 | 426 |  | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 427 |   // Structure types are passed in register if all fields would be | 
 | 428 |   // passed in a register. | 
| Argyrios Kyrtzidis | 17945a0 | 2009-06-30 02:36:12 +0000 | [diff] [blame] | 429 |   for (RecordDecl::field_iterator i = RT->getDecl()->field_begin(), | 
 | 430 |          e = RT->getDecl()->field_end(); i != e; ++i) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 431 |     const FieldDecl *FD = *i; | 
 | 432 |  | 
 | 433 |     // Empty fields are ignored. | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 434 |     if (isEmptyField(Context, FD, true)) | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 435 |       continue; | 
 | 436 |  | 
 | 437 |     // Check fields recursively. | 
 | 438 |     if (!shouldReturnTypeInRegister(FD->getType(), Context)) | 
 | 439 |       return false; | 
 | 440 |   } | 
 | 441 |  | 
 | 442 |   return true; | 
 | 443 | } | 
 | 444 |  | 
 | 445 | ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 446 |                                             ASTContext &Context, | 
 | 447 |                                           llvm::LLVMContext &VMContext) const { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 448 |   if (RetTy->isVoidType()) { | 
 | 449 |     return ABIArgInfo::getIgnore(); | 
| John McCall | 183700f | 2009-09-21 23:43:11 +0000 | [diff] [blame] | 450 |   } else if (const VectorType *VT = RetTy->getAs<VectorType>()) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 451 |     // On Darwin, some vectors are returned in registers. | 
| David Chisnall | 1e4249c | 2009-08-17 23:08:21 +0000 | [diff] [blame] | 452 |     if (IsDarwinVectorABI) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 453 |       uint64_t Size = Context.getTypeSize(RetTy); | 
 | 454 |  | 
 | 455 |       // 128-bit vectors are a special case; they are returned in | 
 | 456 |       // registers and we need to make sure to pick a type the LLVM | 
 | 457 |       // backend will like. | 
 | 458 |       if (Size == 128) | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 459 |         return ABIArgInfo::getCoerce(llvm::VectorType::get( | 
 | 460 |                   llvm::Type::getInt64Ty(VMContext), 2)); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 461 |  | 
 | 462 |       // Always return in register if it fits in a general purpose | 
 | 463 |       // register, or if it is 64 bits and has a single element. | 
 | 464 |       if ((Size == 8 || Size == 16 || Size == 32) || | 
 | 465 |           (Size == 64 && VT->getNumElements() == 1)) | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 466 |         return ABIArgInfo::getCoerce(llvm::IntegerType::get(VMContext, Size)); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 467 |  | 
 | 468 |       return ABIArgInfo::getIndirect(0); | 
 | 469 |     } | 
 | 470 |  | 
 | 471 |     return ABIArgInfo::getDirect(); | 
 | 472 |   } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) { | 
| Anders Carlsson | a887423 | 2010-01-27 03:25:19 +0000 | [diff] [blame] | 473 |     if (const RecordType *RT = RetTy->getAs<RecordType>()) { | 
| Anders Carlsson | 4009297 | 2009-10-20 22:07:59 +0000 | [diff] [blame] | 474 |       // Structures with either a non-trivial destructor or a non-trivial | 
 | 475 |       // copy constructor are always indirect. | 
 | 476 |       if (hasNonTrivialDestructorOrCopyConstructor(RT)) | 
 | 477 |         return ABIArgInfo::getIndirect(0, /*ByVal=*/false); | 
 | 478 |        | 
 | 479 |       // Structures with flexible arrays are always indirect. | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 480 |       if (RT->getDecl()->hasFlexibleArrayMember()) | 
 | 481 |         return ABIArgInfo::getIndirect(0); | 
| Anders Carlsson | 4009297 | 2009-10-20 22:07:59 +0000 | [diff] [blame] | 482 |     } | 
 | 483 |      | 
| David Chisnall | 1e4249c | 2009-08-17 23:08:21 +0000 | [diff] [blame] | 484 |     // If specified, structs and unions are always indirect. | 
 | 485 |     if (!IsSmallStructInRegABI && !RetTy->isAnyComplexType()) | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 486 |       return ABIArgInfo::getIndirect(0); | 
 | 487 |  | 
 | 488 |     // Classify "single element" structs as their element type. | 
 | 489 |     if (const Type *SeltTy = isSingleElementStruct(RetTy, Context)) { | 
| John McCall | 183700f | 2009-09-21 23:43:11 +0000 | [diff] [blame] | 490 |       if (const BuiltinType *BT = SeltTy->getAs<BuiltinType>()) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 491 |         if (BT->isIntegerType()) { | 
 | 492 |           // We need to use the size of the structure, padding | 
 | 493 |           // bit-fields can adjust that to be larger than the single | 
 | 494 |           // element type. | 
 | 495 |           uint64_t Size = Context.getTypeSize(RetTy); | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 496 |           return ABIArgInfo::getCoerce( | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 497 |             llvm::IntegerType::get(VMContext, (unsigned) Size)); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 498 |         } else if (BT->getKind() == BuiltinType::Float) { | 
 | 499 |           assert(Context.getTypeSize(RetTy) == Context.getTypeSize(SeltTy) && | 
 | 500 |                  "Unexpect single element structure size!"); | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 501 |           return ABIArgInfo::getCoerce(llvm::Type::getFloatTy(VMContext)); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 502 |         } else if (BT->getKind() == BuiltinType::Double) { | 
 | 503 |           assert(Context.getTypeSize(RetTy) == Context.getTypeSize(SeltTy) && | 
 | 504 |                  "Unexpect single element structure size!"); | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 505 |           return ABIArgInfo::getCoerce(llvm::Type::getDoubleTy(VMContext)); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 506 |         } | 
 | 507 |       } else if (SeltTy->isPointerType()) { | 
 | 508 |         // FIXME: It would be really nice if this could come out as the proper | 
 | 509 |         // pointer type. | 
| Benjamin Kramer | 3c0ef8c | 2009-10-13 10:07:13 +0000 | [diff] [blame] | 510 |         const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 511 |         return ABIArgInfo::getCoerce(PtrTy); | 
 | 512 |       } else if (SeltTy->isVectorType()) { | 
 | 513 |         // 64- and 128-bit vectors are never returned in a | 
 | 514 |         // register when inside a structure. | 
 | 515 |         uint64_t Size = Context.getTypeSize(RetTy); | 
 | 516 |         if (Size == 64 || Size == 128) | 
 | 517 |           return ABIArgInfo::getIndirect(0); | 
 | 518 |  | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 519 |         return classifyReturnType(QualType(SeltTy, 0), Context, VMContext); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 520 |       } | 
 | 521 |     } | 
 | 522 |  | 
 | 523 |     // Small structures which are register sized are generally returned | 
 | 524 |     // in a register. | 
 | 525 |     if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, Context)) { | 
 | 526 |       uint64_t Size = Context.getTypeSize(RetTy); | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 527 |       return ABIArgInfo::getCoerce(llvm::IntegerType::get(VMContext, Size)); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 528 |     } | 
 | 529 |  | 
 | 530 |     return ABIArgInfo::getIndirect(0); | 
 | 531 |   } else { | 
| Douglas Gregor | aa74a1e | 2010-02-02 20:10:50 +0000 | [diff] [blame] | 532 |     // Treat an enum type as its underlying type. | 
 | 533 |     if (const EnumType *EnumTy = RetTy->getAs<EnumType>()) | 
 | 534 |       RetTy = EnumTy->getDecl()->getIntegerType(); | 
 | 535 |  | 
| Anton Korobeynikov | cc6fa88 | 2009-06-06 09:36:29 +0000 | [diff] [blame] | 536 |     return (RetTy->isPromotableIntegerType() ? | 
 | 537 |             ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 538 |   } | 
 | 539 | } | 
 | 540 |  | 
| Daniel Dunbar | dc6d574 | 2010-04-21 19:10:51 +0000 | [diff] [blame] | 541 | ABIArgInfo X86_32ABIInfo::getIndirectResult(QualType Ty, | 
 | 542 |                                             ASTContext &Context, | 
 | 543 |                                             bool ByVal) const { | 
| Daniel Dunbar | 46c54fb | 2010-04-21 19:49:55 +0000 | [diff] [blame] | 544 |   if (!ByVal) | 
 | 545 |     return ABIArgInfo::getIndirect(0, false); | 
 | 546 |  | 
 | 547 |   // Compute the byval alignment. We trust the back-end to honor the | 
 | 548 |   // minimum ABI alignment for byval, to make cleaner IR. | 
 | 549 |   const unsigned MinABIAlign = 4; | 
 | 550 |   unsigned Align = Context.getTypeAlign(Ty) / 8; | 
 | 551 |   if (Align > MinABIAlign) | 
 | 552 |     return ABIArgInfo::getIndirect(Align); | 
 | 553 |   return ABIArgInfo::getIndirect(0); | 
| Daniel Dunbar | dc6d574 | 2010-04-21 19:10:51 +0000 | [diff] [blame] | 554 | } | 
 | 555 |  | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 556 | ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 557 |                                                ASTContext &Context, | 
 | 558 |                                            llvm::LLVMContext &VMContext) const { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 559 |   // FIXME: Set alignment on indirect arguments. | 
 | 560 |   if (CodeGenFunction::hasAggregateLLVMType(Ty)) { | 
 | 561 |     // Structures with flexible arrays are always indirect. | 
| Anders Carlsson | a887423 | 2010-01-27 03:25:19 +0000 | [diff] [blame] | 562 |     if (const RecordType *RT = Ty->getAs<RecordType>()) { | 
 | 563 |       // Structures with either a non-trivial destructor or a non-trivial | 
 | 564 |       // copy constructor are always indirect. | 
 | 565 |       if (hasNonTrivialDestructorOrCopyConstructor(RT)) | 
| Daniel Dunbar | dc6d574 | 2010-04-21 19:10:51 +0000 | [diff] [blame] | 566 |         return getIndirectResult(Ty, Context, /*ByVal=*/false); | 
 | 567 |  | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 568 |       if (RT->getDecl()->hasFlexibleArrayMember()) | 
| Daniel Dunbar | dc6d574 | 2010-04-21 19:10:51 +0000 | [diff] [blame] | 569 |         return getIndirectResult(Ty, Context); | 
| Anders Carlsson | a887423 | 2010-01-27 03:25:19 +0000 | [diff] [blame] | 570 |     } | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 571 |  | 
 | 572 |     // Ignore empty structs. | 
| Eli Friedman | a1e6de9 | 2009-06-13 21:37:10 +0000 | [diff] [blame] | 573 |     if (Ty->isStructureType() && Context.getTypeSize(Ty) == 0) | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 574 |       return ABIArgInfo::getIgnore(); | 
 | 575 |  | 
| Daniel Dunbar | 53012f4 | 2009-11-09 01:33:53 +0000 | [diff] [blame] | 576 |     // Expand small (<= 128-bit) record types when we know that the stack layout | 
 | 577 |     // of those arguments will match the struct. This is important because the | 
 | 578 |     // LLVM backend isn't smart enough to remove byval, which inhibits many | 
 | 579 |     // optimizations. | 
 | 580 |     if (Context.getTypeSize(Ty) <= 4*32 && | 
 | 581 |         canExpandIndirectArgument(Ty, Context)) | 
 | 582 |       return ABIArgInfo::getExpand(); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 583 |  | 
| Daniel Dunbar | dc6d574 | 2010-04-21 19:10:51 +0000 | [diff] [blame] | 584 |     return getIndirectResult(Ty, Context); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 585 |   } else { | 
| Douglas Gregor | aa74a1e | 2010-02-02 20:10:50 +0000 | [diff] [blame] | 586 |     if (const EnumType *EnumTy = Ty->getAs<EnumType>()) | 
 | 587 |       Ty = EnumTy->getDecl()->getIntegerType(); | 
 | 588 |  | 
| Anton Korobeynikov | cc6fa88 | 2009-06-06 09:36:29 +0000 | [diff] [blame] | 589 |     return (Ty->isPromotableIntegerType() ? | 
 | 590 |             ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 591 |   } | 
 | 592 | } | 
 | 593 |  | 
 | 594 | llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, | 
 | 595 |                                       CodeGenFunction &CGF) const { | 
| Benjamin Kramer | 3c0ef8c | 2009-10-13 10:07:13 +0000 | [diff] [blame] | 596 |   const llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); | 
| Owen Anderson | 96e0fc7 | 2009-07-29 22:16:19 +0000 | [diff] [blame] | 597 |   const llvm::Type *BPP = llvm::PointerType::getUnqual(BP); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 598 |  | 
 | 599 |   CGBuilderTy &Builder = CGF.Builder; | 
 | 600 |   llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, | 
 | 601 |                                                        "ap"); | 
 | 602 |   llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur"); | 
 | 603 |   llvm::Type *PTy = | 
| Owen Anderson | 96e0fc7 | 2009-07-29 22:16:19 +0000 | [diff] [blame] | 604 |     llvm::PointerType::getUnqual(CGF.ConvertType(Ty)); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 605 |   llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy); | 
 | 606 |  | 
 | 607 |   uint64_t Offset = | 
 | 608 |     llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, 4); | 
 | 609 |   llvm::Value *NextAddr = | 
| Chris Lattner | 77b89b8 | 2010-06-27 07:15:29 +0000 | [diff] [blame] | 610 |     Builder.CreateGEP(Addr, llvm::ConstantInt::get(CGF.Int32Ty, Offset), | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 611 |                       "ap.next"); | 
 | 612 |   Builder.CreateStore(NextAddr, VAListAddrAsBPP); | 
 | 613 |  | 
 | 614 |   return AddrTyped; | 
 | 615 | } | 
 | 616 |  | 
| Charles Davis | 74f7293 | 2010-02-13 15:54:06 +0000 | [diff] [blame] | 617 | void X86_32TargetCodeGenInfo::SetTargetAttributes(const Decl *D, | 
 | 618 |                                                   llvm::GlobalValue *GV, | 
 | 619 |                                             CodeGen::CodeGenModule &CGM) const { | 
 | 620 |   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { | 
 | 621 |     if (FD->hasAttr<X86ForceAlignArgPointerAttr>()) { | 
 | 622 |       // Get the LLVM function. | 
 | 623 |       llvm::Function *Fn = cast<llvm::Function>(GV); | 
 | 624 |  | 
 | 625 |       // Now add the 'alignstack' attribute with a value of 16. | 
 | 626 |       Fn->addFnAttr(llvm::Attribute::constructStackAlignmentFromInt(16)); | 
 | 627 |     } | 
 | 628 |   } | 
 | 629 | } | 
 | 630 |  | 
| John McCall | 6374c33 | 2010-03-06 00:35:14 +0000 | [diff] [blame] | 631 | bool X86_32TargetCodeGenInfo::initDwarfEHRegSizeTable( | 
 | 632 |                                                CodeGen::CodeGenFunction &CGF, | 
 | 633 |                                                llvm::Value *Address) const { | 
 | 634 |   CodeGen::CGBuilderTy &Builder = CGF.Builder; | 
 | 635 |   llvm::LLVMContext &Context = CGF.getLLVMContext(); | 
 | 636 |  | 
 | 637 |   const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context); | 
 | 638 |   llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4); | 
 | 639 |      | 
 | 640 |   // 0-7 are the eight integer registers;  the order is different | 
 | 641 |   //   on Darwin (for EH), but the range is the same. | 
 | 642 |   // 8 is %eip. | 
| John McCall | aeeb701 | 2010-05-27 06:19:26 +0000 | [diff] [blame] | 643 |   AssignToArrayRange(Builder, Address, Four8, 0, 8); | 
| John McCall | 6374c33 | 2010-03-06 00:35:14 +0000 | [diff] [blame] | 644 |  | 
 | 645 |   if (CGF.CGM.isTargetDarwin()) { | 
 | 646 |     // 12-16 are st(0..4).  Not sure why we stop at 4. | 
 | 647 |     // These have size 16, which is sizeof(long double) on | 
 | 648 |     // platforms with 8-byte alignment for that type. | 
 | 649 |     llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16); | 
| John McCall | aeeb701 | 2010-05-27 06:19:26 +0000 | [diff] [blame] | 650 |     AssignToArrayRange(Builder, Address, Sixteen8, 12, 16); | 
| John McCall | 6374c33 | 2010-03-06 00:35:14 +0000 | [diff] [blame] | 651 |        | 
 | 652 |   } else { | 
 | 653 |     // 9 is %eflags, which doesn't get a size on Darwin for some | 
 | 654 |     // reason. | 
 | 655 |     Builder.CreateStore(Four8, Builder.CreateConstInBoundsGEP1_32(Address, 9)); | 
 | 656 |  | 
 | 657 |     // 11-16 are st(0..5).  Not sure why we stop at 5. | 
 | 658 |     // These have size 12, which is sizeof(long double) on | 
 | 659 |     // platforms with 4-byte alignment for that type. | 
 | 660 |     llvm::Value *Twelve8 = llvm::ConstantInt::get(i8, 12); | 
| John McCall | aeeb701 | 2010-05-27 06:19:26 +0000 | [diff] [blame] | 661 |     AssignToArrayRange(Builder, Address, Twelve8, 11, 16); | 
 | 662 |   } | 
| John McCall | 6374c33 | 2010-03-06 00:35:14 +0000 | [diff] [blame] | 663 |  | 
 | 664 |   return false; | 
 | 665 | } | 
 | 666 |  | 
| Chris Lattner | dce5ad0 | 2010-06-28 20:05:43 +0000 | [diff] [blame] | 667 | //===----------------------------------------------------------------------===// | 
 | 668 | // X86-64 ABI Implementation | 
 | 669 | //===----------------------------------------------------------------------===// | 
 | 670 |  | 
 | 671 |  | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 672 | namespace { | 
 | 673 | /// X86_64ABIInfo - The X86_64 ABI information. | 
 | 674 | class X86_64ABIInfo : public ABIInfo { | 
 | 675 |   enum Class { | 
 | 676 |     Integer = 0, | 
 | 677 |     SSE, | 
 | 678 |     SSEUp, | 
 | 679 |     X87, | 
 | 680 |     X87Up, | 
 | 681 |     ComplexX87, | 
 | 682 |     NoClass, | 
 | 683 |     Memory | 
 | 684 |   }; | 
 | 685 |  | 
 | 686 |   /// merge - Implement the X86_64 ABI merging algorithm. | 
 | 687 |   /// | 
 | 688 |   /// Merge an accumulating classification \arg Accum with a field | 
 | 689 |   /// classification \arg Field. | 
 | 690 |   /// | 
 | 691 |   /// \param Accum - The accumulating classification. This should | 
 | 692 |   /// always be either NoClass or the result of a previous merge | 
 | 693 |   /// call. In addition, this should never be Memory (the caller | 
 | 694 |   /// should just return Memory for the aggregate). | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 695 |   static Class merge(Class Accum, Class Field); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 696 |  | 
 | 697 |   /// classify - Determine the x86_64 register classes in which the | 
 | 698 |   /// given type T should be passed. | 
 | 699 |   /// | 
 | 700 |   /// \param Lo - The classification for the parts of the type | 
 | 701 |   /// residing in the low word of the containing object. | 
 | 702 |   /// | 
 | 703 |   /// \param Hi - The classification for the parts of the type | 
 | 704 |   /// residing in the high word of the containing object. | 
 | 705 |   /// | 
 | 706 |   /// \param OffsetBase - The bit offset of this type in the | 
 | 707 |   /// containing object.  Some parameters are classified different | 
 | 708 |   /// depending on whether they straddle an eightbyte boundary. | 
 | 709 |   /// | 
 | 710 |   /// If a word is unused its result will be NoClass; if a type should | 
 | 711 |   /// be passed in Memory then at least the classification of \arg Lo | 
 | 712 |   /// will be Memory. | 
 | 713 |   /// | 
 | 714 |   /// The \arg Lo class will be NoClass iff the argument is ignored. | 
 | 715 |   /// | 
 | 716 |   /// If the \arg Lo class is ComplexX87, then the \arg Hi class will | 
 | 717 |   /// also be ComplexX87. | 
 | 718 |   void classify(QualType T, ASTContext &Context, uint64_t OffsetBase, | 
 | 719 |                 Class &Lo, Class &Hi) const; | 
 | 720 |  | 
 | 721 |   /// getCoerceResult - Given a source type \arg Ty and an LLVM type | 
 | 722 |   /// to coerce to, chose the best way to pass Ty in the same place | 
 | 723 |   /// that \arg CoerceTo would be passed, but while keeping the | 
 | 724 |   /// emitted code as simple as possible. | 
 | 725 |   /// | 
 | 726 |   /// FIXME: Note, this should be cleaned up to just take an enumeration of all | 
 | 727 |   /// the ways we might want to pass things, instead of constructing an LLVM | 
 | 728 |   /// type. This makes this code more explicit, and it makes it clearer that we | 
 | 729 |   /// are also doing this for correctness in the case of passing scalar types. | 
 | 730 |   ABIArgInfo getCoerceResult(QualType Ty, | 
 | 731 |                              const llvm::Type *CoerceTo, | 
 | 732 |                              ASTContext &Context) const; | 
 | 733 |  | 
 | 734 |   /// getIndirectResult - Give a source type \arg Ty, return a suitable result | 
| Daniel Dunbar | 46c54fb | 2010-04-21 19:49:55 +0000 | [diff] [blame] | 735 |   /// such that the argument will be returned in memory. | 
 | 736 |   ABIArgInfo getIndirectReturnResult(QualType Ty, ASTContext &Context) const; | 
 | 737 |  | 
 | 738 |   /// getIndirectResult - Give a source type \arg Ty, return a suitable result | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 739 |   /// such that the argument will be passed in memory. | 
| Daniel Dunbar | dc6d574 | 2010-04-21 19:10:51 +0000 | [diff] [blame] | 740 |   ABIArgInfo getIndirectResult(QualType Ty, ASTContext &Context) const; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 741 |  | 
 | 742 |   ABIArgInfo classifyReturnType(QualType RetTy, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 743 |                                 ASTContext &Context, | 
 | 744 |                                 llvm::LLVMContext &VMContext) const; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 745 |  | 
 | 746 |   ABIArgInfo classifyArgumentType(QualType Ty, | 
 | 747 |                                   ASTContext &Context, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 748 |                                   llvm::LLVMContext &VMContext, | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 749 |                                   unsigned &neededInt, | 
 | 750 |                                   unsigned &neededSSE) const; | 
 | 751 |  | 
 | 752 | public: | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 753 |   virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context, | 
| Chris Lattner | 8640cd6 | 2010-06-29 01:08:48 +0000 | [diff] [blame^] | 754 |                            llvm::LLVMContext &VMContext, | 
 | 755 |                            const llvm::Type *const *PrefTypes, | 
 | 756 |                            unsigned NumPrefTypes) const; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 757 |  | 
 | 758 |   virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, | 
 | 759 |                                  CodeGenFunction &CGF) const; | 
 | 760 | }; | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 761 |  | 
 | 762 | class X86_64TargetCodeGenInfo : public TargetCodeGenInfo { | 
 | 763 | public: | 
| Douglas Gregor | 568bb2d | 2010-01-22 15:41:14 +0000 | [diff] [blame] | 764 |   X86_64TargetCodeGenInfo():TargetCodeGenInfo(new X86_64ABIInfo()) {} | 
| John McCall | 6374c33 | 2010-03-06 00:35:14 +0000 | [diff] [blame] | 765 |  | 
 | 766 |   int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const { | 
 | 767 |     return 7; | 
 | 768 |   } | 
 | 769 |  | 
 | 770 |   bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, | 
 | 771 |                                llvm::Value *Address) const { | 
 | 772 |     CodeGen::CGBuilderTy &Builder = CGF.Builder; | 
 | 773 |     llvm::LLVMContext &Context = CGF.getLLVMContext(); | 
 | 774 |  | 
 | 775 |     const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context); | 
 | 776 |     llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8); | 
 | 777 |        | 
| John McCall | aeeb701 | 2010-05-27 06:19:26 +0000 | [diff] [blame] | 778 |     // 0-15 are the 16 integer registers. | 
 | 779 |     // 16 is %rip. | 
 | 780 |     AssignToArrayRange(Builder, Address, Eight8, 0, 16); | 
| John McCall | 6374c33 | 2010-03-06 00:35:14 +0000 | [diff] [blame] | 781 |  | 
 | 782 |     return false; | 
 | 783 |   } | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 784 | }; | 
 | 785 |  | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 786 | } | 
 | 787 |  | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 788 | X86_64ABIInfo::Class X86_64ABIInfo::merge(Class Accum, Class Field) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 789 |   // AMD64-ABI 3.2.3p2: Rule 4. Each field of an object is | 
 | 790 |   // classified recursively so that always two fields are | 
 | 791 |   // considered. The resulting class is calculated according to | 
 | 792 |   // the classes of the fields in the eightbyte: | 
 | 793 |   // | 
 | 794 |   // (a) If both classes are equal, this is the resulting class. | 
 | 795 |   // | 
 | 796 |   // (b) If one of the classes is NO_CLASS, the resulting class is | 
 | 797 |   // the other class. | 
 | 798 |   // | 
 | 799 |   // (c) If one of the classes is MEMORY, the result is the MEMORY | 
 | 800 |   // class. | 
 | 801 |   // | 
 | 802 |   // (d) If one of the classes is INTEGER, the result is the | 
 | 803 |   // INTEGER. | 
 | 804 |   // | 
 | 805 |   // (e) If one of the classes is X87, X87UP, COMPLEX_X87 class, | 
 | 806 |   // MEMORY is used as class. | 
 | 807 |   // | 
 | 808 |   // (f) Otherwise class SSE is used. | 
 | 809 |  | 
 | 810 |   // Accum should never be memory (we should have returned) or | 
 | 811 |   // ComplexX87 (because this cannot be passed in a structure). | 
 | 812 |   assert((Accum != Memory && Accum != ComplexX87) && | 
 | 813 |          "Invalid accumulated classification during merge."); | 
 | 814 |   if (Accum == Field || Field == NoClass) | 
 | 815 |     return Accum; | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 816 |   if (Field == Memory) | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 817 |     return Memory; | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 818 |   if (Accum == NoClass) | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 819 |     return Field; | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 820 |   if (Accum == Integer || Field == Integer) | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 821 |     return Integer; | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 822 |   if (Field == X87 || Field == X87Up || Field == ComplexX87 || | 
 | 823 |       Accum == X87 || Accum == X87Up) | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 824 |     return Memory; | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 825 |   return SSE; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 826 | } | 
 | 827 |  | 
 | 828 | void X86_64ABIInfo::classify(QualType Ty, | 
 | 829 |                              ASTContext &Context, | 
 | 830 |                              uint64_t OffsetBase, | 
 | 831 |                              Class &Lo, Class &Hi) const { | 
 | 832 |   // FIXME: This code can be simplified by introducing a simple value class for | 
 | 833 |   // Class pairs with appropriate constructor methods for the various | 
 | 834 |   // situations. | 
 | 835 |  | 
 | 836 |   // FIXME: Some of the split computations are wrong; unaligned vectors | 
 | 837 |   // shouldn't be passed in registers for example, so there is no chance they | 
 | 838 |   // can straddle an eightbyte. Verify & simplify. | 
 | 839 |  | 
 | 840 |   Lo = Hi = NoClass; | 
 | 841 |  | 
 | 842 |   Class &Current = OffsetBase < 64 ? Lo : Hi; | 
 | 843 |   Current = Memory; | 
 | 844 |  | 
| John McCall | 183700f | 2009-09-21 23:43:11 +0000 | [diff] [blame] | 845 |   if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 846 |     BuiltinType::Kind k = BT->getKind(); | 
 | 847 |  | 
 | 848 |     if (k == BuiltinType::Void) { | 
 | 849 |       Current = NoClass; | 
 | 850 |     } else if (k == BuiltinType::Int128 || k == BuiltinType::UInt128) { | 
 | 851 |       Lo = Integer; | 
 | 852 |       Hi = Integer; | 
 | 853 |     } else if (k >= BuiltinType::Bool && k <= BuiltinType::LongLong) { | 
 | 854 |       Current = Integer; | 
 | 855 |     } else if (k == BuiltinType::Float || k == BuiltinType::Double) { | 
 | 856 |       Current = SSE; | 
 | 857 |     } else if (k == BuiltinType::LongDouble) { | 
 | 858 |       Lo = X87; | 
 | 859 |       Hi = X87Up; | 
 | 860 |     } | 
 | 861 |     // FIXME: _Decimal32 and _Decimal64 are SSE. | 
 | 862 |     // FIXME: _float128 and _Decimal128 are (SSE, SSEUp). | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 863 |     return; | 
 | 864 |   } | 
 | 865 |    | 
 | 866 |   if (const EnumType *ET = Ty->getAs<EnumType>()) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 867 |     // Classify the underlying integer type. | 
 | 868 |     classify(ET->getDecl()->getIntegerType(), Context, OffsetBase, Lo, Hi); | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 869 |     return; | 
 | 870 |   } | 
 | 871 |    | 
 | 872 |   if (Ty->hasPointerRepresentation()) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 873 |     Current = Integer; | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 874 |     return; | 
 | 875 |   } | 
 | 876 |    | 
 | 877 |   if (Ty->isMemberPointerType()) { | 
| Daniel Dunbar | 67d438d | 2010-05-15 00:00:37 +0000 | [diff] [blame] | 878 |     if (Ty->isMemberFunctionPointerType()) | 
 | 879 |       Lo = Hi = Integer; | 
 | 880 |     else | 
 | 881 |       Current = Integer; | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 882 |     return; | 
 | 883 |   } | 
 | 884 |    | 
 | 885 |   if (const VectorType *VT = Ty->getAs<VectorType>()) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 886 |     uint64_t Size = Context.getTypeSize(VT); | 
 | 887 |     if (Size == 32) { | 
 | 888 |       // gcc passes all <4 x char>, <2 x short>, <1 x int>, <1 x | 
 | 889 |       // float> as integer. | 
 | 890 |       Current = Integer; | 
 | 891 |  | 
 | 892 |       // If this type crosses an eightbyte boundary, it should be | 
 | 893 |       // split. | 
 | 894 |       uint64_t EB_Real = (OffsetBase) / 64; | 
 | 895 |       uint64_t EB_Imag = (OffsetBase + Size - 1) / 64; | 
 | 896 |       if (EB_Real != EB_Imag) | 
 | 897 |         Hi = Lo; | 
 | 898 |     } else if (Size == 64) { | 
 | 899 |       // gcc passes <1 x double> in memory. :( | 
 | 900 |       if (VT->getElementType()->isSpecificBuiltinType(BuiltinType::Double)) | 
 | 901 |         return; | 
 | 902 |  | 
 | 903 |       // gcc passes <1 x long long> as INTEGER. | 
 | 904 |       if (VT->getElementType()->isSpecificBuiltinType(BuiltinType::LongLong)) | 
 | 905 |         Current = Integer; | 
 | 906 |       else | 
 | 907 |         Current = SSE; | 
 | 908 |  | 
 | 909 |       // If this type crosses an eightbyte boundary, it should be | 
 | 910 |       // split. | 
 | 911 |       if (OffsetBase && OffsetBase != 64) | 
 | 912 |         Hi = Lo; | 
 | 913 |     } else if (Size == 128) { | 
 | 914 |       Lo = SSE; | 
 | 915 |       Hi = SSEUp; | 
 | 916 |     } | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 917 |     return; | 
 | 918 |   } | 
 | 919 |    | 
 | 920 |   if (const ComplexType *CT = Ty->getAs<ComplexType>()) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 921 |     QualType ET = Context.getCanonicalType(CT->getElementType()); | 
 | 922 |  | 
 | 923 |     uint64_t Size = Context.getTypeSize(Ty); | 
| Douglas Gregor | 2ade35e | 2010-06-16 00:17:44 +0000 | [diff] [blame] | 924 |     if (ET->isIntegralOrEnumerationType()) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 925 |       if (Size <= 64) | 
 | 926 |         Current = Integer; | 
 | 927 |       else if (Size <= 128) | 
 | 928 |         Lo = Hi = Integer; | 
 | 929 |     } else if (ET == Context.FloatTy) | 
 | 930 |       Current = SSE; | 
 | 931 |     else if (ET == Context.DoubleTy) | 
 | 932 |       Lo = Hi = SSE; | 
 | 933 |     else if (ET == Context.LongDoubleTy) | 
 | 934 |       Current = ComplexX87; | 
 | 935 |  | 
 | 936 |     // If this complex type crosses an eightbyte boundary then it | 
 | 937 |     // should be split. | 
 | 938 |     uint64_t EB_Real = (OffsetBase) / 64; | 
 | 939 |     uint64_t EB_Imag = (OffsetBase + Context.getTypeSize(ET)) / 64; | 
 | 940 |     if (Hi == NoClass && EB_Real != EB_Imag) | 
 | 941 |       Hi = Lo; | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 942 |      | 
 | 943 |     return; | 
 | 944 |   } | 
 | 945 |    | 
 | 946 |   if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 947 |     // Arrays are treated like structures. | 
 | 948 |  | 
 | 949 |     uint64_t Size = Context.getTypeSize(Ty); | 
 | 950 |  | 
 | 951 |     // AMD64-ABI 3.2.3p2: Rule 1. If the size of an object is larger | 
 | 952 |     // than two eightbytes, ..., it has class MEMORY. | 
 | 953 |     if (Size > 128) | 
 | 954 |       return; | 
 | 955 |  | 
 | 956 |     // AMD64-ABI 3.2.3p2: Rule 1. If ..., or it contains unaligned | 
 | 957 |     // fields, it has class MEMORY. | 
 | 958 |     // | 
 | 959 |     // Only need to check alignment of array base. | 
 | 960 |     if (OffsetBase % Context.getTypeAlign(AT->getElementType())) | 
 | 961 |       return; | 
 | 962 |  | 
 | 963 |     // Otherwise implement simplified merge. We could be smarter about | 
 | 964 |     // this, but it isn't worth it and would be harder to verify. | 
 | 965 |     Current = NoClass; | 
 | 966 |     uint64_t EltSize = Context.getTypeSize(AT->getElementType()); | 
 | 967 |     uint64_t ArraySize = AT->getSize().getZExtValue(); | 
 | 968 |     for (uint64_t i=0, Offset=OffsetBase; i<ArraySize; ++i, Offset += EltSize) { | 
 | 969 |       Class FieldLo, FieldHi; | 
 | 970 |       classify(AT->getElementType(), Context, Offset, FieldLo, FieldHi); | 
 | 971 |       Lo = merge(Lo, FieldLo); | 
 | 972 |       Hi = merge(Hi, FieldHi); | 
 | 973 |       if (Lo == Memory || Hi == Memory) | 
 | 974 |         break; | 
 | 975 |     } | 
 | 976 |  | 
 | 977 |     // Do post merger cleanup (see below). Only case we worry about is Memory. | 
 | 978 |     if (Hi == Memory) | 
 | 979 |       Lo = Memory; | 
 | 980 |     assert((Hi != SSEUp || Lo == SSE) && "Invalid SSEUp array classification."); | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 981 |     return; | 
 | 982 |   } | 
 | 983 |    | 
 | 984 |   if (const RecordType *RT = Ty->getAs<RecordType>()) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 985 |     uint64_t Size = Context.getTypeSize(Ty); | 
 | 986 |  | 
 | 987 |     // AMD64-ABI 3.2.3p2: Rule 1. If the size of an object is larger | 
 | 988 |     // than two eightbytes, ..., it has class MEMORY. | 
 | 989 |     if (Size > 128) | 
 | 990 |       return; | 
 | 991 |  | 
| Anders Carlsson | 0a8f847 | 2009-09-16 15:53:40 +0000 | [diff] [blame] | 992 |     // AMD64-ABI 3.2.3p2: Rule 2. If a C++ object has either a non-trivial | 
 | 993 |     // copy constructor or a non-trivial destructor, it is passed by invisible | 
 | 994 |     // reference. | 
 | 995 |     if (hasNonTrivialDestructorOrCopyConstructor(RT)) | 
 | 996 |       return; | 
| Daniel Dunbar | ce9f423 | 2009-11-22 23:01:23 +0000 | [diff] [blame] | 997 |  | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 998 |     const RecordDecl *RD = RT->getDecl(); | 
 | 999 |  | 
 | 1000 |     // Assume variable sized types are passed in memory. | 
 | 1001 |     if (RD->hasFlexibleArrayMember()) | 
 | 1002 |       return; | 
 | 1003 |  | 
 | 1004 |     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); | 
 | 1005 |  | 
 | 1006 |     // Reset Lo class, this will be recomputed. | 
 | 1007 |     Current = NoClass; | 
| Daniel Dunbar | ce9f423 | 2009-11-22 23:01:23 +0000 | [diff] [blame] | 1008 |  | 
 | 1009 |     // If this is a C++ record, classify the bases first. | 
 | 1010 |     if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { | 
 | 1011 |       for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(), | 
 | 1012 |              e = CXXRD->bases_end(); i != e; ++i) { | 
 | 1013 |         assert(!i->isVirtual() && !i->getType()->isDependentType() && | 
 | 1014 |                "Unexpected base class!"); | 
 | 1015 |         const CXXRecordDecl *Base = | 
 | 1016 |           cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); | 
 | 1017 |  | 
 | 1018 |         // Classify this field. | 
 | 1019 |         // | 
 | 1020 |         // AMD64-ABI 3.2.3p2: Rule 3. If the size of the aggregate exceeds a | 
 | 1021 |         // single eightbyte, each is classified separately. Each eightbyte gets | 
 | 1022 |         // initialized to class NO_CLASS. | 
 | 1023 |         Class FieldLo, FieldHi; | 
 | 1024 |         uint64_t Offset = OffsetBase + Layout.getBaseClassOffset(Base); | 
 | 1025 |         classify(i->getType(), Context, Offset, FieldLo, FieldHi); | 
 | 1026 |         Lo = merge(Lo, FieldLo); | 
 | 1027 |         Hi = merge(Hi, FieldHi); | 
 | 1028 |         if (Lo == Memory || Hi == Memory) | 
 | 1029 |           break; | 
 | 1030 |       } | 
| Daniel Dunbar | 4971ff8 | 2009-12-22 01:19:25 +0000 | [diff] [blame] | 1031 |  | 
 | 1032 |       // If this record has no fields but isn't empty, classify as INTEGER. | 
 | 1033 |       if (RD->field_empty() && Size) | 
 | 1034 |         Current = Integer; | 
| Daniel Dunbar | ce9f423 | 2009-11-22 23:01:23 +0000 | [diff] [blame] | 1035 |     } | 
 | 1036 |  | 
 | 1037 |     // Classify the fields one at a time, merging the results. | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1038 |     unsigned idx = 0; | 
| Argyrios Kyrtzidis | 17945a0 | 2009-06-30 02:36:12 +0000 | [diff] [blame] | 1039 |     for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); | 
 | 1040 |            i != e; ++i, ++idx) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1041 |       uint64_t Offset = OffsetBase + Layout.getFieldOffset(idx); | 
 | 1042 |       bool BitField = i->isBitField(); | 
 | 1043 |  | 
 | 1044 |       // AMD64-ABI 3.2.3p2: Rule 1. If ..., or it contains unaligned | 
 | 1045 |       // fields, it has class MEMORY. | 
 | 1046 |       // | 
 | 1047 |       // Note, skip this test for bit-fields, see below. | 
 | 1048 |       if (!BitField && Offset % Context.getTypeAlign(i->getType())) { | 
 | 1049 |         Lo = Memory; | 
 | 1050 |         return; | 
 | 1051 |       } | 
 | 1052 |  | 
 | 1053 |       // Classify this field. | 
 | 1054 |       // | 
 | 1055 |       // AMD64-ABI 3.2.3p2: Rule 3. If the size of the aggregate | 
 | 1056 |       // exceeds a single eightbyte, each is classified | 
 | 1057 |       // separately. Each eightbyte gets initialized to class | 
 | 1058 |       // NO_CLASS. | 
 | 1059 |       Class FieldLo, FieldHi; | 
 | 1060 |  | 
 | 1061 |       // Bit-fields require special handling, they do not force the | 
 | 1062 |       // structure to be passed in memory even if unaligned, and | 
 | 1063 |       // therefore they can straddle an eightbyte. | 
 | 1064 |       if (BitField) { | 
 | 1065 |         // Ignore padding bit-fields. | 
 | 1066 |         if (i->isUnnamedBitfield()) | 
 | 1067 |           continue; | 
 | 1068 |  | 
 | 1069 |         uint64_t Offset = OffsetBase + Layout.getFieldOffset(idx); | 
 | 1070 |         uint64_t Size = i->getBitWidth()->EvaluateAsInt(Context).getZExtValue(); | 
 | 1071 |  | 
 | 1072 |         uint64_t EB_Lo = Offset / 64; | 
 | 1073 |         uint64_t EB_Hi = (Offset + Size - 1) / 64; | 
 | 1074 |         FieldLo = FieldHi = NoClass; | 
 | 1075 |         if (EB_Lo) { | 
 | 1076 |           assert(EB_Hi == EB_Lo && "Invalid classification, type > 16 bytes."); | 
 | 1077 |           FieldLo = NoClass; | 
 | 1078 |           FieldHi = Integer; | 
 | 1079 |         } else { | 
 | 1080 |           FieldLo = Integer; | 
 | 1081 |           FieldHi = EB_Hi ? Integer : NoClass; | 
 | 1082 |         } | 
 | 1083 |       } else | 
 | 1084 |         classify(i->getType(), Context, Offset, FieldLo, FieldHi); | 
 | 1085 |       Lo = merge(Lo, FieldLo); | 
 | 1086 |       Hi = merge(Hi, FieldHi); | 
 | 1087 |       if (Lo == Memory || Hi == Memory) | 
 | 1088 |         break; | 
 | 1089 |     } | 
 | 1090 |  | 
 | 1091 |     // AMD64-ABI 3.2.3p2: Rule 5. Then a post merger cleanup is done: | 
 | 1092 |     // | 
 | 1093 |     // (a) If one of the classes is MEMORY, the whole argument is | 
 | 1094 |     // passed in memory. | 
 | 1095 |     // | 
 | 1096 |     // (b) If SSEUP is not preceeded by SSE, it is converted to SSE. | 
 | 1097 |  | 
 | 1098 |     // The first of these conditions is guaranteed by how we implement | 
 | 1099 |     // the merge (just bail). | 
 | 1100 |     // | 
 | 1101 |     // The second condition occurs in the case of unions; for example | 
 | 1102 |     // union { _Complex double; unsigned; }. | 
 | 1103 |     if (Hi == Memory) | 
 | 1104 |       Lo = Memory; | 
 | 1105 |     if (Hi == SSEUp && Lo != SSE) | 
 | 1106 |       Hi = SSE; | 
 | 1107 |   } | 
 | 1108 | } | 
 | 1109 |  | 
 | 1110 | ABIArgInfo X86_64ABIInfo::getCoerceResult(QualType Ty, | 
 | 1111 |                                           const llvm::Type *CoerceTo, | 
 | 1112 |                                           ASTContext &Context) const { | 
| Chris Lattner | 7f215c1 | 2010-06-26 21:52:32 +0000 | [diff] [blame] | 1113 |   if (CoerceTo->isIntegerTy(64)) { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1114 |     // Integer and pointer types will end up in a general purpose | 
 | 1115 |     // register. | 
| Douglas Gregor | aa74a1e | 2010-02-02 20:10:50 +0000 | [diff] [blame] | 1116 |  | 
 | 1117 |     // Treat an enum type as its underlying type. | 
 | 1118 |     if (const EnumType *EnumTy = Ty->getAs<EnumType>()) | 
 | 1119 |       Ty = EnumTy->getDecl()->getIntegerType(); | 
 | 1120 |  | 
| Douglas Gregor | 9d3347a | 2010-06-16 00:35:25 +0000 | [diff] [blame] | 1121 |     if (Ty->isIntegralOrEnumerationType() || Ty->hasPointerRepresentation()) | 
| Anton Korobeynikov | cc6fa88 | 2009-06-06 09:36:29 +0000 | [diff] [blame] | 1122 |       return (Ty->isPromotableIntegerType() ? | 
 | 1123 |               ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); | 
| Chris Lattner | faf23b7 | 2010-06-28 19:56:59 +0000 | [diff] [blame] | 1124 |      | 
| Chris Lattner | 8ff2964 | 2010-06-28 21:59:07 +0000 | [diff] [blame] | 1125 |     // If this is a 8/16/32-bit structure that is passed as an int64, then it | 
 | 1126 |     // will be passed in the low 8/16/32-bits of a 64-bit GPR, which is the same | 
 | 1127 |     // as how an i8/i16/i32 is passed.  Coerce to a i8/i16/i32 instead of a i64. | 
 | 1128 |     switch (Context.getTypeSizeInChars(Ty).getQuantity()) { | 
 | 1129 |     default: break; | 
 | 1130 |     case 1: CoerceTo = llvm::Type::getInt8Ty(CoerceTo->getContext()); break; | 
 | 1131 |     case 2: CoerceTo = llvm::Type::getInt16Ty(CoerceTo->getContext()); break; | 
 | 1132 |     case 4: CoerceTo = llvm::Type::getInt32Ty(CoerceTo->getContext()); break; | 
 | 1133 |     } | 
| Chris Lattner | faf23b7 | 2010-06-28 19:56:59 +0000 | [diff] [blame] | 1134 |      | 
| Chris Lattner | 7f215c1 | 2010-06-26 21:52:32 +0000 | [diff] [blame] | 1135 |   } else if (CoerceTo->isDoubleTy()) { | 
| John McCall | 0b0ef0a | 2010-02-24 07:14:12 +0000 | [diff] [blame] | 1136 |     assert(Ty.isCanonical() && "should always have a canonical type here"); | 
 | 1137 |     assert(!Ty.hasQualifiers() && "should never have a qualified type here"); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1138 |  | 
 | 1139 |     // Float and double end up in a single SSE reg. | 
| John McCall | 0b0ef0a | 2010-02-24 07:14:12 +0000 | [diff] [blame] | 1140 |     if (Ty == Context.FloatTy || Ty == Context.DoubleTy) | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1141 |       return ABIArgInfo::getDirect(); | 
 | 1142 |  | 
| Chris Lattner | faf23b7 | 2010-06-28 19:56:59 +0000 | [diff] [blame] | 1143 |     // If this is a 32-bit structure that is passed as a double, then it will be | 
 | 1144 |     // passed in the low 32-bits of the XMM register, which is the same as how a | 
 | 1145 |     // float is passed.  Coerce to a float instead of a double. | 
 | 1146 |     if (Context.getTypeSizeInChars(Ty).getQuantity() == 4) | 
 | 1147 |       CoerceTo = llvm::Type::getFloatTy(CoerceTo->getContext()); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1148 |   } | 
 | 1149 |  | 
 | 1150 |   return ABIArgInfo::getCoerce(CoerceTo); | 
 | 1151 | } | 
 | 1152 |  | 
| Daniel Dunbar | 46c54fb | 2010-04-21 19:49:55 +0000 | [diff] [blame] | 1153 | ABIArgInfo X86_64ABIInfo::getIndirectReturnResult(QualType Ty, | 
 | 1154 |                                                   ASTContext &Context) const { | 
 | 1155 |   // If this is a scalar LLVM value then assume LLVM will pass it in the right | 
 | 1156 |   // place naturally. | 
 | 1157 |   if (!CodeGenFunction::hasAggregateLLVMType(Ty)) { | 
 | 1158 |     // Treat an enum type as its underlying type. | 
 | 1159 |     if (const EnumType *EnumTy = Ty->getAs<EnumType>()) | 
 | 1160 |       Ty = EnumTy->getDecl()->getIntegerType(); | 
 | 1161 |  | 
 | 1162 |     return (Ty->isPromotableIntegerType() ? | 
 | 1163 |             ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); | 
 | 1164 |   } | 
 | 1165 |  | 
 | 1166 |   return ABIArgInfo::getIndirect(0); | 
 | 1167 | } | 
 | 1168 |  | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1169 | ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty, | 
 | 1170 |                                             ASTContext &Context) const { | 
 | 1171 |   // If this is a scalar LLVM value then assume LLVM will pass it in the right | 
 | 1172 |   // place naturally. | 
| Douglas Gregor | aa74a1e | 2010-02-02 20:10:50 +0000 | [diff] [blame] | 1173 |   if (!CodeGenFunction::hasAggregateLLVMType(Ty)) { | 
 | 1174 |     // Treat an enum type as its underlying type. | 
 | 1175 |     if (const EnumType *EnumTy = Ty->getAs<EnumType>()) | 
 | 1176 |       Ty = EnumTy->getDecl()->getIntegerType(); | 
 | 1177 |  | 
| Anton Korobeynikov | cc6fa88 | 2009-06-06 09:36:29 +0000 | [diff] [blame] | 1178 |     return (Ty->isPromotableIntegerType() ? | 
 | 1179 |             ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); | 
| Douglas Gregor | aa74a1e | 2010-02-02 20:10:50 +0000 | [diff] [blame] | 1180 |   } | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1181 |  | 
| Daniel Dunbar | 46c54fb | 2010-04-21 19:49:55 +0000 | [diff] [blame] | 1182 |   if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) | 
 | 1183 |     return ABIArgInfo::getIndirect(0, /*ByVal=*/false); | 
| Anders Carlsson | 0a8f847 | 2009-09-16 15:53:40 +0000 | [diff] [blame] | 1184 |  | 
| Daniel Dunbar | 46c54fb | 2010-04-21 19:49:55 +0000 | [diff] [blame] | 1185 |   // Compute the byval alignment. We trust the back-end to honor the | 
 | 1186 |   // minimum ABI alignment for byval, to make cleaner IR. | 
 | 1187 |   const unsigned MinABIAlign = 8; | 
 | 1188 |   unsigned Align = Context.getTypeAlign(Ty) / 8; | 
 | 1189 |   if (Align > MinABIAlign) | 
 | 1190 |     return ABIArgInfo::getIndirect(Align); | 
 | 1191 |   return ABIArgInfo::getIndirect(0); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1192 | } | 
 | 1193 |  | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 1194 | ABIArgInfo X86_64ABIInfo:: | 
 | 1195 | classifyReturnType(QualType RetTy, ASTContext &Context, | 
 | 1196 |                    llvm::LLVMContext &VMContext) const { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1197 |   // AMD64-ABI 3.2.3p4: Rule 1. Classify the return type with the | 
 | 1198 |   // classification algorithm. | 
 | 1199 |   X86_64ABIInfo::Class Lo, Hi; | 
 | 1200 |   classify(RetTy, Context, 0, Lo, Hi); | 
 | 1201 |  | 
 | 1202 |   // Check some invariants. | 
 | 1203 |   assert((Hi != Memory || Lo == Memory) && "Invalid memory classification."); | 
 | 1204 |   assert((Lo != NoClass || Hi == NoClass) && "Invalid null classification."); | 
 | 1205 |   assert((Hi != SSEUp || Lo == SSE) && "Invalid SSEUp classification."); | 
 | 1206 |  | 
 | 1207 |   const llvm::Type *ResType = 0; | 
 | 1208 |   switch (Lo) { | 
 | 1209 |   case NoClass: | 
 | 1210 |     return ABIArgInfo::getIgnore(); | 
 | 1211 |  | 
 | 1212 |   case SSEUp: | 
 | 1213 |   case X87Up: | 
 | 1214 |     assert(0 && "Invalid classification for lo word."); | 
 | 1215 |  | 
 | 1216 |     // AMD64-ABI 3.2.3p4: Rule 2. Types of class memory are returned via | 
 | 1217 |     // hidden argument. | 
 | 1218 |   case Memory: | 
| Daniel Dunbar | 46c54fb | 2010-04-21 19:49:55 +0000 | [diff] [blame] | 1219 |     return getIndirectReturnResult(RetTy, Context); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1220 |  | 
 | 1221 |     // AMD64-ABI 3.2.3p4: Rule 3. If the class is INTEGER, the next | 
 | 1222 |     // available register of the sequence %rax, %rdx is used. | 
 | 1223 |   case Integer: | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 1224 |     ResType = llvm::Type::getInt64Ty(VMContext); break; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1225 |  | 
 | 1226 |     // AMD64-ABI 3.2.3p4: Rule 4. If the class is SSE, the next | 
 | 1227 |     // available SSE register of the sequence %xmm0, %xmm1 is used. | 
 | 1228 |   case SSE: | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 1229 |     ResType = llvm::Type::getDoubleTy(VMContext); break; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1230 |  | 
 | 1231 |     // AMD64-ABI 3.2.3p4: Rule 6. If the class is X87, the value is | 
 | 1232 |     // returned on the X87 stack in %st0 as 80-bit x87 number. | 
 | 1233 |   case X87: | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 1234 |     ResType = llvm::Type::getX86_FP80Ty(VMContext); break; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1235 |  | 
 | 1236 |     // AMD64-ABI 3.2.3p4: Rule 8. If the class is COMPLEX_X87, the real | 
 | 1237 |     // part of the value is returned in %st0 and the imaginary part in | 
 | 1238 |     // %st1. | 
 | 1239 |   case ComplexX87: | 
 | 1240 |     assert(Hi == ComplexX87 && "Unexpected ComplexX87 classification."); | 
| Chris Lattner | 52d9ae3 | 2010-04-06 17:29:22 +0000 | [diff] [blame] | 1241 |     ResType = llvm::StructType::get(VMContext, | 
 | 1242 |                                     llvm::Type::getX86_FP80Ty(VMContext), | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 1243 |                                     llvm::Type::getX86_FP80Ty(VMContext), | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1244 |                                     NULL); | 
 | 1245 |     break; | 
 | 1246 |   } | 
 | 1247 |  | 
 | 1248 |   switch (Hi) { | 
 | 1249 |     // Memory was handled previously and X87 should | 
 | 1250 |     // never occur as a hi class. | 
 | 1251 |   case Memory: | 
 | 1252 |   case X87: | 
 | 1253 |     assert(0 && "Invalid classification for hi word."); | 
 | 1254 |  | 
 | 1255 |   case ComplexX87: // Previously handled. | 
 | 1256 |   case NoClass: break; | 
 | 1257 |  | 
 | 1258 |   case Integer: | 
| Owen Anderson | 47a434f | 2009-08-05 23:18:46 +0000 | [diff] [blame] | 1259 |     ResType = llvm::StructType::get(VMContext, ResType, | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 1260 |                                     llvm::Type::getInt64Ty(VMContext), NULL); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1261 |     break; | 
 | 1262 |   case SSE: | 
| Owen Anderson | 47a434f | 2009-08-05 23:18:46 +0000 | [diff] [blame] | 1263 |     ResType = llvm::StructType::get(VMContext, ResType, | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 1264 |                                     llvm::Type::getDoubleTy(VMContext), NULL); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1265 |     break; | 
 | 1266 |  | 
 | 1267 |     // AMD64-ABI 3.2.3p4: Rule 5. If the class is SSEUP, the eightbyte | 
 | 1268 |     // is passed in the upper half of the last used SSE register. | 
 | 1269 |     // | 
 | 1270 |     // SSEUP should always be preceeded by SSE, just widen. | 
 | 1271 |   case SSEUp: | 
 | 1272 |     assert(Lo == SSE && "Unexpected SSEUp classification."); | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 1273 |     ResType = llvm::VectorType::get(llvm::Type::getDoubleTy(VMContext), 2); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1274 |     break; | 
 | 1275 |  | 
 | 1276 |     // AMD64-ABI 3.2.3p4: Rule 7. If the class is X87UP, the value is | 
 | 1277 |     // returned together with the previous X87 value in %st0. | 
 | 1278 |   case X87Up: | 
 | 1279 |     // If X87Up is preceeded by X87, we don't need to do | 
 | 1280 |     // anything. However, in some cases with unions it may not be | 
 | 1281 |     // preceeded by X87. In such situations we follow gcc and pass the | 
 | 1282 |     // extra bits in an SSE reg. | 
 | 1283 |     if (Lo != X87) | 
| Owen Anderson | 47a434f | 2009-08-05 23:18:46 +0000 | [diff] [blame] | 1284 |       ResType = llvm::StructType::get(VMContext, ResType, | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 1285 |                                       llvm::Type::getDoubleTy(VMContext), NULL); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1286 |     break; | 
 | 1287 |   } | 
 | 1288 |  | 
 | 1289 |   return getCoerceResult(RetTy, ResType, Context); | 
 | 1290 | } | 
 | 1291 |  | 
 | 1292 | ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, ASTContext &Context, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1293 |                                                llvm::LLVMContext &VMContext, | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1294 |                                                unsigned &neededInt, | 
 | 1295 |                                                unsigned &neededSSE) const { | 
 | 1296 |   X86_64ABIInfo::Class Lo, Hi; | 
 | 1297 |   classify(Ty, Context, 0, Lo, Hi); | 
 | 1298 |  | 
 | 1299 |   // Check some invariants. | 
 | 1300 |   // FIXME: Enforce these by construction. | 
 | 1301 |   assert((Hi != Memory || Lo == Memory) && "Invalid memory classification."); | 
 | 1302 |   assert((Lo != NoClass || Hi == NoClass) && "Invalid null classification."); | 
 | 1303 |   assert((Hi != SSEUp || Lo == SSE) && "Invalid SSEUp classification."); | 
 | 1304 |  | 
 | 1305 |   neededInt = 0; | 
 | 1306 |   neededSSE = 0; | 
 | 1307 |   const llvm::Type *ResType = 0; | 
 | 1308 |   switch (Lo) { | 
 | 1309 |   case NoClass: | 
 | 1310 |     return ABIArgInfo::getIgnore(); | 
 | 1311 |  | 
 | 1312 |     // AMD64-ABI 3.2.3p3: Rule 1. If the class is MEMORY, pass the argument | 
 | 1313 |     // on the stack. | 
 | 1314 |   case Memory: | 
 | 1315 |  | 
 | 1316 |     // AMD64-ABI 3.2.3p3: Rule 5. If the class is X87, X87UP or | 
 | 1317 |     // COMPLEX_X87, it is passed in memory. | 
 | 1318 |   case X87: | 
 | 1319 |   case ComplexX87: | 
 | 1320 |     return getIndirectResult(Ty, Context); | 
 | 1321 |  | 
 | 1322 |   case SSEUp: | 
 | 1323 |   case X87Up: | 
 | 1324 |     assert(0 && "Invalid classification for lo word."); | 
 | 1325 |  | 
 | 1326 |     // AMD64-ABI 3.2.3p3: Rule 2. If the class is INTEGER, the next | 
 | 1327 |     // available register of the sequence %rdi, %rsi, %rdx, %rcx, %r8 | 
 | 1328 |     // and %r9 is used. | 
 | 1329 |   case Integer: | 
 | 1330 |     ++neededInt; | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 1331 |     ResType = llvm::Type::getInt64Ty(VMContext); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1332 |     break; | 
 | 1333 |  | 
 | 1334 |     // AMD64-ABI 3.2.3p3: Rule 3. If the class is SSE, the next | 
 | 1335 |     // available SSE register is used, the registers are taken in the | 
 | 1336 |     // order from %xmm0 to %xmm7. | 
 | 1337 |   case SSE: | 
 | 1338 |     ++neededSSE; | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 1339 |     ResType = llvm::Type::getDoubleTy(VMContext); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1340 |     break; | 
 | 1341 |   } | 
 | 1342 |  | 
 | 1343 |   switch (Hi) { | 
 | 1344 |     // Memory was handled previously, ComplexX87 and X87 should | 
 | 1345 |     // never occur as hi classes, and X87Up must be preceed by X87, | 
 | 1346 |     // which is passed in memory. | 
 | 1347 |   case Memory: | 
 | 1348 |   case X87: | 
 | 1349 |   case ComplexX87: | 
 | 1350 |     assert(0 && "Invalid classification for hi word."); | 
 | 1351 |     break; | 
 | 1352 |  | 
 | 1353 |   case NoClass: break; | 
 | 1354 |   case Integer: | 
| Owen Anderson | 47a434f | 2009-08-05 23:18:46 +0000 | [diff] [blame] | 1355 |     ResType = llvm::StructType::get(VMContext, ResType, | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 1356 |                                     llvm::Type::getInt64Ty(VMContext), NULL); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1357 |     ++neededInt; | 
 | 1358 |     break; | 
 | 1359 |  | 
 | 1360 |     // X87Up generally doesn't occur here (long double is passed in | 
 | 1361 |     // memory), except in situations involving unions. | 
 | 1362 |   case X87Up: | 
 | 1363 |   case SSE: | 
| Owen Anderson | 47a434f | 2009-08-05 23:18:46 +0000 | [diff] [blame] | 1364 |     ResType = llvm::StructType::get(VMContext, ResType, | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 1365 |                                     llvm::Type::getDoubleTy(VMContext), NULL); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1366 |     ++neededSSE; | 
 | 1367 |     break; | 
 | 1368 |  | 
 | 1369 |     // AMD64-ABI 3.2.3p3: Rule 4. If the class is SSEUP, the | 
 | 1370 |     // eightbyte is passed in the upper half of the last used SSE | 
 | 1371 |     // register. | 
 | 1372 |   case SSEUp: | 
 | 1373 |     assert(Lo == SSE && "Unexpected SSEUp classification."); | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 1374 |     ResType = llvm::VectorType::get(llvm::Type::getDoubleTy(VMContext), 2); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1375 |     break; | 
 | 1376 |   } | 
 | 1377 |  | 
 | 1378 |   return getCoerceResult(Ty, ResType, Context); | 
 | 1379 | } | 
 | 1380 |  | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1381 | void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context, | 
| Chris Lattner | 8640cd6 | 2010-06-29 01:08:48 +0000 | [diff] [blame^] | 1382 |                                 llvm::LLVMContext &VMContext, | 
 | 1383 |                                 const llvm::Type *const *PrefTypes, | 
 | 1384 |                                 unsigned NumPrefTypes) const { | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1385 |   FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), | 
 | 1386 |                                           Context, VMContext); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1387 |  | 
 | 1388 |   // Keep track of the number of assigned registers. | 
 | 1389 |   unsigned freeIntRegs = 6, freeSSERegs = 8; | 
 | 1390 |  | 
 | 1391 |   // If the return value is indirect, then the hidden argument is consuming one | 
 | 1392 |   // integer register. | 
 | 1393 |   if (FI.getReturnInfo().isIndirect()) | 
 | 1394 |     --freeIntRegs; | 
 | 1395 |  | 
 | 1396 |   // AMD64-ABI 3.2.3p3: Once arguments are classified, the registers | 
 | 1397 |   // get assigned (in left-to-right order) for passing as follows... | 
 | 1398 |   for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); | 
 | 1399 |        it != ie; ++it) { | 
 | 1400 |     unsigned neededInt, neededSSE; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1401 |     it->info = classifyArgumentType(it->type, Context, VMContext, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1402 |                                     neededInt, neededSSE); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1403 |  | 
 | 1404 |     // AMD64-ABI 3.2.3p3: If there are no registers available for any | 
 | 1405 |     // eightbyte of an argument, the whole argument is passed on the | 
 | 1406 |     // stack. If registers have already been assigned for some | 
 | 1407 |     // eightbytes of such an argument, the assignments get reverted. | 
 | 1408 |     if (freeIntRegs >= neededInt && freeSSERegs >= neededSSE) { | 
 | 1409 |       freeIntRegs -= neededInt; | 
 | 1410 |       freeSSERegs -= neededSSE; | 
 | 1411 |     } else { | 
 | 1412 |       it->info = getIndirectResult(it->type, Context); | 
 | 1413 |     } | 
 | 1414 |   } | 
 | 1415 | } | 
 | 1416 |  | 
 | 1417 | static llvm::Value *EmitVAArgFromMemory(llvm::Value *VAListAddr, | 
 | 1418 |                                         QualType Ty, | 
 | 1419 |                                         CodeGenFunction &CGF) { | 
 | 1420 |   llvm::Value *overflow_arg_area_p = | 
 | 1421 |     CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_p"); | 
 | 1422 |   llvm::Value *overflow_arg_area = | 
 | 1423 |     CGF.Builder.CreateLoad(overflow_arg_area_p, "overflow_arg_area"); | 
 | 1424 |  | 
 | 1425 |   // AMD64-ABI 3.5.7p5: Step 7. Align l->overflow_arg_area upwards to a 16 | 
 | 1426 |   // byte boundary if alignment needed by type exceeds 8 byte boundary. | 
 | 1427 |   uint64_t Align = CGF.getContext().getTypeAlign(Ty) / 8; | 
 | 1428 |   if (Align > 8) { | 
 | 1429 |     // Note that we follow the ABI & gcc here, even though the type | 
 | 1430 |     // could in theory have an alignment greater than 16. This case | 
 | 1431 |     // shouldn't ever matter in practice. | 
 | 1432 |  | 
 | 1433 |     // overflow_arg_area = (overflow_arg_area + 15) & ~15; | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 1434 |     llvm::Value *Offset = | 
| Chris Lattner | 77b89b8 | 2010-06-27 07:15:29 +0000 | [diff] [blame] | 1435 |       llvm::ConstantInt::get(CGF.Int32Ty, 15); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1436 |     overflow_arg_area = CGF.Builder.CreateGEP(overflow_arg_area, Offset); | 
 | 1437 |     llvm::Value *AsInt = CGF.Builder.CreatePtrToInt(overflow_arg_area, | 
| Chris Lattner | 77b89b8 | 2010-06-27 07:15:29 +0000 | [diff] [blame] | 1438 |                                                     CGF.Int64Ty); | 
 | 1439 |     llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int64Ty, ~15LL); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1440 |     overflow_arg_area = | 
 | 1441 |       CGF.Builder.CreateIntToPtr(CGF.Builder.CreateAnd(AsInt, Mask), | 
 | 1442 |                                  overflow_arg_area->getType(), | 
 | 1443 |                                  "overflow_arg_area.align"); | 
 | 1444 |   } | 
 | 1445 |  | 
 | 1446 |   // AMD64-ABI 3.5.7p5: Step 8. Fetch type from l->overflow_arg_area. | 
 | 1447 |   const llvm::Type *LTy = CGF.ConvertTypeForMem(Ty); | 
 | 1448 |   llvm::Value *Res = | 
 | 1449 |     CGF.Builder.CreateBitCast(overflow_arg_area, | 
| Owen Anderson | 96e0fc7 | 2009-07-29 22:16:19 +0000 | [diff] [blame] | 1450 |                               llvm::PointerType::getUnqual(LTy)); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1451 |  | 
 | 1452 |   // AMD64-ABI 3.5.7p5: Step 9. Set l->overflow_arg_area to: | 
 | 1453 |   // l->overflow_arg_area + sizeof(type). | 
 | 1454 |   // AMD64-ABI 3.5.7p5: Step 10. Align l->overflow_arg_area upwards to | 
 | 1455 |   // an 8 byte boundary. | 
 | 1456 |  | 
 | 1457 |   uint64_t SizeInBytes = (CGF.getContext().getTypeSize(Ty) + 7) / 8; | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 1458 |   llvm::Value *Offset = | 
| Chris Lattner | 77b89b8 | 2010-06-27 07:15:29 +0000 | [diff] [blame] | 1459 |       llvm::ConstantInt::get(CGF.Int32Ty, (SizeInBytes + 7)  & ~7); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1460 |   overflow_arg_area = CGF.Builder.CreateGEP(overflow_arg_area, Offset, | 
 | 1461 |                                             "overflow_arg_area.next"); | 
 | 1462 |   CGF.Builder.CreateStore(overflow_arg_area, overflow_arg_area_p); | 
 | 1463 |  | 
 | 1464 |   // AMD64-ABI 3.5.7p5: Step 11. Return the fetched type. | 
 | 1465 |   return Res; | 
 | 1466 | } | 
 | 1467 |  | 
 | 1468 | llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, | 
 | 1469 |                                       CodeGenFunction &CGF) const { | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1470 |   llvm::LLVMContext &VMContext = CGF.getLLVMContext(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1471 |  | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1472 |   // Assume that va_list type is correct; should be pointer to LLVM type: | 
 | 1473 |   // struct { | 
 | 1474 |   //   i32 gp_offset; | 
 | 1475 |   //   i32 fp_offset; | 
 | 1476 |   //   i8* overflow_arg_area; | 
 | 1477 |   //   i8* reg_save_area; | 
 | 1478 |   // }; | 
 | 1479 |   unsigned neededInt, neededSSE; | 
| Chris Lattner | a14db75 | 2010-03-11 18:19:55 +0000 | [diff] [blame] | 1480 |    | 
 | 1481 |   Ty = CGF.getContext().getCanonicalType(Ty); | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1482 |   ABIArgInfo AI = classifyArgumentType(Ty, CGF.getContext(), VMContext, | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1483 |                                        neededInt, neededSSE); | 
 | 1484 |  | 
 | 1485 |   // AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed | 
 | 1486 |   // in the registers. If not go to step 7. | 
 | 1487 |   if (!neededInt && !neededSSE) | 
 | 1488 |     return EmitVAArgFromMemory(VAListAddr, Ty, CGF); | 
 | 1489 |  | 
 | 1490 |   // AMD64-ABI 3.5.7p5: Step 2. Compute num_gp to hold the number of | 
 | 1491 |   // general purpose registers needed to pass type and num_fp to hold | 
 | 1492 |   // the number of floating point registers needed. | 
 | 1493 |  | 
 | 1494 |   // AMD64-ABI 3.5.7p5: Step 3. Verify whether arguments fit into | 
 | 1495 |   // registers. In the case: l->gp_offset > 48 - num_gp * 8 or | 
 | 1496 |   // l->fp_offset > 304 - num_fp * 16 go to step 7. | 
 | 1497 |   // | 
 | 1498 |   // NOTE: 304 is a typo, there are (6 * 8 + 8 * 16) = 176 bytes of | 
 | 1499 |   // register save space). | 
 | 1500 |  | 
 | 1501 |   llvm::Value *InRegs = 0; | 
 | 1502 |   llvm::Value *gp_offset_p = 0, *gp_offset = 0; | 
 | 1503 |   llvm::Value *fp_offset_p = 0, *fp_offset = 0; | 
 | 1504 |   if (neededInt) { | 
 | 1505 |     gp_offset_p = CGF.Builder.CreateStructGEP(VAListAddr, 0, "gp_offset_p"); | 
 | 1506 |     gp_offset = CGF.Builder.CreateLoad(gp_offset_p, "gp_offset"); | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 1507 |     InRegs = llvm::ConstantInt::get(CGF.Int32Ty, 48 - neededInt * 8); | 
 | 1508 |     InRegs = CGF.Builder.CreateICmpULE(gp_offset, InRegs, "fits_in_gp"); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1509 |   } | 
 | 1510 |  | 
 | 1511 |   if (neededSSE) { | 
 | 1512 |     fp_offset_p = CGF.Builder.CreateStructGEP(VAListAddr, 1, "fp_offset_p"); | 
 | 1513 |     fp_offset = CGF.Builder.CreateLoad(fp_offset_p, "fp_offset"); | 
 | 1514 |     llvm::Value *FitsInFP = | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 1515 |       llvm::ConstantInt::get(CGF.Int32Ty, 176 - neededSSE * 16); | 
 | 1516 |     FitsInFP = CGF.Builder.CreateICmpULE(fp_offset, FitsInFP, "fits_in_fp"); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1517 |     InRegs = InRegs ? CGF.Builder.CreateAnd(InRegs, FitsInFP) : FitsInFP; | 
 | 1518 |   } | 
 | 1519 |  | 
 | 1520 |   llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg"); | 
 | 1521 |   llvm::BasicBlock *InMemBlock = CGF.createBasicBlock("vaarg.in_mem"); | 
 | 1522 |   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("vaarg.end"); | 
 | 1523 |   CGF.Builder.CreateCondBr(InRegs, InRegBlock, InMemBlock); | 
 | 1524 |  | 
 | 1525 |   // Emit code to load the value if it was passed in registers. | 
 | 1526 |  | 
 | 1527 |   CGF.EmitBlock(InRegBlock); | 
 | 1528 |  | 
 | 1529 |   // AMD64-ABI 3.5.7p5: Step 4. Fetch type from l->reg_save_area with | 
 | 1530 |   // an offset of l->gp_offset and/or l->fp_offset. This may require | 
 | 1531 |   // copying to a temporary location in case the parameter is passed | 
 | 1532 |   // in different register classes or requires an alignment greater | 
 | 1533 |   // than 8 for general purpose registers and 16 for XMM registers. | 
 | 1534 |   // | 
 | 1535 |   // FIXME: This really results in shameful code when we end up needing to | 
 | 1536 |   // collect arguments from different places; often what should result in a | 
 | 1537 |   // simple assembling of a structure from scattered addresses has many more | 
 | 1538 |   // loads than necessary. Can we clean this up? | 
 | 1539 |   const llvm::Type *LTy = CGF.ConvertTypeForMem(Ty); | 
 | 1540 |   llvm::Value *RegAddr = | 
 | 1541 |     CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(VAListAddr, 3), | 
 | 1542 |                            "reg_save_area"); | 
 | 1543 |   if (neededInt && neededSSE) { | 
 | 1544 |     // FIXME: Cleanup. | 
 | 1545 |     assert(AI.isCoerce() && "Unexpected ABI info for mixed regs"); | 
 | 1546 |     const llvm::StructType *ST = cast<llvm::StructType>(AI.getCoerceToType()); | 
 | 1547 |     llvm::Value *Tmp = CGF.CreateTempAlloca(ST); | 
 | 1548 |     assert(ST->getNumElements() == 2 && "Unexpected ABI info for mixed regs"); | 
 | 1549 |     const llvm::Type *TyLo = ST->getElementType(0); | 
 | 1550 |     const llvm::Type *TyHi = ST->getElementType(1); | 
| Duncan Sands | f177d9d | 2010-02-15 16:14:01 +0000 | [diff] [blame] | 1551 |     assert((TyLo->isFloatingPointTy() ^ TyHi->isFloatingPointTy()) && | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1552 |            "Unexpected ABI info for mixed regs"); | 
| Owen Anderson | 96e0fc7 | 2009-07-29 22:16:19 +0000 | [diff] [blame] | 1553 |     const llvm::Type *PTyLo = llvm::PointerType::getUnqual(TyLo); | 
 | 1554 |     const llvm::Type *PTyHi = llvm::PointerType::getUnqual(TyHi); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1555 |     llvm::Value *GPAddr = CGF.Builder.CreateGEP(RegAddr, gp_offset); | 
 | 1556 |     llvm::Value *FPAddr = CGF.Builder.CreateGEP(RegAddr, fp_offset); | 
| Duncan Sands | f177d9d | 2010-02-15 16:14:01 +0000 | [diff] [blame] | 1557 |     llvm::Value *RegLoAddr = TyLo->isFloatingPointTy() ? FPAddr : GPAddr; | 
 | 1558 |     llvm::Value *RegHiAddr = TyLo->isFloatingPointTy() ? GPAddr : FPAddr; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1559 |     llvm::Value *V = | 
 | 1560 |       CGF.Builder.CreateLoad(CGF.Builder.CreateBitCast(RegLoAddr, PTyLo)); | 
 | 1561 |     CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 0)); | 
 | 1562 |     V = CGF.Builder.CreateLoad(CGF.Builder.CreateBitCast(RegHiAddr, PTyHi)); | 
 | 1563 |     CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 1)); | 
 | 1564 |  | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1565 |     RegAddr = CGF.Builder.CreateBitCast(Tmp, | 
| Owen Anderson | 96e0fc7 | 2009-07-29 22:16:19 +0000 | [diff] [blame] | 1566 |                                         llvm::PointerType::getUnqual(LTy)); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1567 |   } else if (neededInt) { | 
 | 1568 |     RegAddr = CGF.Builder.CreateGEP(RegAddr, gp_offset); | 
 | 1569 |     RegAddr = CGF.Builder.CreateBitCast(RegAddr, | 
| Owen Anderson | 96e0fc7 | 2009-07-29 22:16:19 +0000 | [diff] [blame] | 1570 |                                         llvm::PointerType::getUnqual(LTy)); | 
| Chris Lattner | dce5ad0 | 2010-06-28 20:05:43 +0000 | [diff] [blame] | 1571 |   } else if (neededSSE == 1) { | 
 | 1572 |     RegAddr = CGF.Builder.CreateGEP(RegAddr, fp_offset); | 
 | 1573 |     RegAddr = CGF.Builder.CreateBitCast(RegAddr, | 
 | 1574 |                                         llvm::PointerType::getUnqual(LTy)); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1575 |   } else { | 
| Chris Lattner | dce5ad0 | 2010-06-28 20:05:43 +0000 | [diff] [blame] | 1576 |     assert(neededSSE == 2 && "Invalid number of needed registers!"); | 
 | 1577 |     // SSE registers are spaced 16 bytes apart in the register save | 
 | 1578 |     // area, we need to collect the two eightbytes together. | 
 | 1579 |     llvm::Value *RegAddrLo = CGF.Builder.CreateGEP(RegAddr, fp_offset); | 
| Chris Lattner | 1090a9b | 2010-06-28 21:43:59 +0000 | [diff] [blame] | 1580 |     llvm::Value *RegAddrHi = CGF.Builder.CreateConstGEP1_32(RegAddrLo, 16); | 
| Chris Lattner | dce5ad0 | 2010-06-28 20:05:43 +0000 | [diff] [blame] | 1581 |     const llvm::Type *DoubleTy = llvm::Type::getDoubleTy(VMContext); | 
 | 1582 |     const llvm::Type *DblPtrTy = | 
 | 1583 |       llvm::PointerType::getUnqual(DoubleTy); | 
 | 1584 |     const llvm::StructType *ST = llvm::StructType::get(VMContext, DoubleTy, | 
 | 1585 |                                                        DoubleTy, NULL); | 
 | 1586 |     llvm::Value *V, *Tmp = CGF.CreateTempAlloca(ST); | 
 | 1587 |     V = CGF.Builder.CreateLoad(CGF.Builder.CreateBitCast(RegAddrLo, | 
 | 1588 |                                                          DblPtrTy)); | 
 | 1589 |     CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 0)); | 
 | 1590 |     V = CGF.Builder.CreateLoad(CGF.Builder.CreateBitCast(RegAddrHi, | 
 | 1591 |                                                          DblPtrTy)); | 
 | 1592 |     CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 1)); | 
 | 1593 |     RegAddr = CGF.Builder.CreateBitCast(Tmp, | 
 | 1594 |                                         llvm::PointerType::getUnqual(LTy)); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1595 |   } | 
 | 1596 |  | 
 | 1597 |   // AMD64-ABI 3.5.7p5: Step 5. Set: | 
 | 1598 |   // l->gp_offset = l->gp_offset + num_gp * 8 | 
 | 1599 |   // l->fp_offset = l->fp_offset + num_fp * 16. | 
 | 1600 |   if (neededInt) { | 
| Chris Lattner | 77b89b8 | 2010-06-27 07:15:29 +0000 | [diff] [blame] | 1601 |     llvm::Value *Offset = llvm::ConstantInt::get(CGF.Int32Ty, neededInt * 8); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1602 |     CGF.Builder.CreateStore(CGF.Builder.CreateAdd(gp_offset, Offset), | 
 | 1603 |                             gp_offset_p); | 
 | 1604 |   } | 
 | 1605 |   if (neededSSE) { | 
| Chris Lattner | 77b89b8 | 2010-06-27 07:15:29 +0000 | [diff] [blame] | 1606 |     llvm::Value *Offset = llvm::ConstantInt::get(CGF.Int32Ty, neededSSE * 16); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1607 |     CGF.Builder.CreateStore(CGF.Builder.CreateAdd(fp_offset, Offset), | 
 | 1608 |                             fp_offset_p); | 
 | 1609 |   } | 
 | 1610 |   CGF.EmitBranch(ContBlock); | 
 | 1611 |  | 
 | 1612 |   // Emit code to load the value if it was passed in memory. | 
 | 1613 |  | 
 | 1614 |   CGF.EmitBlock(InMemBlock); | 
 | 1615 |   llvm::Value *MemAddr = EmitVAArgFromMemory(VAListAddr, Ty, CGF); | 
 | 1616 |  | 
 | 1617 |   // Return the appropriate result. | 
 | 1618 |  | 
 | 1619 |   CGF.EmitBlock(ContBlock); | 
 | 1620 |   llvm::PHINode *ResAddr = CGF.Builder.CreatePHI(RegAddr->getType(), | 
 | 1621 |                                                  "vaarg.addr"); | 
 | 1622 |   ResAddr->reserveOperandSpace(2); | 
 | 1623 |   ResAddr->addIncoming(RegAddr, InRegBlock); | 
 | 1624 |   ResAddr->addIncoming(MemAddr, InMemBlock); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1625 |   return ResAddr; | 
 | 1626 | } | 
 | 1627 |  | 
| Chris Lattner | dce5ad0 | 2010-06-28 20:05:43 +0000 | [diff] [blame] | 1628 |  | 
 | 1629 |  | 
 | 1630 | //===----------------------------------------------------------------------===// | 
| Daniel Dunbar | 34d91fd | 2009-09-12 00:59:49 +0000 | [diff] [blame] | 1631 | // PIC16 ABI Implementation | 
| Chris Lattner | dce5ad0 | 2010-06-28 20:05:43 +0000 | [diff] [blame] | 1632 | //===----------------------------------------------------------------------===// | 
| Daniel Dunbar | 34d91fd | 2009-09-12 00:59:49 +0000 | [diff] [blame] | 1633 |  | 
 | 1634 | namespace { | 
 | 1635 |  | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1636 | class PIC16ABIInfo : public ABIInfo { | 
 | 1637 |   ABIArgInfo classifyReturnType(QualType RetTy, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1638 |                                 ASTContext &Context, | 
 | 1639 |                                 llvm::LLVMContext &VMContext) const; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1640 |  | 
 | 1641 |   ABIArgInfo classifyArgumentType(QualType RetTy, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1642 |                                   ASTContext &Context, | 
 | 1643 |                                   llvm::LLVMContext &VMContext) const; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1644 |  | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1645 |   virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context, | 
| Chris Lattner | 8640cd6 | 2010-06-29 01:08:48 +0000 | [diff] [blame^] | 1646 |                            llvm::LLVMContext &VMContext, | 
 | 1647 |                            const llvm::Type *const *PrefTypes, | 
 | 1648 |                            unsigned NumPrefTypes) const { | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1649 |     FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), Context, | 
 | 1650 |                                             VMContext); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1651 |     for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); | 
 | 1652 |          it != ie; ++it) | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1653 |       it->info = classifyArgumentType(it->type, Context, VMContext); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1654 |   } | 
 | 1655 |  | 
 | 1656 |   virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, | 
 | 1657 |                                  CodeGenFunction &CGF) const; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1658 | }; | 
 | 1659 |  | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 1660 | class PIC16TargetCodeGenInfo : public TargetCodeGenInfo { | 
 | 1661 | public: | 
| Douglas Gregor | 568bb2d | 2010-01-22 15:41:14 +0000 | [diff] [blame] | 1662 |   PIC16TargetCodeGenInfo():TargetCodeGenInfo(new PIC16ABIInfo()) {} | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 1663 | }; | 
 | 1664 |  | 
| Daniel Dunbar | 34d91fd | 2009-09-12 00:59:49 +0000 | [diff] [blame] | 1665 | } | 
 | 1666 |  | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1667 | ABIArgInfo PIC16ABIInfo::classifyReturnType(QualType RetTy, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1668 |                                             ASTContext &Context, | 
 | 1669 |                                           llvm::LLVMContext &VMContext) const { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1670 |   if (RetTy->isVoidType()) { | 
 | 1671 |     return ABIArgInfo::getIgnore(); | 
 | 1672 |   } else { | 
 | 1673 |     return ABIArgInfo::getDirect(); | 
 | 1674 |   } | 
 | 1675 | } | 
 | 1676 |  | 
 | 1677 | ABIArgInfo PIC16ABIInfo::classifyArgumentType(QualType Ty, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1678 |                                               ASTContext &Context, | 
 | 1679 |                                           llvm::LLVMContext &VMContext) const { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1680 |   return ABIArgInfo::getDirect(); | 
 | 1681 | } | 
 | 1682 |  | 
 | 1683 | llvm::Value *PIC16ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, | 
| Chris Lattner | 77b89b8 | 2010-06-27 07:15:29 +0000 | [diff] [blame] | 1684 |                                      CodeGenFunction &CGF) const { | 
| Chris Lattner | 52d9ae3 | 2010-04-06 17:29:22 +0000 | [diff] [blame] | 1685 |   const llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); | 
| Sanjiv Gupta | a446ecd | 2010-02-17 02:25:52 +0000 | [diff] [blame] | 1686 |   const llvm::Type *BPP = llvm::PointerType::getUnqual(BP); | 
 | 1687 |  | 
 | 1688 |   CGBuilderTy &Builder = CGF.Builder; | 
 | 1689 |   llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, | 
 | 1690 |                                                        "ap"); | 
 | 1691 |   llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur"); | 
 | 1692 |   llvm::Type *PTy = | 
 | 1693 |     llvm::PointerType::getUnqual(CGF.ConvertType(Ty)); | 
 | 1694 |   llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy); | 
 | 1695 |  | 
 | 1696 |   uint64_t Offset = CGF.getContext().getTypeSize(Ty) / 8; | 
 | 1697 |  | 
 | 1698 |   llvm::Value *NextAddr = | 
 | 1699 |     Builder.CreateGEP(Addr, llvm::ConstantInt::get( | 
 | 1700 |                           llvm::Type::getInt32Ty(CGF.getLLVMContext()), Offset), | 
 | 1701 |                       "ap.next"); | 
 | 1702 |   Builder.CreateStore(NextAddr, VAListAddrAsBPP); | 
 | 1703 |  | 
 | 1704 |   return AddrTyped; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1705 | } | 
 | 1706 |  | 
| Sanjiv Gupta | a446ecd | 2010-02-17 02:25:52 +0000 | [diff] [blame] | 1707 |  | 
| John McCall | ec853ba | 2010-03-11 00:10:12 +0000 | [diff] [blame] | 1708 | // PowerPC-32 | 
 | 1709 |  | 
 | 1710 | namespace { | 
 | 1711 | class PPC32TargetCodeGenInfo : public DefaultTargetCodeGenInfo { | 
 | 1712 | public: | 
 | 1713 |   int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const { | 
 | 1714 |     // This is recovered from gcc output. | 
 | 1715 |     return 1; // r1 is the dedicated stack pointer | 
 | 1716 |   } | 
 | 1717 |  | 
 | 1718 |   bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, | 
 | 1719 |                                llvm::Value *Address) const;   | 
 | 1720 | }; | 
 | 1721 |  | 
 | 1722 | } | 
 | 1723 |  | 
 | 1724 | bool | 
 | 1725 | PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, | 
 | 1726 |                                                 llvm::Value *Address) const { | 
 | 1727 |   // This is calculated from the LLVM and GCC tables and verified | 
 | 1728 |   // against gcc output.  AFAIK all ABIs use the same encoding. | 
 | 1729 |  | 
 | 1730 |   CodeGen::CGBuilderTy &Builder = CGF.Builder; | 
 | 1731 |   llvm::LLVMContext &Context = CGF.getLLVMContext(); | 
 | 1732 |  | 
 | 1733 |   const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context); | 
 | 1734 |   llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4); | 
 | 1735 |   llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8); | 
 | 1736 |   llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16); | 
 | 1737 |  | 
 | 1738 |   // 0-31: r0-31, the 4-byte general-purpose registers | 
| John McCall | aeeb701 | 2010-05-27 06:19:26 +0000 | [diff] [blame] | 1739 |   AssignToArrayRange(Builder, Address, Four8, 0, 31); | 
| John McCall | ec853ba | 2010-03-11 00:10:12 +0000 | [diff] [blame] | 1740 |  | 
 | 1741 |   // 32-63: fp0-31, the 8-byte floating-point registers | 
| John McCall | aeeb701 | 2010-05-27 06:19:26 +0000 | [diff] [blame] | 1742 |   AssignToArrayRange(Builder, Address, Eight8, 32, 63); | 
| John McCall | ec853ba | 2010-03-11 00:10:12 +0000 | [diff] [blame] | 1743 |  | 
 | 1744 |   // 64-76 are various 4-byte special-purpose registers: | 
 | 1745 |   // 64: mq | 
 | 1746 |   // 65: lr | 
 | 1747 |   // 66: ctr | 
 | 1748 |   // 67: ap | 
 | 1749 |   // 68-75 cr0-7 | 
 | 1750 |   // 76: xer | 
| John McCall | aeeb701 | 2010-05-27 06:19:26 +0000 | [diff] [blame] | 1751 |   AssignToArrayRange(Builder, Address, Four8, 64, 76); | 
| John McCall | ec853ba | 2010-03-11 00:10:12 +0000 | [diff] [blame] | 1752 |  | 
 | 1753 |   // 77-108: v0-31, the 16-byte vector registers | 
| John McCall | aeeb701 | 2010-05-27 06:19:26 +0000 | [diff] [blame] | 1754 |   AssignToArrayRange(Builder, Address, Sixteen8, 77, 108); | 
| John McCall | ec853ba | 2010-03-11 00:10:12 +0000 | [diff] [blame] | 1755 |  | 
 | 1756 |   // 109: vrsave | 
 | 1757 |   // 110: vscr | 
 | 1758 |   // 111: spe_acc | 
 | 1759 |   // 112: spefscr | 
 | 1760 |   // 113: sfp | 
| John McCall | aeeb701 | 2010-05-27 06:19:26 +0000 | [diff] [blame] | 1761 |   AssignToArrayRange(Builder, Address, Four8, 109, 113); | 
| John McCall | ec853ba | 2010-03-11 00:10:12 +0000 | [diff] [blame] | 1762 |  | 
 | 1763 |   return false;   | 
 | 1764 | } | 
 | 1765 |  | 
 | 1766 |  | 
| Chris Lattner | dce5ad0 | 2010-06-28 20:05:43 +0000 | [diff] [blame] | 1767 | //===----------------------------------------------------------------------===// | 
| Daniel Dunbar | 34d91fd | 2009-09-12 00:59:49 +0000 | [diff] [blame] | 1768 | // ARM ABI Implementation | 
| Chris Lattner | dce5ad0 | 2010-06-28 20:05:43 +0000 | [diff] [blame] | 1769 | //===----------------------------------------------------------------------===// | 
| Daniel Dunbar | 34d91fd | 2009-09-12 00:59:49 +0000 | [diff] [blame] | 1770 |  | 
 | 1771 | namespace { | 
 | 1772 |  | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1773 | class ARMABIInfo : public ABIInfo { | 
| Daniel Dunbar | 5e7bace | 2009-09-12 01:00:39 +0000 | [diff] [blame] | 1774 | public: | 
 | 1775 |   enum ABIKind { | 
 | 1776 |     APCS = 0, | 
 | 1777 |     AAPCS = 1, | 
 | 1778 |     AAPCS_VFP | 
 | 1779 |   }; | 
 | 1780 |  | 
 | 1781 | private: | 
 | 1782 |   ABIKind Kind; | 
 | 1783 |  | 
 | 1784 | public: | 
 | 1785 |   ARMABIInfo(ABIKind _Kind) : Kind(_Kind) {} | 
 | 1786 |  | 
 | 1787 | private: | 
 | 1788 |   ABIKind getABIKind() const { return Kind; } | 
 | 1789 |  | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1790 |   ABIArgInfo classifyReturnType(QualType RetTy, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1791 |                                 ASTContext &Context, | 
 | 1792 |                                 llvm::LLVMContext &VMCOntext) const; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1793 |  | 
 | 1794 |   ABIArgInfo classifyArgumentType(QualType RetTy, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1795 |                                   ASTContext &Context, | 
 | 1796 |                                   llvm::LLVMContext &VMContext) const; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1797 |  | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1798 |   virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context, | 
| Chris Lattner | 8640cd6 | 2010-06-29 01:08:48 +0000 | [diff] [blame^] | 1799 |                            llvm::LLVMContext &VMContext, | 
 | 1800 |                            const llvm::Type *const *PrefTypes, | 
 | 1801 |                            unsigned NumPrefTypes) const; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1802 |  | 
 | 1803 |   virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, | 
 | 1804 |                                  CodeGenFunction &CGF) const; | 
 | 1805 | }; | 
 | 1806 |  | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 1807 | class ARMTargetCodeGenInfo : public TargetCodeGenInfo { | 
 | 1808 | public: | 
 | 1809 |   ARMTargetCodeGenInfo(ARMABIInfo::ABIKind K) | 
| Douglas Gregor | 568bb2d | 2010-01-22 15:41:14 +0000 | [diff] [blame] | 1810 |     :TargetCodeGenInfo(new ARMABIInfo(K)) {} | 
| John McCall | 6374c33 | 2010-03-06 00:35:14 +0000 | [diff] [blame] | 1811 |  | 
 | 1812 |   int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const { | 
 | 1813 |     return 13; | 
 | 1814 |   } | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 1815 | }; | 
 | 1816 |  | 
| Daniel Dunbar | 34d91fd | 2009-09-12 00:59:49 +0000 | [diff] [blame] | 1817 | } | 
 | 1818 |  | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1819 | void ARMABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context, | 
| Chris Lattner | 8640cd6 | 2010-06-29 01:08:48 +0000 | [diff] [blame^] | 1820 |                              llvm::LLVMContext &VMContext, | 
 | 1821 |                              const llvm::Type *const *PrefTypes, | 
 | 1822 |                              unsigned NumPrefTypes) const { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1823 |   FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), Context, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1824 |                                           VMContext); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1825 |   for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); | 
 | 1826 |        it != ie; ++it) { | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1827 |     it->info = classifyArgumentType(it->type, Context, VMContext); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1828 |   } | 
| Daniel Dunbar | 5e7bace | 2009-09-12 01:00:39 +0000 | [diff] [blame] | 1829 |  | 
| Rafael Espindola | 25117ab | 2010-06-16 16:13:39 +0000 | [diff] [blame] | 1830 |   const llvm::Triple &Triple(Context.Target.getTriple()); | 
 | 1831 |   llvm::CallingConv::ID DefaultCC; | 
| Rafael Espindola | 1ed1a59 | 2010-06-16 19:01:17 +0000 | [diff] [blame] | 1832 |   if (Triple.getEnvironmentName() == "gnueabi" || | 
 | 1833 |       Triple.getEnvironmentName() == "eabi") | 
| Rafael Espindola | 25117ab | 2010-06-16 16:13:39 +0000 | [diff] [blame] | 1834 |     DefaultCC = llvm::CallingConv::ARM_AAPCS; | 
| Rafael Espindola | 1ed1a59 | 2010-06-16 19:01:17 +0000 | [diff] [blame] | 1835 |   else | 
 | 1836 |     DefaultCC = llvm::CallingConv::ARM_APCS; | 
| Rafael Espindola | 25117ab | 2010-06-16 16:13:39 +0000 | [diff] [blame] | 1837 |  | 
| Daniel Dunbar | 5e7bace | 2009-09-12 01:00:39 +0000 | [diff] [blame] | 1838 |   switch (getABIKind()) { | 
 | 1839 |   case APCS: | 
| Rafael Espindola | 25117ab | 2010-06-16 16:13:39 +0000 | [diff] [blame] | 1840 |     if (DefaultCC != llvm::CallingConv::ARM_APCS) | 
 | 1841 |       FI.setEffectiveCallingConvention(llvm::CallingConv::ARM_APCS); | 
| Daniel Dunbar | 5e7bace | 2009-09-12 01:00:39 +0000 | [diff] [blame] | 1842 |     break; | 
 | 1843 |  | 
 | 1844 |   case AAPCS: | 
| Rafael Espindola | 25117ab | 2010-06-16 16:13:39 +0000 | [diff] [blame] | 1845 |     if (DefaultCC != llvm::CallingConv::ARM_AAPCS) | 
 | 1846 |       FI.setEffectiveCallingConvention(llvm::CallingConv::ARM_AAPCS); | 
| Daniel Dunbar | 5e7bace | 2009-09-12 01:00:39 +0000 | [diff] [blame] | 1847 |     break; | 
 | 1848 |  | 
 | 1849 |   case AAPCS_VFP: | 
 | 1850 |     FI.setEffectiveCallingConvention(llvm::CallingConv::ARM_AAPCS_VFP); | 
 | 1851 |     break; | 
 | 1852 |   } | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1853 | } | 
 | 1854 |  | 
 | 1855 | ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1856 |                                             ASTContext &Context, | 
 | 1857 |                                           llvm::LLVMContext &VMContext) const { | 
| Douglas Gregor | aa74a1e | 2010-02-02 20:10:50 +0000 | [diff] [blame] | 1858 |   if (!CodeGenFunction::hasAggregateLLVMType(Ty)) { | 
 | 1859 |     // Treat an enum type as its underlying type. | 
 | 1860 |     if (const EnumType *EnumTy = Ty->getAs<EnumType>()) | 
 | 1861 |       Ty = EnumTy->getDecl()->getIntegerType(); | 
 | 1862 |  | 
| Anton Korobeynikov | cc6fa88 | 2009-06-06 09:36:29 +0000 | [diff] [blame] | 1863 |     return (Ty->isPromotableIntegerType() ? | 
 | 1864 |             ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); | 
| Douglas Gregor | aa74a1e | 2010-02-02 20:10:50 +0000 | [diff] [blame] | 1865 |   } | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 1866 |  | 
| Daniel Dunbar | 4202557 | 2009-09-14 21:54:03 +0000 | [diff] [blame] | 1867 |   // Ignore empty records. | 
 | 1868 |   if (isEmptyRecord(Context, Ty, true)) | 
 | 1869 |     return ABIArgInfo::getIgnore(); | 
 | 1870 |  | 
| Rafael Espindola | 0eb1d97 | 2010-06-08 02:42:08 +0000 | [diff] [blame] | 1871 |   // Structures with either a non-trivial destructor or a non-trivial | 
 | 1872 |   // copy constructor are always indirect. | 
 | 1873 |   if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) | 
 | 1874 |     return ABIArgInfo::getIndirect(0, /*ByVal=*/false); | 
 | 1875 |  | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1876 |   // FIXME: This is kind of nasty... but there isn't much choice because the ARM | 
 | 1877 |   // backend doesn't support byval. | 
 | 1878 |   // FIXME: This doesn't handle alignment > 64 bits. | 
 | 1879 |   const llvm::Type* ElemTy; | 
 | 1880 |   unsigned SizeRegs; | 
 | 1881 |   if (Context.getTypeAlign(Ty) > 32) { | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 1882 |     ElemTy = llvm::Type::getInt64Ty(VMContext); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1883 |     SizeRegs = (Context.getTypeSize(Ty) + 63) / 64; | 
 | 1884 |   } else { | 
| Owen Anderson | 0032b27 | 2009-08-13 21:57:51 +0000 | [diff] [blame] | 1885 |     ElemTy = llvm::Type::getInt32Ty(VMContext); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1886 |     SizeRegs = (Context.getTypeSize(Ty) + 31) / 32; | 
 | 1887 |   } | 
 | 1888 |   std::vector<const llvm::Type*> LLVMFields; | 
| Owen Anderson | 96e0fc7 | 2009-07-29 22:16:19 +0000 | [diff] [blame] | 1889 |   LLVMFields.push_back(llvm::ArrayType::get(ElemTy, SizeRegs)); | 
| Owen Anderson | 47a434f | 2009-08-05 23:18:46 +0000 | [diff] [blame] | 1890 |   const llvm::Type* STy = llvm::StructType::get(VMContext, LLVMFields, true); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1891 |   return ABIArgInfo::getCoerce(STy); | 
 | 1892 | } | 
 | 1893 |  | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 1894 | static bool isIntegerLikeType(QualType Ty, | 
 | 1895 |                               ASTContext &Context, | 
 | 1896 |                               llvm::LLVMContext &VMContext) { | 
 | 1897 |   // APCS, C Language Calling Conventions, Non-Simple Return Values: A structure | 
 | 1898 |   // is called integer-like if its size is less than or equal to one word, and | 
 | 1899 |   // the offset of each of its addressable sub-fields is zero. | 
 | 1900 |  | 
 | 1901 |   uint64_t Size = Context.getTypeSize(Ty); | 
 | 1902 |  | 
 | 1903 |   // Check that the type fits in a word. | 
 | 1904 |   if (Size > 32) | 
 | 1905 |     return false; | 
 | 1906 |  | 
 | 1907 |   // FIXME: Handle vector types! | 
 | 1908 |   if (Ty->isVectorType()) | 
 | 1909 |     return false; | 
 | 1910 |  | 
| Daniel Dunbar | b0d5819 | 2009-09-14 02:20:34 +0000 | [diff] [blame] | 1911 |   // Float types are never treated as "integer like". | 
 | 1912 |   if (Ty->isRealFloatingType()) | 
 | 1913 |     return false; | 
 | 1914 |  | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 1915 |   // If this is a builtin or pointer type then it is ok. | 
| John McCall | 183700f | 2009-09-21 23:43:11 +0000 | [diff] [blame] | 1916 |   if (Ty->getAs<BuiltinType>() || Ty->isPointerType()) | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 1917 |     return true; | 
 | 1918 |  | 
| Daniel Dunbar | 4581581 | 2010-02-01 23:31:26 +0000 | [diff] [blame] | 1919 |   // Small complex integer types are "integer like". | 
 | 1920 |   if (const ComplexType *CT = Ty->getAs<ComplexType>()) | 
 | 1921 |     return isIntegerLikeType(CT->getElementType(), Context, VMContext); | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 1922 |  | 
 | 1923 |   // Single element and zero sized arrays should be allowed, by the definition | 
 | 1924 |   // above, but they are not. | 
 | 1925 |  | 
 | 1926 |   // Otherwise, it must be a record type. | 
 | 1927 |   const RecordType *RT = Ty->getAs<RecordType>(); | 
 | 1928 |   if (!RT) return false; | 
 | 1929 |  | 
 | 1930 |   // Ignore records with flexible arrays. | 
 | 1931 |   const RecordDecl *RD = RT->getDecl(); | 
 | 1932 |   if (RD->hasFlexibleArrayMember()) | 
 | 1933 |     return false; | 
 | 1934 |  | 
 | 1935 |   // Check that all sub-fields are at offset 0, and are themselves "integer | 
 | 1936 |   // like". | 
 | 1937 |   const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); | 
 | 1938 |  | 
 | 1939 |   bool HadField = false; | 
 | 1940 |   unsigned idx = 0; | 
 | 1941 |   for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); | 
 | 1942 |        i != e; ++i, ++idx) { | 
 | 1943 |     const FieldDecl *FD = *i; | 
 | 1944 |  | 
| Daniel Dunbar | 679855a | 2010-01-29 03:22:29 +0000 | [diff] [blame] | 1945 |     // Bit-fields are not addressable, we only need to verify they are "integer | 
 | 1946 |     // like". We still have to disallow a subsequent non-bitfield, for example: | 
 | 1947 |     //   struct { int : 0; int x } | 
 | 1948 |     // is non-integer like according to gcc. | 
 | 1949 |     if (FD->isBitField()) { | 
 | 1950 |       if (!RD->isUnion()) | 
 | 1951 |         HadField = true; | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 1952 |  | 
| Daniel Dunbar | 679855a | 2010-01-29 03:22:29 +0000 | [diff] [blame] | 1953 |       if (!isIntegerLikeType(FD->getType(), Context, VMContext)) | 
 | 1954 |         return false; | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 1955 |  | 
| Daniel Dunbar | 679855a | 2010-01-29 03:22:29 +0000 | [diff] [blame] | 1956 |       continue; | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 1957 |     } | 
 | 1958 |  | 
| Daniel Dunbar | 679855a | 2010-01-29 03:22:29 +0000 | [diff] [blame] | 1959 |     // Check if this field is at offset 0. | 
 | 1960 |     if (Layout.getFieldOffset(idx) != 0) | 
 | 1961 |       return false; | 
 | 1962 |  | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 1963 |     if (!isIntegerLikeType(FD->getType(), Context, VMContext)) | 
 | 1964 |       return false; | 
 | 1965 |      | 
| Daniel Dunbar | 679855a | 2010-01-29 03:22:29 +0000 | [diff] [blame] | 1966 |     // Only allow at most one field in a structure. This doesn't match the | 
 | 1967 |     // wording above, but follows gcc in situations with a field following an | 
 | 1968 |     // empty structure. | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 1969 |     if (!RD->isUnion()) { | 
 | 1970 |       if (HadField) | 
 | 1971 |         return false; | 
 | 1972 |  | 
 | 1973 |       HadField = true; | 
 | 1974 |     } | 
 | 1975 |   } | 
 | 1976 |  | 
 | 1977 |   return true; | 
 | 1978 | } | 
 | 1979 |  | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1980 | ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 1981 |                                           ASTContext &Context, | 
 | 1982 |                                           llvm::LLVMContext &VMContext) const { | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 1983 |   if (RetTy->isVoidType()) | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 1984 |     return ABIArgInfo::getIgnore(); | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 1985 |  | 
| Douglas Gregor | aa74a1e | 2010-02-02 20:10:50 +0000 | [diff] [blame] | 1986 |   if (!CodeGenFunction::hasAggregateLLVMType(RetTy)) { | 
 | 1987 |     // Treat an enum type as its underlying type. | 
 | 1988 |     if (const EnumType *EnumTy = RetTy->getAs<EnumType>()) | 
 | 1989 |       RetTy = EnumTy->getDecl()->getIntegerType(); | 
 | 1990 |  | 
| Anton Korobeynikov | cc6fa88 | 2009-06-06 09:36:29 +0000 | [diff] [blame] | 1991 |     return (RetTy->isPromotableIntegerType() ? | 
 | 1992 |             ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); | 
| Douglas Gregor | aa74a1e | 2010-02-02 20:10:50 +0000 | [diff] [blame] | 1993 |   } | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 1994 |  | 
| Rafael Espindola | 0eb1d97 | 2010-06-08 02:42:08 +0000 | [diff] [blame] | 1995 |   // Structures with either a non-trivial destructor or a non-trivial | 
 | 1996 |   // copy constructor are always indirect. | 
 | 1997 |   if (isRecordWithNonTrivialDestructorOrCopyConstructor(RetTy)) | 
 | 1998 |     return ABIArgInfo::getIndirect(0, /*ByVal=*/false); | 
 | 1999 |  | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 2000 |   // Are we following APCS? | 
 | 2001 |   if (getABIKind() == APCS) { | 
 | 2002 |     if (isEmptyRecord(Context, RetTy, false)) | 
 | 2003 |       return ABIArgInfo::getIgnore(); | 
 | 2004 |  | 
| Daniel Dunbar | 4cc753f | 2010-02-01 23:31:19 +0000 | [diff] [blame] | 2005 |     // Complex types are all returned as packed integers. | 
 | 2006 |     // | 
 | 2007 |     // FIXME: Consider using 2 x vector types if the back end handles them | 
 | 2008 |     // correctly. | 
 | 2009 |     if (RetTy->isAnyComplexType()) | 
 | 2010 |       return ABIArgInfo::getCoerce(llvm::IntegerType::get( | 
 | 2011 |                                      VMContext, Context.getTypeSize(RetTy))); | 
 | 2012 |  | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 2013 |     // Integer like structures are returned in r0. | 
 | 2014 |     if (isIntegerLikeType(RetTy, Context, VMContext)) { | 
 | 2015 |       // Return in the smallest viable integer type. | 
 | 2016 |       uint64_t Size = Context.getTypeSize(RetTy); | 
 | 2017 |       if (Size <= 8) | 
 | 2018 |         return ABIArgInfo::getCoerce(llvm::Type::getInt8Ty(VMContext)); | 
 | 2019 |       if (Size <= 16) | 
 | 2020 |         return ABIArgInfo::getCoerce(llvm::Type::getInt16Ty(VMContext)); | 
 | 2021 |       return ABIArgInfo::getCoerce(llvm::Type::getInt32Ty(VMContext)); | 
 | 2022 |     } | 
 | 2023 |  | 
 | 2024 |     // Otherwise return in memory. | 
 | 2025 |     return ABIArgInfo::getIndirect(0); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 2026 |   } | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 2027 |  | 
 | 2028 |   // Otherwise this is an AAPCS variant. | 
 | 2029 |  | 
| Daniel Dunbar | 16a0808 | 2009-09-14 00:56:55 +0000 | [diff] [blame] | 2030 |   if (isEmptyRecord(Context, RetTy, true)) | 
 | 2031 |     return ABIArgInfo::getIgnore(); | 
 | 2032 |  | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 2033 |   // Aggregates <= 4 bytes are returned in r0; other aggregates | 
 | 2034 |   // are returned indirectly. | 
 | 2035 |   uint64_t Size = Context.getTypeSize(RetTy); | 
| Daniel Dunbar | 16a0808 | 2009-09-14 00:56:55 +0000 | [diff] [blame] | 2036 |   if (Size <= 32) { | 
 | 2037 |     // Return in the smallest viable integer type. | 
 | 2038 |     if (Size <= 8) | 
 | 2039 |       return ABIArgInfo::getCoerce(llvm::Type::getInt8Ty(VMContext)); | 
 | 2040 |     if (Size <= 16) | 
 | 2041 |       return ABIArgInfo::getCoerce(llvm::Type::getInt16Ty(VMContext)); | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 2042 |     return ABIArgInfo::getCoerce(llvm::Type::getInt32Ty(VMContext)); | 
| Daniel Dunbar | 16a0808 | 2009-09-14 00:56:55 +0000 | [diff] [blame] | 2043 |   } | 
 | 2044 |  | 
| Daniel Dunbar | 98303b9 | 2009-09-13 08:03:58 +0000 | [diff] [blame] | 2045 |   return ABIArgInfo::getIndirect(0); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 2046 | } | 
 | 2047 |  | 
 | 2048 | llvm::Value *ARMABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, | 
| Chris Lattner | 77b89b8 | 2010-06-27 07:15:29 +0000 | [diff] [blame] | 2049 |                                    CodeGenFunction &CGF) const { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 2050 |   // FIXME: Need to handle alignment | 
| Benjamin Kramer | 3c0ef8c | 2009-10-13 10:07:13 +0000 | [diff] [blame] | 2051 |   const llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); | 
| Owen Anderson | 96e0fc7 | 2009-07-29 22:16:19 +0000 | [diff] [blame] | 2052 |   const llvm::Type *BPP = llvm::PointerType::getUnqual(BP); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 2053 |  | 
 | 2054 |   CGBuilderTy &Builder = CGF.Builder; | 
 | 2055 |   llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, | 
 | 2056 |                                                        "ap"); | 
 | 2057 |   llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur"); | 
 | 2058 |   llvm::Type *PTy = | 
| Owen Anderson | 96e0fc7 | 2009-07-29 22:16:19 +0000 | [diff] [blame] | 2059 |     llvm::PointerType::getUnqual(CGF.ConvertType(Ty)); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 2060 |   llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy); | 
 | 2061 |  | 
 | 2062 |   uint64_t Offset = | 
 | 2063 |     llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, 4); | 
 | 2064 |   llvm::Value *NextAddr = | 
| Chris Lattner | 77b89b8 | 2010-06-27 07:15:29 +0000 | [diff] [blame] | 2065 |     Builder.CreateGEP(Addr, llvm::ConstantInt::get(CGF.Int32Ty, Offset), | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 2066 |                       "ap.next"); | 
 | 2067 |   Builder.CreateStore(NextAddr, VAListAddrAsBPP); | 
 | 2068 |  | 
 | 2069 |   return AddrTyped; | 
 | 2070 | } | 
 | 2071 |  | 
 | 2072 | ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy, | 
| Owen Anderson | a1cf15f | 2009-07-14 23:10:40 +0000 | [diff] [blame] | 2073 |                                               ASTContext &Context, | 
 | 2074 |                                           llvm::LLVMContext &VMContext) const { | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 2075 |   if (RetTy->isVoidType()) { | 
 | 2076 |     return ABIArgInfo::getIgnore(); | 
 | 2077 |   } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) { | 
 | 2078 |     return ABIArgInfo::getIndirect(0); | 
 | 2079 |   } else { | 
| Douglas Gregor | aa74a1e | 2010-02-02 20:10:50 +0000 | [diff] [blame] | 2080 |     // Treat an enum type as its underlying type. | 
 | 2081 |     if (const EnumType *EnumTy = RetTy->getAs<EnumType>()) | 
 | 2082 |       RetTy = EnumTy->getDecl()->getIntegerType(); | 
 | 2083 |  | 
| Anton Korobeynikov | cc6fa88 | 2009-06-06 09:36:29 +0000 | [diff] [blame] | 2084 |     return (RetTy->isPromotableIntegerType() ? | 
 | 2085 |             ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 2086 |   } | 
 | 2087 | } | 
 | 2088 |  | 
| Chris Lattner | dce5ad0 | 2010-06-28 20:05:43 +0000 | [diff] [blame] | 2089 | //===----------------------------------------------------------------------===// | 
| Daniel Dunbar | 34d91fd | 2009-09-12 00:59:49 +0000 | [diff] [blame] | 2090 | // SystemZ ABI Implementation | 
| Chris Lattner | dce5ad0 | 2010-06-28 20:05:43 +0000 | [diff] [blame] | 2091 | //===----------------------------------------------------------------------===// | 
| Daniel Dunbar | 34d91fd | 2009-09-12 00:59:49 +0000 | [diff] [blame] | 2092 |  | 
| Anton Korobeynikov | 89e887f | 2009-07-16 20:09:57 +0000 | [diff] [blame] | 2093 | namespace { | 
| Daniel Dunbar | 34d91fd | 2009-09-12 00:59:49 +0000 | [diff] [blame] | 2094 |  | 
| Anton Korobeynikov | 89e887f | 2009-07-16 20:09:57 +0000 | [diff] [blame] | 2095 | class SystemZABIInfo : public ABIInfo { | 
 | 2096 |   bool isPromotableIntegerType(QualType Ty) const; | 
 | 2097 |  | 
 | 2098 |   ABIArgInfo classifyReturnType(QualType RetTy, ASTContext &Context, | 
 | 2099 |                                 llvm::LLVMContext &VMContext) const; | 
 | 2100 |  | 
 | 2101 |   ABIArgInfo classifyArgumentType(QualType RetTy, ASTContext &Context, | 
 | 2102 |                                   llvm::LLVMContext &VMContext) const; | 
 | 2103 |  | 
 | 2104 |   virtual void computeInfo(CGFunctionInfo &FI, ASTContext &Context, | 
| Chris Lattner | 8640cd6 | 2010-06-29 01:08:48 +0000 | [diff] [blame^] | 2105 |                           llvm::LLVMContext &VMContext, | 
 | 2106 |                            const llvm::Type *const *PrefTypes, | 
 | 2107 |                            unsigned NumPrefTypes) const { | 
| Anton Korobeynikov | 89e887f | 2009-07-16 20:09:57 +0000 | [diff] [blame] | 2108 |     FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), | 
 | 2109 |                                             Context, VMContext); | 
 | 2110 |     for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); | 
 | 2111 |          it != ie; ++it) | 
 | 2112 |       it->info = classifyArgumentType(it->type, Context, VMContext); | 
 | 2113 |   } | 
 | 2114 |  | 
 | 2115 |   virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, | 
 | 2116 |                                  CodeGenFunction &CGF) const; | 
 | 2117 | }; | 
| Daniel Dunbar | 34d91fd | 2009-09-12 00:59:49 +0000 | [diff] [blame] | 2118 |  | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 2119 | class SystemZTargetCodeGenInfo : public TargetCodeGenInfo { | 
 | 2120 | public: | 
| Douglas Gregor | 568bb2d | 2010-01-22 15:41:14 +0000 | [diff] [blame] | 2121 |   SystemZTargetCodeGenInfo():TargetCodeGenInfo(new SystemZABIInfo()) {} | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 2122 | }; | 
 | 2123 |  | 
| Anton Korobeynikov | 89e887f | 2009-07-16 20:09:57 +0000 | [diff] [blame] | 2124 | } | 
 | 2125 |  | 
 | 2126 | bool SystemZABIInfo::isPromotableIntegerType(QualType Ty) const { | 
 | 2127 |   // SystemZ ABI requires all 8, 16 and 32 bit quantities to be extended. | 
| John McCall | 183700f | 2009-09-21 23:43:11 +0000 | [diff] [blame] | 2128 |   if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) | 
| Anton Korobeynikov | 89e887f | 2009-07-16 20:09:57 +0000 | [diff] [blame] | 2129 |     switch (BT->getKind()) { | 
 | 2130 |     case BuiltinType::Bool: | 
 | 2131 |     case BuiltinType::Char_S: | 
 | 2132 |     case BuiltinType::Char_U: | 
 | 2133 |     case BuiltinType::SChar: | 
 | 2134 |     case BuiltinType::UChar: | 
 | 2135 |     case BuiltinType::Short: | 
 | 2136 |     case BuiltinType::UShort: | 
 | 2137 |     case BuiltinType::Int: | 
 | 2138 |     case BuiltinType::UInt: | 
 | 2139 |       return true; | 
 | 2140 |     default: | 
 | 2141 |       return false; | 
 | 2142 |     } | 
 | 2143 |   return false; | 
 | 2144 | } | 
 | 2145 |  | 
 | 2146 | llvm::Value *SystemZABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, | 
 | 2147 |                                        CodeGenFunction &CGF) const { | 
 | 2148 |   // FIXME: Implement | 
 | 2149 |   return 0; | 
 | 2150 | } | 
 | 2151 |  | 
 | 2152 |  | 
 | 2153 | ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy, | 
 | 2154 |                                               ASTContext &Context, | 
| Daniel Dunbar | 34d91fd | 2009-09-12 00:59:49 +0000 | [diff] [blame] | 2155 |                                            llvm::LLVMContext &VMContext) const { | 
| Anton Korobeynikov | 89e887f | 2009-07-16 20:09:57 +0000 | [diff] [blame] | 2156 |   if (RetTy->isVoidType()) { | 
 | 2157 |     return ABIArgInfo::getIgnore(); | 
 | 2158 |   } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) { | 
 | 2159 |     return ABIArgInfo::getIndirect(0); | 
 | 2160 |   } else { | 
 | 2161 |     return (isPromotableIntegerType(RetTy) ? | 
 | 2162 |             ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); | 
 | 2163 |   } | 
 | 2164 | } | 
 | 2165 |  | 
 | 2166 | ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty, | 
 | 2167 |                                                 ASTContext &Context, | 
| Daniel Dunbar | 34d91fd | 2009-09-12 00:59:49 +0000 | [diff] [blame] | 2168 |                                            llvm::LLVMContext &VMContext) const { | 
| Anton Korobeynikov | 89e887f | 2009-07-16 20:09:57 +0000 | [diff] [blame] | 2169 |   if (CodeGenFunction::hasAggregateLLVMType(Ty)) { | 
 | 2170 |     return ABIArgInfo::getIndirect(0); | 
 | 2171 |   } else { | 
 | 2172 |     return (isPromotableIntegerType(Ty) ? | 
 | 2173 |             ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); | 
 | 2174 |   } | 
 | 2175 | } | 
 | 2176 |  | 
| Chris Lattner | dce5ad0 | 2010-06-28 20:05:43 +0000 | [diff] [blame] | 2177 | //===----------------------------------------------------------------------===// | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 2178 | // MSP430 ABI Implementation | 
| Chris Lattner | dce5ad0 | 2010-06-28 20:05:43 +0000 | [diff] [blame] | 2179 | //===----------------------------------------------------------------------===// | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 2180 |  | 
 | 2181 | namespace { | 
 | 2182 |  | 
 | 2183 | class MSP430TargetCodeGenInfo : public TargetCodeGenInfo { | 
 | 2184 | public: | 
| Douglas Gregor | 568bb2d | 2010-01-22 15:41:14 +0000 | [diff] [blame] | 2185 |   MSP430TargetCodeGenInfo():TargetCodeGenInfo(new DefaultABIInfo()) {} | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 2186 |   void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, | 
 | 2187 |                            CodeGen::CodeGenModule &M) const; | 
 | 2188 | }; | 
 | 2189 |  | 
 | 2190 | } | 
 | 2191 |  | 
 | 2192 | void MSP430TargetCodeGenInfo::SetTargetAttributes(const Decl *D, | 
 | 2193 |                                                   llvm::GlobalValue *GV, | 
 | 2194 |                                              CodeGen::CodeGenModule &M) const { | 
 | 2195 |   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { | 
 | 2196 |     if (const MSP430InterruptAttr *attr = FD->getAttr<MSP430InterruptAttr>()) { | 
 | 2197 |       // Handle 'interrupt' attribute: | 
 | 2198 |       llvm::Function *F = cast<llvm::Function>(GV); | 
 | 2199 |  | 
 | 2200 |       // Step 1: Set ISR calling convention. | 
 | 2201 |       F->setCallingConv(llvm::CallingConv::MSP430_INTR); | 
 | 2202 |  | 
 | 2203 |       // Step 2: Add attributes goodness. | 
 | 2204 |       F->addFnAttr(llvm::Attribute::NoInline); | 
 | 2205 |  | 
 | 2206 |       // Step 3: Emit ISR vector alias. | 
 | 2207 |       unsigned Num = attr->getNumber() + 0xffe0; | 
 | 2208 |       new llvm::GlobalAlias(GV->getType(), llvm::Function::ExternalLinkage, | 
 | 2209 |                             "vector_" + | 
 | 2210 |                             llvm::LowercaseString(llvm::utohexstr(Num)), | 
 | 2211 |                             GV, &M.getModule()); | 
 | 2212 |     } | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 2213 |   } | 
 | 2214 | } | 
 | 2215 |  | 
| Chris Lattner | dce5ad0 | 2010-06-28 20:05:43 +0000 | [diff] [blame] | 2216 | //===----------------------------------------------------------------------===// | 
| John McCall | aeeb701 | 2010-05-27 06:19:26 +0000 | [diff] [blame] | 2217 | // MIPS ABI Implementation.  This works for both little-endian and | 
 | 2218 | // big-endian variants. | 
| Chris Lattner | dce5ad0 | 2010-06-28 20:05:43 +0000 | [diff] [blame] | 2219 | //===----------------------------------------------------------------------===// | 
 | 2220 |  | 
| John McCall | aeeb701 | 2010-05-27 06:19:26 +0000 | [diff] [blame] | 2221 | namespace { | 
 | 2222 | class MIPSTargetCodeGenInfo : public TargetCodeGenInfo { | 
 | 2223 | public: | 
 | 2224 |   MIPSTargetCodeGenInfo(): TargetCodeGenInfo(new DefaultABIInfo()) {} | 
 | 2225 |  | 
 | 2226 |   int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const { | 
 | 2227 |     return 29; | 
 | 2228 |   } | 
 | 2229 |  | 
 | 2230 |   bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, | 
 | 2231 |                                llvm::Value *Address) const;   | 
 | 2232 | }; | 
 | 2233 | } | 
 | 2234 |  | 
 | 2235 | bool | 
 | 2236 | MIPSTargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, | 
 | 2237 |                                                llvm::Value *Address) const { | 
 | 2238 |   // This information comes from gcc's implementation, which seems to | 
 | 2239 |   // as canonical as it gets. | 
 | 2240 |  | 
 | 2241 |   CodeGen::CGBuilderTy &Builder = CGF.Builder; | 
 | 2242 |   llvm::LLVMContext &Context = CGF.getLLVMContext(); | 
 | 2243 |  | 
 | 2244 |   // Everything on MIPS is 4 bytes.  Double-precision FP registers | 
 | 2245 |   // are aliased to pairs of single-precision FP registers. | 
 | 2246 |   const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context); | 
 | 2247 |   llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4); | 
 | 2248 |  | 
 | 2249 |   // 0-31 are the general purpose registers, $0 - $31. | 
 | 2250 |   // 32-63 are the floating-point registers, $f0 - $f31. | 
 | 2251 |   // 64 and 65 are the multiply/divide registers, $hi and $lo. | 
 | 2252 |   // 66 is the (notional, I think) register for signal-handler return. | 
 | 2253 |   AssignToArrayRange(Builder, Address, Four8, 0, 65); | 
 | 2254 |  | 
 | 2255 |   // 67-74 are the floating-point status registers, $fcc0 - $fcc7. | 
 | 2256 |   // They are one bit wide and ignored here. | 
 | 2257 |  | 
 | 2258 |   // 80-111 are the coprocessor 0 registers, $c0r0 - $c0r31. | 
 | 2259 |   // (coprocessor 1 is the FP unit) | 
 | 2260 |   // 112-143 are the coprocessor 2 registers, $c2r0 - $c2r31. | 
 | 2261 |   // 144-175 are the coprocessor 3 registers, $c3r0 - $c3r31. | 
 | 2262 |   // 176-181 are the DSP accumulator registers. | 
 | 2263 |   AssignToArrayRange(Builder, Address, Four8, 80, 181); | 
 | 2264 |  | 
 | 2265 |   return false; | 
 | 2266 | } | 
 | 2267 |  | 
 | 2268 |  | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 2269 | const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() const { | 
 | 2270 |   if (TheTargetCodeGenInfo) | 
 | 2271 |     return *TheTargetCodeGenInfo; | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 2272 |  | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 2273 |   // For now we just cache the TargetCodeGenInfo in CodeGenModule and don't | 
 | 2274 |   // free it. | 
| Daniel Dunbar | 2c0843f | 2009-08-24 08:52:16 +0000 | [diff] [blame] | 2275 |  | 
| Daniel Dunbar | 1752ee4 | 2009-08-24 09:10:05 +0000 | [diff] [blame] | 2276 |   const llvm::Triple &Triple(getContext().Target.getTriple()); | 
 | 2277 |   switch (Triple.getArch()) { | 
| Daniel Dunbar | 2c0843f | 2009-08-24 08:52:16 +0000 | [diff] [blame] | 2278 |   default: | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 2279 |     return *(TheTargetCodeGenInfo = new DefaultTargetCodeGenInfo); | 
| Daniel Dunbar | 2c0843f | 2009-08-24 08:52:16 +0000 | [diff] [blame] | 2280 |  | 
| John McCall | aeeb701 | 2010-05-27 06:19:26 +0000 | [diff] [blame] | 2281 |   case llvm::Triple::mips: | 
 | 2282 |   case llvm::Triple::mipsel: | 
 | 2283 |     return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo()); | 
 | 2284 |  | 
| Daniel Dunbar | 34d91fd | 2009-09-12 00:59:49 +0000 | [diff] [blame] | 2285 |   case llvm::Triple::arm: | 
 | 2286 |   case llvm::Triple::thumb: | 
| Daniel Dunbar | 5e7bace | 2009-09-12 01:00:39 +0000 | [diff] [blame] | 2287 |     // FIXME: We want to know the float calling convention as well. | 
| Daniel Dunbar | 018ba5a | 2009-09-14 00:35:03 +0000 | [diff] [blame] | 2288 |     if (strcmp(getContext().Target.getABI(), "apcs-gnu") == 0) | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 2289 |       return *(TheTargetCodeGenInfo = | 
 | 2290 |                new ARMTargetCodeGenInfo(ARMABIInfo::APCS)); | 
| Daniel Dunbar | 5e7bace | 2009-09-12 01:00:39 +0000 | [diff] [blame] | 2291 |  | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 2292 |     return *(TheTargetCodeGenInfo = | 
 | 2293 |              new ARMTargetCodeGenInfo(ARMABIInfo::AAPCS)); | 
| Daniel Dunbar | 34d91fd | 2009-09-12 00:59:49 +0000 | [diff] [blame] | 2294 |  | 
 | 2295 |   case llvm::Triple::pic16: | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 2296 |     return *(TheTargetCodeGenInfo = new PIC16TargetCodeGenInfo()); | 
| Daniel Dunbar | 34d91fd | 2009-09-12 00:59:49 +0000 | [diff] [blame] | 2297 |  | 
| John McCall | ec853ba | 2010-03-11 00:10:12 +0000 | [diff] [blame] | 2298 |   case llvm::Triple::ppc: | 
 | 2299 |     return *(TheTargetCodeGenInfo = new PPC32TargetCodeGenInfo()); | 
 | 2300 |  | 
| Daniel Dunbar | 34d91fd | 2009-09-12 00:59:49 +0000 | [diff] [blame] | 2301 |   case llvm::Triple::systemz: | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 2302 |     return *(TheTargetCodeGenInfo = new SystemZTargetCodeGenInfo()); | 
 | 2303 |  | 
 | 2304 |   case llvm::Triple::msp430: | 
 | 2305 |     return *(TheTargetCodeGenInfo = new MSP430TargetCodeGenInfo()); | 
| Daniel Dunbar | 34d91fd | 2009-09-12 00:59:49 +0000 | [diff] [blame] | 2306 |  | 
| Daniel Dunbar | 1752ee4 | 2009-08-24 09:10:05 +0000 | [diff] [blame] | 2307 |   case llvm::Triple::x86: | 
| Daniel Dunbar | 1752ee4 | 2009-08-24 09:10:05 +0000 | [diff] [blame] | 2308 |     switch (Triple.getOS()) { | 
| Edward O'Callaghan | 7ee68bd | 2009-10-20 17:22:50 +0000 | [diff] [blame] | 2309 |     case llvm::Triple::Darwin: | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 2310 |       return *(TheTargetCodeGenInfo = | 
 | 2311 |                new X86_32TargetCodeGenInfo(Context, true, true)); | 
| Daniel Dunbar | 2c0843f | 2009-08-24 08:52:16 +0000 | [diff] [blame] | 2312 |     case llvm::Triple::Cygwin: | 
| Daniel Dunbar | 2c0843f | 2009-08-24 08:52:16 +0000 | [diff] [blame] | 2313 |     case llvm::Triple::MinGW32: | 
 | 2314 |     case llvm::Triple::MinGW64: | 
| Edward O'Callaghan | 727e268 | 2009-10-21 11:58:24 +0000 | [diff] [blame] | 2315 |     case llvm::Triple::AuroraUX: | 
 | 2316 |     case llvm::Triple::DragonFly: | 
| David Chisnall | 75c135a | 2009-09-03 01:48:05 +0000 | [diff] [blame] | 2317 |     case llvm::Triple::FreeBSD: | 
| Daniel Dunbar | 2c0843f | 2009-08-24 08:52:16 +0000 | [diff] [blame] | 2318 |     case llvm::Triple::OpenBSD: | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 2319 |       return *(TheTargetCodeGenInfo = | 
 | 2320 |                new X86_32TargetCodeGenInfo(Context, false, true)); | 
| Daniel Dunbar | 2c0843f | 2009-08-24 08:52:16 +0000 | [diff] [blame] | 2321 |  | 
 | 2322 |     default: | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 2323 |       return *(TheTargetCodeGenInfo = | 
 | 2324 |                new X86_32TargetCodeGenInfo(Context, false, false)); | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 2325 |     } | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 2326 |  | 
| Daniel Dunbar | 2c0843f | 2009-08-24 08:52:16 +0000 | [diff] [blame] | 2327 |   case llvm::Triple::x86_64: | 
| Anton Korobeynikov | 82d0a41 | 2010-01-10 12:58:08 +0000 | [diff] [blame] | 2328 |     return *(TheTargetCodeGenInfo = new X86_64TargetCodeGenInfo()); | 
| Daniel Dunbar | 2c0843f | 2009-08-24 08:52:16 +0000 | [diff] [blame] | 2329 |   } | 
| Anton Korobeynikov | c4a59eb | 2009-06-05 22:08:42 +0000 | [diff] [blame] | 2330 | } |