mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-02 08:01:11 +03:00
Merge branch 'ltsmaster'
This commit is contained in:
commit
dcb781004b
14 changed files with 80 additions and 22 deletions
|
@ -1583,7 +1583,7 @@ public:
|
|||
if (f.linkage == LINKd || (f.parameters && Parameter.dim(f.parameters)))
|
||||
{
|
||||
// Declare _argptr
|
||||
Type t = Type.tvalist;
|
||||
Type t = Type.tvalist.semantic(loc, sc);
|
||||
argptr = new VarDeclaration(Loc(), t, Id._argptr, null);
|
||||
argptr.storage_class |= STCtemp;
|
||||
argptr.semantic(sc2);
|
||||
|
|
|
@ -230,10 +230,23 @@ static int linkObjToBinaryGcc(bool sharedLib, bool fullyStatic) {
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
if (global.params.is64bit) {
|
||||
args.push_back("-m64");
|
||||
} else {
|
||||
args.push_back("-m32");
|
||||
switch (global.params.targetTriple.getArch()) {
|
||||
case llvm::Triple::arm:
|
||||
case llvm::Triple::armeb:
|
||||
case llvm::Triple::aarch64:
|
||||
case llvm::Triple::aarch64_be:
|
||||
#if LDC_LLVM_VER == 305
|
||||
case llvm::Triple::arm64:
|
||||
case llvm::Triple::arm64_be:
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
if (global.params.is64bit) {
|
||||
args.push_back("-m64");
|
||||
}
|
||||
else {
|
||||
args.push_back("-m32");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,8 +112,7 @@ struct AArch64TargetABI : TargetABI {
|
|||
// using TypeIdentifier here is a bit wonky but works, as long as the name
|
||||
// is actually available in the scope (this is what DMD does, so if a better
|
||||
// solution is found there, this should be adapted).
|
||||
return (createTypeIdentifier(Loc(), Identifier::idPool("__va_list_tag")))
|
||||
->pointerTo();
|
||||
return (new TypeIdentifier(Loc(), Identifier::idPool("__va_list")));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -67,14 +67,29 @@ struct ArmTargetABI : TargetABI {
|
|||
}
|
||||
|
||||
bool passByVal(Type *t) override {
|
||||
// AAPCS does not pass byval
|
||||
return false;
|
||||
// AAPCS does not use an indirect arg to pass aggregates, however
|
||||
// clang uses byval for types > 64-bytes, then llvm backend
|
||||
// converts back to non-byval. Without this special handling the
|
||||
// optimzer generates bad code (e.g. std.random unittest crash).
|
||||
t = t->toBasetype();
|
||||
return ((t->ty == Tsarray || t->ty == Tstruct) && t->size() > 64);
|
||||
|
||||
// Note: the codegen is horrible for Tsarrays passed this way - tries to do
|
||||
// copy without a loop for huge arrays. Would be better if byval was used
|
||||
// for arrays, but then there is an optimizer problem in the "top-down list
|
||||
// latency scheduler" pass that reorders instructions incorrectly if byval
|
||||
// used.
|
||||
// Note: byval can have a codegen problem with -O1 and higher.
|
||||
// What happens is that load instructions are being incorrectly
|
||||
// reordered before stores. It is a problem in the LLVM backend.
|
||||
// The outcome is a program with incorrect results or crashes.
|
||||
// It happens in the "top-down list latency scheduler" pass
|
||||
//
|
||||
// https://forum.dlang.org/post/m2r3u5ac0c.fsf@comcast.net
|
||||
//
|
||||
// Revist and determine if the byval problem is only for small
|
||||
// structs, say 16-bytes or less, that can entirely fit in
|
||||
// registers.
|
||||
|
||||
// Note: the codegen is horrible for Tsarrays passed this way -
|
||||
// does a copy without a loop for huge arrays. Could be better if
|
||||
// byval was always used for sarrays, and maybe can if above
|
||||
// problem is better understood.
|
||||
}
|
||||
|
||||
void rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) override {
|
||||
|
@ -94,6 +109,11 @@ struct ArmTargetABI : TargetABI {
|
|||
if (!arg->byref)
|
||||
rewriteArgument(fty, *arg);
|
||||
}
|
||||
|
||||
// extern(D): reverse parameter order for non variadics, for DMD-compliance
|
||||
if (tf->linkage == LINKd && tf->varargs != 1 && fty.args.size() > 1) {
|
||||
fty.reverseParams = true;
|
||||
}
|
||||
}
|
||||
|
||||
void rewriteArgument(IrFuncTy &fty, IrFuncTyArg &arg) override {
|
||||
|
|
|
@ -114,7 +114,10 @@ Statement *asmSemantic(AsmStatement *s, Scope *sc) {
|
|||
err = true;
|
||||
}
|
||||
if (err) {
|
||||
fatal();
|
||||
if (!global.gag) {
|
||||
fatal();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
// puts(toChars());
|
||||
|
|
|
@ -883,7 +883,7 @@ void DtoDefineFunction(FuncDeclaration *fd) {
|
|||
// D varargs: prepare _argptr and _arguments
|
||||
if (f->linkage == LINKd && f->varargs == 1) {
|
||||
// allocate _argptr (of type core.stdc.stdarg.va_list)
|
||||
LLValue *argptrmem = DtoAlloca(Type::tvalist, "_argptr_mem");
|
||||
LLValue *argptrmem = DtoAlloca(Type::tvalist->semantic(fd->loc, fd->scope), "_argptr_mem");
|
||||
irFunc->_argptr = argptrmem;
|
||||
|
||||
// initialize _argptr with a call to the va_start intrinsic
|
||||
|
|
|
@ -63,7 +63,9 @@ LLAttribute DtoShouldExtend(Type *type) {
|
|||
|
||||
case Tuns8:
|
||||
case Tuns16:
|
||||
return LLAttribute::ZExt;
|
||||
case Tchar:
|
||||
case Twchar:
|
||||
return LLAttribute::ZExt;
|
||||
|
||||
default:
|
||||
// Do not extend.
|
||||
|
@ -410,6 +412,15 @@ LLConstant *DtoConstFP(Type *t, longdouble value) {
|
|||
return LLConstantFP::get(gIR->context(), APFloat(APFloat::x87DoubleExtended,
|
||||
APInt(80, 2, bits)));
|
||||
}
|
||||
if (llty == LLType::getFP128Ty(gIR->context())) {
|
||||
union {
|
||||
longdouble ld;
|
||||
uint64_t bits[2];
|
||||
} t;
|
||||
t.ld = value;
|
||||
return LLConstantFP::get(
|
||||
gIR->context(), APFloat(APFloat::IEEEquad, APInt(128, 2, t.bits)));
|
||||
}
|
||||
if (llty == LLType::getPPC_FP128Ty(gIR->context())) {
|
||||
uint64_t bits[] = {0, 0};
|
||||
bits[0] = *reinterpret_cast<uint64_t *>(&value);
|
||||
|
|
|
@ -27,7 +27,9 @@ void IrDsymbol::resetAll() {
|
|||
}
|
||||
}
|
||||
|
||||
IrDsymbol::IrDsymbol() { list.push_back(this); }
|
||||
IrDsymbol::IrDsymbol() : irData(nullptr) {
|
||||
list.push_back(this);
|
||||
}
|
||||
|
||||
IrDsymbol::IrDsymbol(const IrDsymbol &s) {
|
||||
list.push_back(this);
|
||||
|
|
|
@ -83,7 +83,7 @@ private:
|
|||
friend IrField *getIrField(VarDeclaration *decl, bool create);
|
||||
|
||||
union {
|
||||
void *irData = nullptr;
|
||||
void *irData;
|
||||
IrModule *irModule;
|
||||
IrAggr *irAggr;
|
||||
IrFunction *irFunc;
|
||||
|
|
|
@ -48,12 +48,21 @@ namespace {
|
|||
llvm::Type *getReal80Type(llvm::LLVMContext &ctx) {
|
||||
llvm::Triple::ArchType const a = global.params.targetTriple->getArch();
|
||||
bool const anyX86 = (a == llvm::Triple::x86) || (a == llvm::Triple::x86_64);
|
||||
bool const anyAarch64 = (a == llvm::Triple::aarch64) || (a == llvm::Triple::aarch64_be)
|
||||
#if LDC_LLVM_VER == 305
|
||||
|| (a == llvm::Triple::arm64) || (a == llvm::Triple::arm64_be)
|
||||
#endif
|
||||
;
|
||||
|
||||
// only x86 has 80bit float - but no support with MS C Runtime!
|
||||
if (anyX86 && !global.params.targetTriple->isWindowsMSVCEnvironment()) {
|
||||
return llvm::Type::getX86_FP80Ty(ctx);
|
||||
}
|
||||
|
||||
if (anyAarch64) {
|
||||
return llvm::Type::getFP128Ty(ctx);
|
||||
}
|
||||
|
||||
return llvm::Type::getDoubleTy(ctx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,6 +116,7 @@ if(UNIX)
|
|||
message(WARNING "Please consider updating CMake to at least 2.8.5.")
|
||||
else()
|
||||
list(APPEND DCRT_ASM ${RUNTIME_DIR}/src/core/threadasm.S)
|
||||
list(APPEND DCRT_ASM ${RUNTIME_DIR}/src/ldc/eh_asm.S)
|
||||
endif()
|
||||
if(APPLE)
|
||||
list(APPEND CORE_D_SYS ${CORE_D_OSX})
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit ced8af41ffaf887ef534279289fd857eaa45648a
|
||||
Subproject commit fa0c558126f108a4a991d1d206925427dd4bfaae
|
|
@ -1 +1 @@
|
|||
Subproject commit 32c89fac4ec8cf58b7489ff4437a2577a9a7dba9
|
||||
Subproject commit 1ada8d5571bbfefc71ab45bb102a5455ff54dcb5
|
|
@ -1 +1 @@
|
|||
Subproject commit 331edbc588b60f6adee8eddb78bed97415bc95da
|
||||
Subproject commit 729534b5cc3d2f4e058c54796988efb6c3ed3151
|
Loading…
Add table
Add a link
Reference in a new issue