Merge pull request #3288 from jacob-carlborg/ios

Add support for iOS, tvOS and watchOS
This commit is contained in:
Martin Kinkelin 2020-01-28 22:55:50 +01:00 committed by GitHub
commit 97e0d978ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 20 deletions

View file

@ -811,6 +811,21 @@ void registerPredefinedTargetVersions() {
VersionCondition::addPredefinedGlobalIdent("AIX"); VersionCondition::addPredefinedGlobalIdent("AIX");
VersionCondition::addPredefinedGlobalIdent("Posix"); VersionCondition::addPredefinedGlobalIdent("Posix");
break; break;
case llvm::Triple::IOS:
VersionCondition::addPredefinedGlobalIdent("iOS");
VersionCondition::addPredefinedGlobalIdent("Posix");
VersionCondition::addPredefinedGlobalIdent("CppRuntime_Clang");
break;
case llvm::Triple::TvOS:
VersionCondition::addPredefinedGlobalIdent("TVOS");
VersionCondition::addPredefinedGlobalIdent("Posix");
VersionCondition::addPredefinedGlobalIdent("CppRuntime_Clang");
break;
case llvm::Triple::WatchOS:
VersionCondition::addPredefinedGlobalIdent("WatchOS");
VersionCondition::addPredefinedGlobalIdent("Posix");
VersionCondition::addPredefinedGlobalIdent("CppRuntime_Clang");
break;
default: default:
if (triple.getEnvironment() == llvm::Triple::Android) { if (triple.getEnvironment() == llvm::Triple::Android) {
VersionCondition::addPredefinedGlobalIdent("Android"); VersionCondition::addPredefinedGlobalIdent("Android");

View file

@ -9,6 +9,7 @@
// //
// The Procedure Call Standard can be found here: // The Procedure Call Standard can be found here:
// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
// https://github.com/ARM-software/software-standards/blob/master/abi/aapcs64/aapcs64.rst
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -20,7 +21,7 @@
#include "gen/abi-generic.h" #include "gen/abi-generic.h"
/** /**
* The AACPS64 uses a special native va_list type: * The AAPCS64 uses a special native va_list type:
* *
* typedef struct __va_list { * typedef struct __va_list {
* void *__stack; // next stack param * void *__stack; // next stack param
@ -38,14 +39,16 @@
*/ */
struct AArch64TargetABI : TargetABI { struct AArch64TargetABI : TargetABI {
private: private:
const bool isDarwin;
IndirectByvalRewrite byvalRewrite; IndirectByvalRewrite byvalRewrite;
HFAToArray hfaToArray; HFAToArray hfaToArray;
CompositeToArray64 compositeToArray64; CompositeToArray64 compositeToArray64;
IntegerRewrite integerRewrite; IntegerRewrite integerRewrite;
bool isVaList(Type *t) { bool isAAPCS64VaList(Type *t) {
return t->ty == Tstruct && strcmp(t->toPrettyChars(true), return !isDarwin && t->ty == Tstruct &&
"ldc.internal.vararg.std.__va_list") == 0; strcmp(t->toPrettyChars(true),
"ldc.internal.vararg.std.__va_list") == 0;
} }
bool passIndirectlyByValue(Type *t) { bool passIndirectlyByValue(Type *t) {
@ -55,6 +58,8 @@ private:
} }
public: public:
AArch64TargetABI() : isDarwin(global.params.targetTriple->isOSDarwin()) {}
bool returnInArg(TypeFunction *tf, bool) override { bool returnInArg(TypeFunction *tf, bool) override {
if (tf->isref) { if (tf->isref) {
return false; return false;
@ -89,7 +94,7 @@ public:
if (t->ty != Tstruct && t->ty != Tsarray) if (t->ty != Tstruct && t->ty != Tsarray)
return; return;
if (!isReturnVal && isVaList(t)) { if (!isReturnVal && isAAPCS64VaList(t)) {
// compiler magic: pass va_list args implicitly by reference // compiler magic: pass va_list args implicitly by reference
arg.byref = true; arg.byref = true;
arg.ltype = arg.ltype->getPointerTo(); arg.ltype = arg.ltype->getPointerTo();
@ -115,6 +120,9 @@ public:
} }
Type *vaListType() override { Type *vaListType() override {
if (isDarwin)
return TargetABI::vaListType(); // char*
// We need to pass the actual va_list type for correct mangling. Simply // We need to pass the actual va_list type for correct mangling. Simply
// using TypeIdentifier here is a bit wonky but works, as long as the name // 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 // is actually available in the scope (this is what DMD does, so if a better

View file

@ -124,7 +124,7 @@ RegistryStyle getModuleRegistryStyle() {
return RegistryStyle::sectionMSVC; return RegistryStyle::sectionMSVC;
} }
if (t->isMacOSX()) { if (t->isOSDarwin()) {
return RegistryStyle::sectionDarwin; return RegistryStyle::sectionDarwin;
} }

View file

@ -48,6 +48,10 @@ unsigned getCriticalSectionSize(const Param &params) {
// POSIX: sizeof(pthread_mutex_t) // POSIX: sizeof(pthread_mutex_t)
// based on druntime/src/core/sys/posix/sys/types.d // based on druntime/src/core/sys/posix/sys/types.d
const auto &triple = *params.targetTriple; const auto &triple = *params.targetTriple;
if (triple.isOSDarwin())
return is64bit ? 64 : 44;
const auto arch = triple.getArch(); const auto arch = triple.getArch();
switch (triple.getOS()) { switch (triple.getOS()) {
case llvm::Triple::Linux: case llvm::Triple::Linux:
@ -59,10 +63,6 @@ unsigned getCriticalSectionSize(const Param &params) {
return 48; return 48;
return is64bit ? 40 : 24; return is64bit ? 40 : 24;
case llvm::Triple::Darwin:
case llvm::Triple::MacOSX:
return is64bit ? 64 : 44;
case llvm::Triple::NetBSD: case llvm::Triple::NetBSD:
return is64bit ? 48 : 28; return is64bit ? 48 : 28;
@ -287,6 +287,6 @@ Expression *Target::getTargetInfo(const char *name_, const Loc &loc) {
mem.xstrdup(opts::dcomputeFilePrefix.c_str())); mem.xstrdup(opts::dcomputeFilePrefix.c_str()));
} }
#endif #endif
return nullptr; return nullptr;
} }

View file

@ -48,23 +48,27 @@ LLType *IrTypeBasic::getComplexType(llvm::LLVMContext &ctx, LLType *type) {
namespace { namespace {
llvm::Type *getReal80Type(llvm::LLVMContext &ctx) { llvm::Type *getReal80Type(llvm::LLVMContext &ctx) {
llvm::Triple::ArchType const a = global.params.targetTriple->getArch(); const auto &triple = *global.params.targetTriple;
bool const anyX86 = (a == llvm::Triple::x86) || (a == llvm::Triple::x86_64); const auto a = triple.getArch();
bool const anyAarch64 = const bool anyX86 = (a == llvm::Triple::x86) || (a == llvm::Triple::x86_64);
const bool anyAarch64 =
(a == llvm::Triple::aarch64) || (a == llvm::Triple::aarch64_be); (a == llvm::Triple::aarch64) || (a == llvm::Triple::aarch64_be);
bool const isAndroid = const bool isAndroid = triple.getEnvironment() == llvm::Triple::Android;
global.params.targetTriple->getEnvironment() == llvm::Triple::Android;
// only x86 has 80bit float - but no support with MS C Runtime! // Only x86 has 80-bit extended precision.
if (anyX86 && !global.params.targetTriple->isWindowsMSVCEnvironment() && // MSVC and Android/x86 use double precision, Android/x64 quadruple.
!isAndroid) { if (anyX86 && !triple.isWindowsMSVCEnvironment() && !isAndroid) {
return llvm::Type::getX86_FP80Ty(ctx); return llvm::Type::getX86_FP80Ty(ctx);
} }
if (anyAarch64 || (isAndroid && a == llvm::Triple::x86_64)) { // AArch64 targets except Darwin (64-bit) use 128-bit quadruple precision.
// FIXME: PowerPC, SystemZ, ...
if ((anyAarch64 && !triple.isOSDarwin()) ||
(isAndroid && a == llvm::Triple::x86_64)) {
return llvm::Type::getFP128Ty(ctx); return llvm::Type::getFP128Ty(ctx);
} }
// 64-bit double precision for all other targets.
return llvm::Type::getDoubleTy(ctx); return llvm::Type::getDoubleTy(ctx);
} }
} }