ldc/gen/target.cpp
David Nadlinger 9f998a398d Initial merge of upstream v2.071.0-b2
Notably, the glue layer side of the changed multiple interface
inheritance layout (DMD a54e89d) has not been implemented yet.

This corresponds to DMD commit 3f6a763c0589dd03c1c206eafd434b593702564e.
2016-04-03 15:15:14 +01:00

180 lines
4.5 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.

//===-- target.cpp -------------------------------------------------------===//
//
// LDC the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===//
#include "ldcbindings.h"
#include "target.h"
#include "gen/abi.h"
#include "gen/irstate.h"
#include "gen/llvmhelpers.h"
#include "mars.h"
#include "mtype.h"
#include <assert.h>
#if !defined(_MSC_VER)
#include <pthread.h>
#endif
/*
These guys are allocated by ddmd/target.d:
int Target::ptrsize;
int Target::realsize;
int Target::realpad;
int Target::realalignsize;
int Target::c_longsize;
int Target::c_long_doublesize;
bool Target::reverseCppOverloads;
*/
void Target::_init() {
ptrsize = gDataLayout->getPointerSize(ADDRESS_SPACE);
llvm::Type *real = DtoType(Type::basic[Tfloat80]);
realsize = gDataLayout->getTypeAllocSize(real);
realpad = realsize - gDataLayout->getTypeStoreSize(real);
realalignsize = gDataLayout->getABITypeAlignment(real);
c_longsize = global.params.is64bit ? 8 : 4;
c_long_doublesize = realsize;
// according to DMD, only for MSVC++:
reverseCppOverloads = global.params.targetTriple->isWindowsMSVCEnvironment();
// LDC_FIXME: Set once we support it.
cppExceptions = false;
}
/******************************
* Return memory alignment size of type.
*/
unsigned Target::alignsize(Type *type) {
assert(type->isTypeBasic());
if (type->ty == Tvoid) {
return 1;
}
return gDataLayout->getABITypeAlignment(DtoType(type));
}
/******************************
* Return field alignment size of type.
*/
unsigned Target::fieldalign(Type *type) { return DtoAlignment(type); }
// sizes based on those from tollvm.cpp:DtoMutexType()
unsigned Target::critsecsize() {
#if defined(_MSC_VER)
// Return sizeof(RTL_CRITICAL_SECTION)
return global.params.is64bit ? 40 : 24;
#else
if (global.params.targetTriple->isOSWindows()) {
return global.params.is64bit ? 40 : 24;
}
if (global.params.targetTriple->isOSFreeBSD() ||
#if LDC_LLVM_VER > 305
global.params.targetTriple->isOSNetBSD() ||
global.params.targetTriple->isOSOpenBSD() ||
global.params.targetTriple->isOSDragonFly()
#else
global.params.targetTriple->getOS() == llvm::Triple::NetBSD ||
global.params.targetTriple->getOS() == llvm::Triple::OpenBSD ||
global.params.targetTriple->getOS() == llvm::Triple::DragonFly
#endif
) {
return sizeof(size_t);
}
return sizeof(pthread_mutex_t);
#endif
}
Type *Target::va_listType() { return gABI->vaListType(); }
/******************************
* Encode the given expression, which is assumed to be an rvalue literal
* as another type for use in CTFE.
* This corresponds roughly to the idiom *(Type *)&e.
*/
Expression *Target::paintAsType(Expression *e, Type *type) {
union {
d_int32 int32value;
d_int64 int64value;
float float32value;
double float64value;
} u;
assert(e->type->size() == type->size());
switch (e->type->ty) {
case Tint32:
case Tuns32:
u.int32value = static_cast<d_int32>(e->toInteger());
break;
case Tint64:
case Tuns64:
u.int64value = static_cast<d_int64>(e->toInteger());
break;
case Tfloat32:
u.float32value = e->toReal();
break;
case Tfloat64:
u.float64value = e->toReal();
break;
default:
assert(0);
}
switch (type->ty) {
case Tint32:
case Tuns32:
return createIntegerExp(e->loc, u.int32value, type);
case Tint64:
case Tuns64:
return createIntegerExp(e->loc, u.int64value, type);
case Tfloat32:
return createRealExp(e->loc, ldouble(u.float32value), type);
case Tfloat64:
return createRealExp(e->loc, ldouble(u.float64value), type);
default:
assert(0);
}
return nullptr; // avoid warning
}
/******************************
* Check if the given type is supported for this target
* 0: supported
* 1: not supported
* 2: wrong size
* 3: wrong base type
*/
int Target::checkVectorType(int sz, Type *type) {
// FIXME: It is possible to query the LLVM target about supported vectors?
return 0;
}
/******************************
* For the given module, perform any post parsing analysis.
* Certain compiler backends (ie: GDC) have special placeholder
* modules whose source are empty, but code gets injected
* immediately after loading.
*/
void Target::loadModule(Module *m) {}
/******************************
*
*/
void Target::prefixName(OutBuffer *buf, LINK linkage) {}