Mercurial > projects > ldc
diff 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 |
line wrap: on
line diff
--- a/gen/abi.cpp Fri May 15 17:17:20 2009 +0200 +++ b/gen/abi.cpp Sat May 16 13:06:49 2009 +0200 @@ -10,6 +10,7 @@ #include "gen/abi.h" #include "gen/logger.h" #include "gen/dvalue.h" +#include "gen/abi-generic.h" #include "ir/irfunction.h" @@ -311,3 +312,79 @@ return new UnknownTargetABI; } } + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +// A simple ABI for LLVM intrinsics. +struct IntrinsicABI : TargetABI +{ + RemoveStructPadding remove_padding; + + bool returnInArg(TypeFunction* tf) + { + return false; + } + + bool passByVal(Type* t) + { + return false; + } + + void fixup(IrFuncTyArg& arg) { + assert(arg.type->ty == Tstruct); + // TODO: Check that no unions are passed in or returned. + + LLType* abiTy = DtoUnpaddedStructType(arg.type); + + if (abiTy && abiTy != arg.ltype) { + arg.ltype = abiTy; + arg.rewrite = &remove_padding; + } + } + + void rewriteFunctionType(TypeFunction* tf) + { + assert(tf->linkage == LINKintrinsic); + + IrFuncTy& fty = tf->fty; + + if (!fty.arg_sret) { + Type* rt = fty.ret->type->toBasetype(); + if (rt->ty == Tstruct) { + Logger::println("Intrinsic ABI: Transforming return type"); + fixup(*fty.ret); + } + } + + Logger::println("Intrinsic ABI: Transforming arguments"); + LOG_SCOPE; + + for (IrFuncTy::ArgIter I = fty.args.begin(), E = fty.args.end(); I != E; ++I) { + IrFuncTyArg& arg = **I; + + if (Logger::enabled()) + Logger::cout() << "Arg: " << arg.type->toChars() << '\n'; + + // Arguments that are in memory are of no interest to us. + if (arg.byref) + continue; + + Type* ty = arg.type->toBasetype(); + if (ty->ty == Tstruct) + fixup(arg); + + if (Logger::enabled()) + Logger::cout() << "New arg type: " << *arg.ltype << '\n'; + } + } +}; + +TargetABI * TargetABI::getIntrinsic() +{ + static IntrinsicABI iabi; + return &iabi; +}