| 1 |
/* TargetABI implementation for x86-64. |
|---|
| 2 |
* Written for LDC by Frits van Bommel in 2009. |
|---|
| 3 |
* |
|---|
| 4 |
* extern(D) follows no particular external ABI, but tries to be smart about |
|---|
| 5 |
* passing structs and returning them. It should probably be reviewed if the |
|---|
| 6 |
* way LLVM implements fastcc on this platform ever changes. |
|---|
| 7 |
* (Specifically, the number of return registers of various types is hardcoded) |
|---|
| 8 |
* |
|---|
| 9 |
* |
|---|
| 10 |
* extern(C) implements the C calling convention for x86-64, as found in |
|---|
| 11 |
* http://www.x86-64.org/documentation/abi-0.99.pdf |
|---|
| 12 |
* |
|---|
| 13 |
* Note: |
|---|
| 14 |
* Where a discrepancy was found between llvm-gcc and the ABI documentation, |
|---|
| 15 |
* llvm-gcc behavior was used for compatibility (after it was verified that |
|---|
| 16 |
* regular gcc has the same behavior). |
|---|
| 17 |
* |
|---|
| 18 |
* LLVM gets it right for most types, but complex numbers and structs need some |
|---|
| 19 |
* help. To make sure it gets those right we essentially bitcast small structs |
|---|
| 20 |
* to a type to which LLVM assigns the appropriate registers, and pass that |
|---|
| 21 |
* instead. Structs that are required to be passed in memory are explicitly |
|---|
| 22 |
* marked with the ByVal attribute to ensure no part of them ends up in |
|---|
| 23 |
* registers when only a subset of the desired registers are available. |
|---|
| 24 |
* |
|---|
| 25 |
* We don't perform the same transformation for D-specific types that contain |
|---|
| 26 |
* multiple parts, such as dynamic arrays and delegates. They're passed as if |
|---|
| 27 |
* the parts were passed as separate parameters. This helps make things like |
|---|
| 28 |
* printf("%.*s", o.toString()) work as expected; if we didn't do this that |
|---|
| 29 |
* wouldn't work if there were 4 other integer/pointer arguments before the |
|---|
| 30 |
* toString() call because the string got bumped to memory with one integer |
|---|
| 31 |
* register still free. Keeping it untransformed puts the length in a register |
|---|
| 32 |
* and the pointer in memory, as printf expects it. |
|---|
| 33 |
*/ |
|---|
| 34 |
|
|---|
| 35 |
#include "mtype.h" |
|---|
| 36 |
#include "declaration.h" |
|---|
| 37 |
#include "aggregate.h" |
|---|
| 38 |
|
|---|
| 39 |
#include "gen/irstate.h" |
|---|
| 40 |
#include "gen/llvm.h" |
|---|
| 41 |
#include "gen/tollvm.h" |
|---|
| 42 |
#include "gen/logger.h" |
|---|
| 43 |
#include "gen/dvalue.h" |
|---|
| 44 |
#include "gen/llvmhelpers.h" |
|---|
| 45 |
#include "gen/abi.h" |
|---|
| 46 |
#include "gen/abi-x86-64.h" |
|---|
| 47 |
#include "gen/abi-generic.h" |
|---|
| 48 |
#include "ir/irfunction.h" |
|---|
| 49 |
|
|---|
| 50 |
#include <cassert> |
|---|
| 51 |
#include <map> |
|---|
| 52 |
#include <string> |
|---|
| 53 |
#include <utility> |
|---|
| 54 |
|
|---|
| 55 |
// Implementation details for extern(C) |
|---|
| 56 |
namespace { |
|---|
| 57 |
/** |
|---|
| 58 |
* This function helps filter out things that look like structs to C, |
|---|
| 59 |
* but should be passed to C in separate arguments anyway. |
|---|
| 60 |
* |
|---|
| 61 |
* (e.g. dynamic arrays are passed as separate length and ptr. This |
|---|
| 62 |
* is both less work and makes printf("%.*s", o.toString()) work) |
|---|
| 63 |
*/ |
|---|
| 64 |
inline bool keepUnchanged(Type* t) { |
|---|
| 65 |
switch (t->ty) { |
|---|
| 66 |
case Tarray: // dynamic array |
|---|
| 67 |
case Taarray: // assoc array |
|---|
| 68 |
case Tdelegate: |
|---|
| 69 |
return true; |
|---|
| 70 |
|
|---|
| 71 |
default: |
|---|
| 72 |
return false; |
|---|
| 73 |
} |
|---|
| 74 |
} |
|---|
| 75 |
|
|---|
| 76 |
enum ArgClass { |
|---|
| 77 |
Integer, Sse, SseUp, X87, X87Up, ComplexX87, NoClass, Memory |
|---|
| 78 |
}; |
|---|
| 79 |
|
|---|
| 80 |
struct Classification { |
|---|
| 81 |
bool isMemory; |
|---|
| 82 |
ArgClass classes[2]; |
|---|
| 83 |
|
|---|
| 84 |
Classification() : isMemory(false) { |
|---|
| 85 |
classes[0] = NoClass; |
|---|
| 86 |
classes[1] = NoClass; |
|---|
| 87 |
} |
|---|
| 88 |
|
|---|
| 89 |
void addField(unsigned offset, ArgClass cl) { |
|---|
| 90 |
if (isMemory) |
|---|
| 91 |
return; |
|---|
| 92 |
|
|---|
| 93 |
// Note that we don't need to bother checking if it crosses 8 bytes. |
|---|
| 94 |
// We don't get here with unaligned fields, and anything that can be |
|---|
| 95 |
// big enough to cross 8 bytes (cdoubles, reals, structs and arrays) |
|---|
| 96 |
// is special-cased in classifyType() |
|---|
| 97 |
int idx = (offset < 8 ? 0 : 1); |
|---|
| 98 |
|
|---|
| 99 |
ArgClass nw = merge(classes[idx], cl); |
|---|
| 100 |
if (nw != classes[idx]) { |
|---|
| 101 |
classes[idx] = nw; |
|---|
| 102 |
|
|---|
| 103 |
if (nw == Memory) { |
|---|
| 104 |
classes[1-idx] = Memory; |
|---|
| 105 |
isMemory = true; |
|---|
| 106 |
} |
|---|
| 107 |
} |
|---|
| 108 |
} |
|---|
| 109 |
|
|---|
| 110 |
private: |
|---|
| 111 |
ArgClass merge(ArgClass accum, ArgClass cl) { |
|---|
| 112 |
if (accum == cl) |
|---|
| 113 |
return accum; |
|---|
| 114 |
if (accum == NoClass) |
|---|
| 115 |
return cl; |
|---|
| 116 |
if (cl == NoClass) |
|---|
| 117 |
return accum; |
|---|
| 118 |
if (accum == Memory || cl == Memory) |
|---|
| 119 |
return Memory; |
|---|
| 120 |
if (accum == Integer || cl == Integer) |
|---|
| 121 |
return Integer; |
|---|
| 122 |
if (accum == X87 || accum == X87Up || accum == ComplexX87 || |
|---|
| 123 |
cl == X87 || cl == X87Up || cl == ComplexX87) |
|---|
| 124 |
return Memory; |
|---|
| 125 |
return Sse; |
|---|
| 126 |
} |
|---|
| 127 |
}; |
|---|
| 128 |
|
|---|
| 129 |
void classifyType(Classification& accum, Type* ty, d_uns64 offset) { |
|---|
| 130 |
if (Logger::enabled()) |
|---|
| 131 |
Logger::cout() << "Classifying " << ty->toChars() << " @ " << offset << '\n'; |
|---|
| 132 |
|
|---|
| 133 |
ty = ty->toBasetype(); |
|---|
| 134 |
|
|---|
| 135 |
if (ty->isintegral() || ty->ty == Tpointer) { |
|---|
| 136 |
accum.addField(offset, Integer); |
|---|
| 137 |
} else if (ty->ty == Tfloat80 || ty->ty == Timaginary80) { |
|---|
| 138 |
accum.addField(offset, X87); |
|---|
| 139 |
accum.addField(offset+8, X87Up); |
|---|
| 140 |
} else if (ty->ty == Tcomplex80) { |
|---|
| 141 |
accum.addField(offset, ComplexX87); |
|---|
| 142 |
// make sure other half knows about it too: |
|---|
| 143 |
accum.addField(offset+16, ComplexX87); |
|---|
| 144 |
} else if (ty->ty == Tcomplex64) { |
|---|
| 145 |
accum.addField(offset, Sse); |
|---|
| 146 |
accum.addField(offset+8, Sse); |
|---|
| 147 |
} else if (ty->ty == Tcomplex32) { |
|---|
| 148 |
accum.addField(offset, Sse); |
|---|
| 149 |
accum.addField(offset+4, Sse); |
|---|
| 150 |
} else if (ty->isfloating()) { |
|---|
| 151 |
accum.addField(offset, Sse); |
|---|
| 152 |
} else if (ty->size() > 16 || hasUnalignedFields(ty)) { |
|---|
| 153 |
// This isn't creal, yet is > 16 bytes, so pass in memory. |
|---|
| 154 |
// Must be after creal case but before arrays and structs, |
|---|
| 155 |
// the other types that can get bigger than 16 bytes |
|---|
| 156 |
accum.addField(offset, Memory); |
|---|
| 157 |
} else if (ty->ty == Tsarray) { |
|---|
| 158 |
Type* eltType = ty->nextOf(); |
|---|
| 159 |
d_uns64 eltsize = eltType->size(); |
|---|
| 160 |
if (eltsize > 0) { |
|---|
| 161 |
d_uns64 dim = ty->size() / eltsize; |
|---|
| 162 |
assert(dim <= 16 |
|---|
| 163 |
&& "Array of non-empty type <= 16 bytes but > 16 elements?"); |
|---|
| 164 |
for (d_uns64 i = 0; i < dim; i++) { |
|---|
| 165 |
classifyType(accum, eltType, offset); |
|---|
| 166 |
offset += eltsize; |
|---|
| 167 |
} |
|---|
| 168 |
} |
|---|
| 169 |
} else if (ty->ty == Tstruct) { |
|---|
| 170 |
Array* fields = &((TypeStruct*) ty)->sym->fields; |
|---|
| 171 |
for (size_t i = 0; i < fields->dim; i++) { |
|---|
| 172 |
VarDeclaration* field = (VarDeclaration*) fields->data[i]; |
|---|
| 173 |
classifyType(accum, field->type, offset + field->offset); |
|---|
| 174 |
} |
|---|
| 175 |
} else { |
|---|
| 176 |
if (Logger::enabled()) |
|---|
| 177 |
Logger::cout() << "x86-64 ABI: Implicitly handled type: " |
|---|
| 178 |
<< ty->toChars() << '\n'; |
|---|
| 179 |
// arrays, delegates, etc. (pointer-sized fields, <= 16 bytes) |
|---|
| 180 |
assert(offset == 0 || offset == 8 |
|---|
| 181 |
&& "must be aligned and doesn't fit otherwise"); |
|---|
| 182 |
assert(ty->size() % 8 == 0 && "Not a multiple of pointer size?"); |
|---|
| 183 |
|
|---|
| 184 |
accum.addField(offset, Integer); |
|---|
| 185 |
if (ty->size() > 8) |
|---|
| 186 |
accum.addField(offset+8, Integer); |
|---|
| 187 |
} |
|---|
| 188 |
} |
|---|
| 189 |
|
|---|
| 190 |
Classification classify(Type* ty) { |
|---|
| 191 |
typedef std::map<Type*, Classification> ClassMap; |
|---|
| 192 |
static ClassMap cache; |
|---|
| 193 |
|
|---|
| 194 |
ClassMap::iterator it = cache.find(ty); |
|---|
| 195 |
if (it != cache.end()) { |
|---|
| 196 |
return it->second; |
|---|
| 197 |
} else { |
|---|
| 198 |
Classification cl; |
|---|
| 199 |
classifyType(cl, ty, 0); |
|---|
| 200 |
cache[ty] = cl; |
|---|
| 201 |
return cl; |
|---|
| 202 |
} |
|---|
| 203 |
} |
|---|
| 204 |
|
|---|
| 205 |
/// Returns the type to pass as, or null if no transformation is needed. |
|---|
| 206 |
LLType* getAbiType(Type* ty) { |
|---|
| 207 |
ty = ty->toBasetype(); |
|---|
| 208 |
|
|---|
| 209 |
// First, check if there's any need of a transformation: |
|---|
| 210 |
|
|---|
| 211 |
if (keepUnchanged(ty)) |
|---|
| 212 |
return 0; |
|---|
| 213 |
|
|---|
| 214 |
if (ty->ty != Tcomplex32 && ty->ty != Tstruct) |
|---|
| 215 |
return 0; // Nothing to do, |
|---|
| 216 |
|
|---|
| 217 |
Classification cl = classify(ty); |
|---|
| 218 |
assert(!cl.isMemory); |
|---|
| 219 |
|
|---|
| 220 |
if (cl.classes[0] == NoClass) { |
|---|
| 221 |
assert(cl.classes[1] == NoClass && "Non-empty struct with empty first half?"); |
|---|
| 222 |
return 0; // Empty structs should also be handled correctly by LLVM |
|---|
| 223 |
} |
|---|
| 224 |
|
|---|
| 225 |
// Okay, we may need to transform. Figure out a canonical type: |
|---|
| 226 |
|
|---|
| 227 |
std::vector<const LLType*> parts; |
|---|
| 228 |
|
|---|
| 229 |
unsigned size = ty->size(); |
|---|
| 230 |
|
|---|
| 231 |
switch (cl.classes[0]) { |
|---|
| 232 |
case Integer: { |
|---|
| 233 |
unsigned bits = (size >= 8 ? 64 : (size * 8)); |
|---|
| 234 |
parts.push_back(LLIntegerType::get(gIR->context(), bits)); |
|---|
| 235 |
break; |
|---|
| 236 |
} |
|---|
| 237 |
|
|---|
| 238 |
case Sse: |
|---|
| 239 |
parts.push_back(size <= 4 ? LLType::getFloatTy(gIR->context()) : LLType::getDoubleTy(gIR->context())); |
|---|
| 240 |
break; |
|---|
| 241 |
|
|---|
| 242 |
case X87: |
|---|
| 243 |
assert(cl.classes[1] == X87Up && "Upper half of real not X87Up?"); |
|---|
| 244 |
/// The type only contains a single real/ireal field, |
|---|
| 245 |
/// so just use that type. |
|---|
| 246 |
return const_cast<LLType*>(LLType::getX86_FP80Ty(gIR->context())); |
|---|
| 247 |
|
|---|
| 248 |
default: |
|---|
| 249 |
assert(0 && "Unanticipated argument class"); |
|---|
| 250 |
} |
|---|
| 251 |
|
|---|
| 252 |
switch(cl.classes[1]) { |
|---|
| 253 |
case NoClass: |
|---|
| 254 |
assert(parts.size() == 1); |
|---|
| 255 |
// No need to use a single-element struct type. |
|---|
| 256 |
// Just use the element type instead. |
|---|
| 257 |
return const_cast<LLType*>(parts[0]); |
|---|
| 258 |
break; |
|---|
| 259 |
|
|---|
| 260 |
case Integer: { |
|---|
| 261 |
assert(size > 8); |
|---|
| 262 |
unsigned bits = (size - 8) * 8; |
|---|
| 263 |
parts.push_back(LLIntegerType::get(gIR->context(), bits)); |
|---|
| 264 |
break; |
|---|
| 265 |
} |
|---|
| 266 |
case Sse: |
|---|
| 267 |
parts.push_back(size <= 12 ? LLType::getFloatTy(gIR->context()) : LLType::getDoubleTy(gIR->context())); |
|---|
| 268 |
break; |
|---|
| 269 |
|
|---|
| 270 |
case X87Up: |
|---|
| 271 |
if(cl.classes[0] == X87) { |
|---|
| 272 |
// This won't happen: it was short-circuited while |
|---|
| 273 |
// processing the first half. |
|---|
| 274 |
} else { |
|---|
| 275 |
// I can't find this anywhere in the ABI documentation, |
|---|
| 276 |
// but this is what gcc does (both regular and llvm-gcc). |
|---|
| 277 |
// (This triggers for types like union { real r; byte b; }) |
|---|
| 278 |
parts.push_back(LLType::getDoubleTy(gIR->context())); |
|---|
| 279 |
} |
|---|
| 280 |
break; |
|---|
| 281 |
|
|---|
| 282 |
default: |
|---|
| 283 |
assert(0 && "Unanticipated argument class for second half"); |
|---|
| 284 |
} |
|---|
| 285 |
return LLStructType::get(gIR->context(), parts); |
|---|
| 286 |
} |
|---|
| 287 |
} |
|---|
| 288 |
|
|---|
| 289 |
|
|---|
| 290 |
// Implementation details for extern(D) |
|---|
| 291 |
namespace x86_64_D_cc { |
|---|
| 292 |
struct DRegCount { |
|---|
| 293 |
unsigned ints; |
|---|
| 294 |
unsigned sse; |
|---|
| 295 |
unsigned x87; |
|---|
| 296 |
|
|---|
| 297 |
DRegCount(unsigned ints_, unsigned sse_, unsigned x87_) |
|---|
| 298 |
: ints(ints_), sse(sse_), x87(x87_) {} |
|---|
| 299 |
}; |
|---|
| 300 |
|
|---|
| 301 |
// Count the number of registers needed for a simple type. |
|---|
| 302 |
// (Not a struct or static array) |
|---|
| 303 |
DRegCount regsNeededForSimpleType(Type* t) { |
|---|
| 304 |
DRegCount r(0, 0, 0); |
|---|
| 305 |
switch(t->ty) { |
|---|
| 306 |
case Tstruct: |
|---|
| 307 |
case Tsarray: |
|---|
| 308 |
assert(0 && "Not a simple type!"); |
|---|
| 309 |
// Return huge numbers if assertions are disabled, so it'll always get |
|---|
| 310 |
// bumped to memory. |
|---|
| 311 |
r.ints = r.sse = r.x87 = (unsigned)-1; |
|---|
| 312 |
break; |
|---|
| 313 |
|
|---|
| 314 |
// Floats, doubles and such are passed in SSE registers |
|---|
| 315 |
case Tfloat32: |
|---|
| 316 |
case Tfloat64: |
|---|
| 317 |
case Timaginary32: |
|---|
| 318 |
case Timaginary64: |
|---|
| 319 |
r.sse = 1; |
|---|
| 320 |
break; |
|---|
| 321 |
|
|---|
| 322 |
case Tcomplex32: |
|---|
| 323 |
case Tcomplex64: |
|---|
| 324 |
r.sse = 2; |
|---|
| 325 |
break; |
|---|
| 326 |
|
|---|
| 327 |
// Reals, ireals and creals are passed in x87 registers |
|---|
| 328 |
case Tfloat80: |
|---|
| 329 |
case Timaginary80: |
|---|
| 330 |
r.x87 = 1; |
|---|
| 331 |
break; |
|---|
| 332 |
|
|---|
| 333 |
case Tcomplex80: |
|---|
| 334 |
r.x87 = 2; |
|---|
| 335 |
break; |
|---|
| 336 |
|
|---|
| 337 |
// Anything else is passed in one or two integer registers, |
|---|
| 338 |
// depending on its size. |
|---|
| 339 |
default: { |
|---|
| 340 |
int needed = (t->size() + 7) / 8; |
|---|
| 341 |
assert(needed <= 2); |
|---|
| 342 |
r.ints = needed; |
|---|
| 343 |
break; |
|---|
| 344 |
} |
|---|
| 345 |
} |
|---|
| 346 |
return r; |
|---|
| 347 |
} |
|---|
| 348 |
|
|---|
| 349 |
// Returns true if it's possible (and a good idea) to pass the struct in the |
|---|
| 350 |
// specified number of registers. |
|---|
| 351 |
// (May return false if it's a bad idea to pass the type in registers for |
|---|
| 352 |
// reasons other than it not fitting) |
|---|
| 353 |
// Note that if true is returned, 'left' is also modified to contain the |
|---|
| 354 |
// number of registers left. This property is used in the recursive case. |
|---|
| 355 |
// If false is returned, 'left' is garbage. |
|---|
| 356 |
bool shouldPassStructInRegs(TypeStruct* t, DRegCount& left) { |
|---|
| 357 |
// If it has unaligned fields, there's probably a reason for it, |
|---|
| 358 |
// so keep it in memory. |
|---|
| 359 |
if (hasUnalignedFields(t)) |
|---|
| 360 |
return false; |
|---|
| 361 |
|
|---|
| 362 |
Array* fields = &t->sym->fields; |
|---|
| 363 |
d_uns64 nextbyte = 0; |
|---|
| 364 |
for (d_uns64 i = 0; i < fields->dim; i++) { |
|---|
| 365 |
VarDeclaration* field = (VarDeclaration*) fields->data[i]; |
|---|
| 366 |
|
|---|
| 367 |
// This depends on ascending order of field offsets in structs |
|---|
| 368 |
// without overlapping fields. |
|---|
| 369 |
if (field->offset < nextbyte) { |
|---|
| 370 |
// Don't return unions (or structs containing them) in registers. |
|---|
| 371 |
return false; |
|---|
| 372 |
} |
|---|
| 373 |
nextbyte = field->offset + field->type->size(); |
|---|
| 374 |
|
|---|
| 375 |
switch (field->type->ty) { |
|---|
| 376 |
case Tstruct: |
|---|
| 377 |
if (!shouldPassStructInRegs((TypeStruct*) field->type, left)) |
|---|
| 378 |
return false; |
|---|
| 379 |
break; |
|---|
| 380 |
|
|---|
| 381 |
case Tsarray: |
|---|
| 382 |
// Don't return static arrays in registers |
|---|
| 383 |
// (indexing registers doesn't work well) |
|---|
| 384 |
return false; |
|---|
| 385 |
|
|---|
| 386 |
default: { |
|---|
| 387 |
DRegCount needed = regsNeededForSimpleType(field->type); |
|---|
| 388 |
if (needed.ints > left.ints || needed.sse > left.sse || needed.x87 > left.x87) |
|---|
| 389 |
return false; |
|---|
| 390 |
left.ints -= needed.ints; |
|---|
| 391 |
left.sse -= needed.sse; |
|---|
| 392 |
left.x87 -= needed.x87; |
|---|
| 393 |
break; |
|---|
| 394 |
} |
|---|
| 395 |
} |
|---|
| 396 |
} |
|---|
| 397 |
return true; |
|---|
| 398 |
} |
|---|
| 399 |
|
|---|
| 400 |
// Returns true if the struct fits in return registers in the x86-64 fastcc |
|---|
| 401 |
// calling convention. |
|---|
| 402 |
bool retStructInRegs(TypeStruct* st) { |
|---|
| 403 |
// 'fastcc' allows returns in up to two registers of each kind: |
|---|
| 404 |
DRegCount state(2, 2, 2); |
|---|
| 405 |
return shouldPassStructInRegs(st, state); |
|---|
| 406 |
} |
|---|
| 407 |
|
|---|
| 408 |
// Heuristic for determining whether to pass a struct type directly or |
|---|
| 409 |
// bump it to memory. |
|---|
| 410 |
bool passStructTypeDirectly(TypeStruct* st) { |
|---|
| 411 |
// If the type fits in a reasonable number of registers, |
|---|
| 412 |
// pass it directly. |
|---|
| 413 |
// This does not necessarily mean it will actually be passed in |
|---|
| 414 |
// registers. For example, x87 registers are never actually used for |
|---|
| 415 |
// parameters. |
|---|
| 416 |
DRegCount state(2, 2, 2); |
|---|
| 417 |
return shouldPassStructInRegs(st, state); |
|---|
| 418 |
|
|---|
| 419 |
// This doesn't work well: Since the register count can differ depending |
|---|
| 420 |
// on backend options, there's no way to be exact anyway. |
|---|
| 421 |
/* |
|---|
| 422 |
// Regular fastcc: 6 int, 8 sse, 0 x87 |
|---|
| 423 |
// fastcc + tailcall: 5 int, 8 sse, 0 x87 |
|---|
| 424 |
RegCount state(5, 8, 0); |
|---|
| 425 |
*/ |
|---|
| 426 |
} |
|---|
| 427 |
} |
|---|
| 428 |
|
|---|
| 429 |
//////////////////////////////////////////////////////////////////////////////// |
|---|
| 430 |
//////////////////////////////////////////////////////////////////////////////// |
|---|
| 431 |
//////////////////////////////////////////////////////////////////////////////// |
|---|
| 432 |
//////////////////////////////////////////////////////////////////////////////// |
|---|
| 433 |
|
|---|
| 434 |
|
|---|
| 435 |
/// Just store to memory and it's readable as the other type. |
|---|
| 436 |
struct X86_64_C_struct_rewrite : ABIRewrite { |
|---|
| 437 |
// Get struct from ABI-mangled representation |
|---|
| 438 |
LLValue* get(Type* dty, DValue* v) |
|---|
| 439 |
{ |
|---|
| 440 |
LLValue* lval; |
|---|
| 441 |
if (v->isLVal()) { |
|---|
| 442 |
lval = v->getLVal(); |
|---|
| 443 |
} else { |
|---|
| 444 |
// No memory location, create one. |
|---|
| 445 |
LLValue* rval = v->getRVal(); |
|---|
| 446 |
lval = DtoRawAlloca(rval->getType(), 0); |
|---|
| 447 |
DtoStore(rval, lval); |
|---|
| 448 |
} |
|---|
| 449 |
|
|---|
| 450 |
const LLType* pTy = getPtrToType(DtoType(dty)); |
|---|
| 451 |
return DtoLoad(DtoBitCast(lval, pTy), "get-result"); |
|---|
| 452 |
} |
|---|
| 453 |
|
|---|
| 454 |
// Get struct from ABI-mangled representation, and store in the provided location. |
|---|
| 455 |
void getL(Type* dty, DValue* v, llvm::Value* lval) { |
|---|
| 456 |
LLValue* rval = v->getRVal(); |
|---|
| 457 |
const LLType* pTy = getPtrToType(rval->getType()); |
|---|
| 458 |
DtoStore(rval, DtoBitCast(lval, pTy)); |
|---|
| 459 |
} |
|---|
| 460 |
|
|---|
| 461 |
// Turn a struct into an ABI-mangled representation |
|---|
| 462 |
LLValue* put(Type* dty, DValue* v) |
|---|
| 463 |
{ |
|---|
| 464 |
LLValue* lval; |
|---|
| 465 |
if (v->isLVal()) { |
|---|
| 466 |
lval = v->getLVal(); |
|---|
| 467 |
} else { |
|---|
| 468 |
// No memory location, create one. |
|---|
| 469 |
LLValue* rval = v->getRVal(); |
|---|
| 470 |
lval = DtoRawAlloca(rval->getType(), 0); |
|---|
| 471 |
DtoStore(rval, lval); |
|---|
| 472 |
} |
|---|
| 473 |
|
|---|
| 474 |
LLType* abiTy = getAbiType(dty); |
|---|
| 475 |
assert(abiTy && "Why are we rewriting a non-rewritten type?"); |
|---|
| 476 |
|
|---|
| 477 |
const LLType* pTy = getPtrToType(abiTy); |
|---|
| 478 |
return DtoLoad(DtoBitCast(lval, pTy), "put-result"); |
|---|
| 479 |
} |
|---|
| 480 |
|
|---|
| 481 |
/// should return the transformed type for this rewrite |
|---|
| 482 |
const LLType* type(Type* dty, const LLType* t) |
|---|
| 483 |
{ |
|---|
| 484 |
return getAbiType(dty); |
|---|
| 485 |
} |
|---|
| 486 |
}; |
|---|
| 487 |
|
|---|
| 488 |
|
|---|
| 489 |
struct RegCount { |
|---|
| 490 |
unsigned char int_regs, sse_regs; |
|---|
| 491 |
}; |
|---|
| 492 |
|
|---|
| 493 |
|
|---|
| 494 |
struct X86_64TargetABI : TargetABI { |
|---|
| 495 |
X86_64_C_struct_rewrite struct_rewrite; |
|---|
| 496 |
RemoveStructPadding remove_padding; |
|---|
| 497 |
|
|---|
| 498 |
void newFunctionType(TypeFunction* tf) { |
|---|
| 499 |
funcTypeStack.push_back(FuncTypeData(tf->linkage)); |
|---|
| 500 |
} |
|---|
| 501 |
|
|---|
| 502 |
bool returnInArg(TypeFunction* tf); |
|---|
| 503 |
|
|---|
| 504 |
bool passByVal(Type* t); |
|---|
| 505 |
|
|---|
| 506 |
void rewriteFunctionType(TypeFunction* tf); |
|---|
| 507 |
|
|---|
| 508 |
void doneWithFunctionType() { |
|---|
| 509 |
funcTypeStack.pop_back(); |
|---|
| 510 |
} |
|---|
| 511 |
|
|---|
| 512 |
private: |
|---|
| 513 |
struct FuncTypeData { |
|---|
| 514 |
LINK linkage; // Linkage of the function type currently under construction |
|---|
| 515 |
RegCount state; // bookkeeping for extern(C) parameter registers |
|---|
| 516 |
|
|---|
| 517 |
FuncTypeData(LINK linkage_) |
|---|
| 518 |
: linkage(linkage_) |
|---|
| 519 |
{ |
|---|
| 520 |
state.int_regs = 6; |
|---|
| 521 |
state.sse_regs = 8; |
|---|
| 522 |
} |
|---|
| 523 |
}; |
|---|
| 524 |
std::vector<FuncTypeData> funcTypeStack; |
|---|
| 525 |
|
|---|
| 526 |
LINK linkage() { |
|---|
| 527 |
assert(funcTypeStack.size() != 0); |
|---|
| 528 |
return funcTypeStack.back().linkage; |
|---|
| 529 |
} |
|---|
| 530 |
|
|---|
| 531 |
RegCount& state() { |
|---|
| 532 |
assert(funcTypeStack.size() != 0); |
|---|
| 533 |
return funcTypeStack.back().state; |
|---|
| 534 |
} |
|---|
| 535 |
|
|---|
| 536 |
void fixup_D(IrFuncTyArg& arg); |
|---|
| 537 |
void fixup(IrFuncTyArg& arg); |
|---|
| 538 |
}; |
|---|
| 539 |
|
|---|
| 540 |
|
|---|
| 541 |
// The public getter for abi.cpp |
|---|
| 542 |
TargetABI* getX86_64TargetABI() { |
|---|
| 543 |
return new X86_64TargetABI; |
|---|
| 544 |
} |
|---|
| 545 |
|
|---|
| 546 |
|
|---|
| 547 |
bool X86_64TargetABI::returnInArg(TypeFunction* tf) { |
|---|
| 548 |
assert(linkage() == tf->linkage); |
|---|
| 549 |
Type* rt = tf->next->toBasetype(); |
|---|
| 550 |
|
|---|
| 551 |
if (tf->linkage == LINKd) { |
|---|
| 552 |
assert(rt->ty != Tsarray && "Update calling convention for static array returns"); |
|---|
| 553 |
|
|---|
| 554 |
// All non-structs can be returned in registers. |
|---|
| 555 |
if (rt->ty != Tstruct) |
|---|
| 556 |
return false; |
|---|
| 557 |
|
|---|
| 558 |
// Try to figure out whether the struct fits in return registers |
|---|
| 559 |
// and whether it's a good idea to put it there. |
|---|
| 560 |
return !x86_64_D_cc::retStructInRegs((TypeStruct*) rt); |
|---|
| 561 |
} else { |
|---|
| 562 |
if (rt == Type::tvoid || keepUnchanged(rt)) |
|---|
| 563 |
return false; |
|---|
| 564 |
|
|---|
| 565 |
Classification cl = classify(rt); |
|---|
| 566 |
if (cl.isMemory) { |
|---|
| 567 |
assert(state().int_regs > 0 |
|---|
| 568 |
&& "No int registers available when determining sret-ness?"); |
|---|
| 569 |
// An sret parameter takes an integer register. |
|---|
| 570 |
state().int_regs--; |
|---|
| 571 |
return true; |
|---|
| 572 |
} |
|---|
| 573 |
return false; |
|---|
| 574 |
} |
|---|
| 575 |
} |
|---|
| 576 |
|
|---|
| 577 |
bool X86_64TargetABI::passByVal(Type* t) { |
|---|
| 578 |
t = t->toBasetype(); |
|---|
| 579 |
if (linkage() == LINKd) { |
|---|
| 580 |
if (t->ty != Tstruct) |
|---|
| 581 |
return false; |
|---|
| 582 |
|
|---|
| 583 |
// Try to be smart about which structs are passed in memory. |
|---|
| 584 |
return !x86_64_D_cc::passStructTypeDirectly((TypeStruct*) t); |
|---|
| 585 |
} else { |
|---|
| 586 |
// This implements the C calling convention for x86-64. |
|---|
| 587 |
// It might not be correct for other calling conventions. |
|---|
| 588 |
Classification cl = classify(t); |
|---|
| 589 |
if (cl.isMemory) |
|---|
| 590 |
return true; |
|---|
| 591 |
|
|---|
| 592 |
// Figure out how many registers we want for this arg: |
|---|
| 593 |
RegCount wanted = { 0, 0 }; |
|---|
| 594 |
for (int i = 0 ; i < 2; i++) { |
|---|
| 595 |
if (cl.classes[i] == Integer) |
|---|
| 596 |
wanted.int_regs++; |
|---|
| 597 |
else if (cl.classes[i] == Sse) |
|---|
| 598 |
wanted.sse_regs++; |
|---|
| 599 |
} |
|---|
| 600 |
|
|---|
| 601 |
// See if they're available: |
|---|
| 602 |
RegCount& state = this->state(); |
|---|
| 603 |
if (wanted.int_regs <= state.int_regs && wanted.sse_regs <= state.sse_regs) { |
|---|
| 604 |
state.int_regs -= wanted.int_regs; |
|---|
| 605 |
state.sse_regs -= wanted.sse_regs; |
|---|
| 606 |
} else { |
|---|
| 607 |
if (keepUnchanged(t)) { |
|---|
| 608 |
// Not enough registers available, but this is passed as if it's |
|---|
| 609 |
// multiple arguments. Just use the registers there are, |
|---|
| 610 |
// automatically spilling the rest to memory. |
|---|
| 611 |
if (wanted.int_regs > state.int_regs) |
|---|
| 612 |
state.int_regs = 0; |
|---|
| 613 |
else |
|---|
| 614 |
state.int_regs -= wanted.int_regs; |
|---|
| 615 |
|
|---|
| 616 |
if (wanted.sse_regs > state.sse_regs) |
|---|
| 617 |
state.sse_regs = 0; |
|---|
| 618 |
else |
|---|
| 619 |
state.sse_regs -= wanted.sse_regs; |
|---|
| 620 |
} else if (t->iscomplex() || t->ty == Tstruct) { |
|---|
| 621 |
// Spill entirely to memory, even if some of the registers are |
|---|
| 622 |
// available. |
|---|
| 623 |
|
|---|
| 624 |
// FIXME: Don't do this if *none* of the wanted registers are available, |
|---|
| 625 |
// (i.e. only when absolutely necessary for abi-compliance) |
|---|
| 626 |
// so it gets alloca'd by the callee and -scalarrepl can |
|---|
| 627 |
// more easily break it up? |
|---|
| 628 |
// Note: this won't be necessary if the following LLVM bug gets fixed: |
|---|
| 629 |
// http://llvm.org/bugs/show_bug.cgi?id=3741 |
|---|
| 630 |
return true; |
|---|
| 631 |
} else { |
|---|
| 632 |
assert(t == Type::tfloat80 || t == Type::timaginary80 || t->size() <= 8 |
|---|
| 633 |
&& "What other big types are there?"); // other than static arrays... |
|---|
| 634 |
// In any case, they shouldn't be represented as structs in LLVM: |
|---|
| 635 |
assert(!isaStruct(DtoType(t))); |
|---|
| 636 |
} |
|---|
| 637 |
} |
|---|
| 638 |
// Everything else that's passed in memory is handled by LLVM. |
|---|
| 639 |
return false; |
|---|
| 640 |
} |
|---|
| 641 |
} |
|---|
| 642 |
|
|---|
| 643 |
// Helper function for rewriteFunctionType. |
|---|
| 644 |
// Structs passed or returned in registers are passed here |
|---|
| 645 |
// to get their padding removed (if necessary). |
|---|
| 646 |
void X86_64TargetABI::fixup_D(IrFuncTyArg& arg) { |
|---|
| 647 |
assert(arg.type->ty == Tstruct); |
|---|
| 648 |
LLType* abiTy = DtoUnpaddedStructType(arg.type); |
|---|
| 649 |
|
|---|
| 650 |
if (abiTy && abiTy != arg.ltype) { |
|---|
| 651 |
arg.ltype = abiTy; |
|---|
| 652 |
arg.rewrite = &remove_padding; |
|---|
| 653 |
} |
|---|
| 654 |
} |
|---|
| 655 |
|
|---|
| 656 |
// Helper function for rewriteFunctionType. |
|---|
| 657 |
// Return type and parameters are passed here (unless they're already in memory) |
|---|
| 658 |
// to get the rewrite applied (if necessary). |
|---|
| 659 |
void X86_64TargetABI::fixup(IrFuncTyArg& arg) { |
|---|
| 660 |
LLType* abiTy = getAbiType(arg.type); |
|---|
| 661 |
|
|---|
| 662 |
if (abiTy && abiTy != arg.ltype) { |
|---|
| 663 |
assert(arg.type == Type::tcomplex32 || arg.type->ty == Tstruct); |
|---|
| 664 |
arg.ltype = abiTy; |
|---|
| 665 |
arg.rewrite = &struct_rewrite; |
|---|
| 666 |
} |
|---|
| 667 |
} |
|---|
| 668 |
|
|---|
| 669 |
void X86_64TargetABI::rewriteFunctionType(TypeFunction* tf) { |
|---|
| 670 |
IrFuncTy& fty = tf->fty; |
|---|
| 671 |
|
|---|
| 672 |
if (tf->linkage == LINKd) { |
|---|
| 673 |
if (!fty.arg_sret) { |
|---|
| 674 |
Type* rt = fty.ret->type->toBasetype(); |
|---|
| 675 |
if (rt->ty == Tstruct) { |
|---|
| 676 |
Logger::println("x86-64 D ABI: Transforming return type"); |
|---|
| 677 |
fixup_D(*fty.ret); |
|---|
| 678 |
} |
|---|
| 679 |
} |
|---|
| 680 |
|
|---|
| 681 |
if (fty.arg_this) { |
|---|
| 682 |
fty.arg_this->attrs |= llvm::Attribute::Nest; |
|---|
| 683 |
} |
|---|
| 684 |
if (fty.arg_nest) { |
|---|
| 685 |
fty.arg_nest->attrs |= llvm::Attribute::Nest; |
|---|
| 686 |
} |
|---|
| 687 |
|
|---|
| 688 |
Logger::println("x86-64 D ABI: Transforming arguments"); |
|---|
| 689 |
LOG_SCOPE; |
|---|
| 690 |
|
|---|
| 691 |
for (IrFuncTy::ArgIter I = fty.args.begin(), E = fty.args.end(); I != E; ++I) { |
|---|
| 692 |
IrFuncTyArg& arg = **I; |
|---|
| 693 |
|
|---|
| 694 |
if (Logger::enabled()) |
|---|
| 695 |
Logger::cout() << "Arg: " << arg.type->toChars() << '\n'; |
|---|
| 696 |
|
|---|
| 697 |
// Arguments that are in memory are of no interest to us. |
|---|
| 698 |
if (arg.byref) |
|---|
| 699 |
continue; |
|---|
| 700 |
|
|---|
| 701 |
Type* ty = arg.type->toBasetype(); |
|---|
| 702 |
if (ty->ty == Tstruct) |
|---|
| 703 |
fixup_D(arg); |
|---|
| 704 |
|
|---|
| 705 |
if (Logger::enabled()) |
|---|
| 706 |
Logger::cout() << "New arg type: " << *arg.ltype << '\n'; |
|---|
| 707 |
} |
|---|
| 708 |
|
|---|
| 709 |
} else { |
|---|
| 710 |
// TODO: See if this is correct for more than just extern(C). |
|---|
| 711 |
|
|---|
| 712 |
if (!fty.arg_sret) { |
|---|
| 713 |
Logger::println("x86-64 ABI: Transforming return type"); |
|---|
| 714 |
Type* rt = fty.ret->type->toBasetype(); |
|---|
| 715 |
if (rt != Type::tvoid) |
|---|
| 716 |
fixup(*fty.ret); |
|---|
| 717 |
} |
|---|
| 718 |
|
|---|
| 719 |
|
|---|
| 720 |
Logger::println("x86-64 ABI: Transforming arguments"); |
|---|
| 721 |
LOG_SCOPE; |
|---|
| 722 |
|
|---|
| 723 |
for (IrFuncTy::ArgIter I = fty.args.begin(), E = fty.args.end(); I != E; ++I) { |
|---|
| 724 |
IrFuncTyArg& arg = **I; |
|---|
| 725 |
|
|---|
| 726 |
if (Logger::enabled()) |
|---|
| 727 |
Logger::cout() << "Arg: " << arg.type->toChars() << '\n'; |
|---|
| 728 |
|
|---|
| 729 |
// Arguments that are in memory are of no interest to us. |
|---|
| 730 |
if (arg.byref) |
|---|
| 731 |
continue; |
|---|
| 732 |
|
|---|
| 733 |
Type* ty = arg.type->toBasetype(); |
|---|
| 734 |
|
|---|
| 735 |
fixup(arg); |
|---|
| 736 |
if (Logger::enabled()) |
|---|
| 737 |
Logger::cout() << "New arg type: " << *arg.ltype << '\n'; |
|---|
| 738 |
} |
|---|
| 739 |
} |
|---|
| 740 |
} |
|---|