Mercurial > projects > ldc
comparison gen/abi.cpp @ 1359:34f2fd925de3
Intrinsics shouldn't see struct padding, so use a special TargetABI for them
that removes it.
This unbreaks the `llvm_*_with_overflow` intrinsics.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Sat, 16 May 2009 13:06:49 +0200 |
parents | 15e9762bb620 |
children | c363d131c1ef |
comparison
equal
deleted
inserted
replaced
1357:48747003a5de | 1359:34f2fd925de3 |
---|---|
8 #include "gen/llvmhelpers.h" | 8 #include "gen/llvmhelpers.h" |
9 #include "gen/tollvm.h" | 9 #include "gen/tollvm.h" |
10 #include "gen/abi.h" | 10 #include "gen/abi.h" |
11 #include "gen/logger.h" | 11 #include "gen/logger.h" |
12 #include "gen/dvalue.h" | 12 #include "gen/dvalue.h" |
13 #include "gen/abi-generic.h" | |
13 | 14 |
14 #include "ir/irfunction.h" | 15 #include "ir/irfunction.h" |
15 | 16 |
16 ////////////////////////////////////////////////////////////////////////////// | 17 ////////////////////////////////////////////////////////////////////////////// |
17 | 18 |
309 default: | 310 default: |
310 Logger::cout() << "WARNING: Unknown ABI, guessing...\n"; | 311 Logger::cout() << "WARNING: Unknown ABI, guessing...\n"; |
311 return new UnknownTargetABI; | 312 return new UnknownTargetABI; |
312 } | 313 } |
313 } | 314 } |
315 | |
316 ////////////////////////////////////////////////////////////////////////////// | |
317 ////////////////////////////////////////////////////////////////////////////// | |
318 ////////////////////////////////////////////////////////////////////////////// | |
319 ////////////////////////////////////////////////////////////////////////////// | |
320 ////////////////////////////////////////////////////////////////////////////// | |
321 | |
322 // A simple ABI for LLVM intrinsics. | |
323 struct IntrinsicABI : TargetABI | |
324 { | |
325 RemoveStructPadding remove_padding; | |
326 | |
327 bool returnInArg(TypeFunction* tf) | |
328 { | |
329 return false; | |
330 } | |
331 | |
332 bool passByVal(Type* t) | |
333 { | |
334 return false; | |
335 } | |
336 | |
337 void fixup(IrFuncTyArg& arg) { | |
338 assert(arg.type->ty == Tstruct); | |
339 // TODO: Check that no unions are passed in or returned. | |
340 | |
341 LLType* abiTy = DtoUnpaddedStructType(arg.type); | |
342 | |
343 if (abiTy && abiTy != arg.ltype) { | |
344 arg.ltype = abiTy; | |
345 arg.rewrite = &remove_padding; | |
346 } | |
347 } | |
348 | |
349 void rewriteFunctionType(TypeFunction* tf) | |
350 { | |
351 assert(tf->linkage == LINKintrinsic); | |
352 | |
353 IrFuncTy& fty = tf->fty; | |
354 | |
355 if (!fty.arg_sret) { | |
356 Type* rt = fty.ret->type->toBasetype(); | |
357 if (rt->ty == Tstruct) { | |
358 Logger::println("Intrinsic ABI: Transforming return type"); | |
359 fixup(*fty.ret); | |
360 } | |
361 } | |
362 | |
363 Logger::println("Intrinsic ABI: Transforming arguments"); | |
364 LOG_SCOPE; | |
365 | |
366 for (IrFuncTy::ArgIter I = fty.args.begin(), E = fty.args.end(); I != E; ++I) { | |
367 IrFuncTyArg& arg = **I; | |
368 | |
369 if (Logger::enabled()) | |
370 Logger::cout() << "Arg: " << arg.type->toChars() << '\n'; | |
371 | |
372 // Arguments that are in memory are of no interest to us. | |
373 if (arg.byref) | |
374 continue; | |
375 | |
376 Type* ty = arg.type->toBasetype(); | |
377 if (ty->ty == Tstruct) | |
378 fixup(arg); | |
379 | |
380 if (Logger::enabled()) | |
381 Logger::cout() << "New arg type: " << *arg.ltype << '\n'; | |
382 } | |
383 } | |
384 }; | |
385 | |
386 TargetABI * TargetABI::getIntrinsic() | |
387 { | |
388 static IntrinsicABI iabi; | |
389 return &iabi; | |
390 } |