ldc/gen/abi-generic.h
2012-12-16 17:19:14 +01:00

114 lines
3.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//===-- gen/abi-generic.h - Generic Target ABI helpers ----------*- C++ -*-===//
//
// LDC the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===//
//
// Contains helpers for handling rewrites common to more than one target ABI.
//
//===----------------------------------------------------------------------===//
#ifndef LDC_GEN_ABI_GENERIC
#define LDC_GEN_ABI_GENERIC
#include "gen/llvmhelpers.h"
#include "gen/tollvm.h"
#include "gen/structs.h"
/// Removes padding fields for (non-union-containing!) structs
struct RemoveStructPadding : ABIRewrite {
/// get a rewritten value back to its original form
virtual LLValue* get(Type* dty, DValue* v) {
LLValue* lval = DtoAlloca(dty, ".rewritetmp");
getL(dty, v, lval);
return lval;
}
/// get a rewritten value back to its original form and store result in provided lvalue
/// this one is optional and defaults to calling the one above
virtual void getL(Type* dty, DValue* v, llvm::Value* lval) {
// Make sure the padding is zero, so struct comparisons work.
// TODO: Only do this if there's padding, and/or only initialize padding.
DtoMemSetZero(lval, DtoConstSize_t(getTypePaddedSize(DtoType(dty))));
DtoPaddedStruct(dty->toBasetype(), v->getRVal(), lval);
}
/// put out rewritten value
virtual LLValue* put(Type* dty, DValue* v) {
return DtoUnpaddedStruct(dty->toBasetype(), v->getRVal());
}
/// return the transformed type for this rewrite
virtual LLType* type(Type* dty, LLType* t) {
return DtoUnpaddedStructType(dty->toBasetype());
}
};
//////////////////////////////////////////////////////////////////////////////
// simply swap of real/imag parts for proper x87 complex abi
struct X87_complex_swap : ABIRewrite
{
LLValue* get(Type*, DValue* v)
{
return DtoAggrPairSwap(v->getRVal());
}
LLValue* put(Type*, DValue* v)
{
return DtoAggrPairSwap(v->getRVal());
}
LLType* type(Type*, LLType* t)
{
return t;
}
};
//////////////////////////////////////////////////////////////////////////////
/**
* Rewrites a composite type parameter to an integer of the same size.
*
* This is needed in order to be able to use LLVM's inreg attribute to put
* struct and static array parameters into registers, because the attribute has
* slightly different semantics. For example, LLVM would store a [4 x i8] inreg
* in four registers (zero-extended), instead of a single 32bit one.
*
* The LLVM value in dv is expected to be a pointer to the parameter, as
* generated when lowering struct/static array paramters to LLVM byval.
*/
struct CompositeToInt : ABIRewrite
{
LLValue* get(Type* dty, DValue* dv)
{
Logger::println("rewriting integer -> %s", dty->toChars());
LLValue* mem = DtoAlloca(dty, ".int_to_composite");
LLValue* v = dv->getRVal();
DtoStore(v, DtoBitCast(mem, getPtrToType(v->getType())));
return DtoLoad(mem);
}
void getL(Type* dty, DValue* dv, llvm::Value* lval)
{
Logger::println("rewriting integer -> %s", dty->toChars());
LLValue* v = dv->getRVal();
DtoStore(v, DtoBitCast(lval, getPtrToType(v->getType())));
}
LLValue* put(Type* dty, DValue* dv)
{
Logger::println("rewriting %s -> integer", dty->toChars());
LLType* t = LLIntegerType::get(gIR->context(), dty->size() * 8);
return DtoLoad(DtoBitCast(dv->getRVal(), getPtrToType(t)));
}
LLType* type(Type* t, LLType*)
{
size_t sz = t->size() * 8;
return LLIntegerType::get(gIR->context(), sz);
}
};
#endif