[watchOS] Add support of watch_arm64 target. (#3404)

* [watchOS] Add support of watch_arm64 target.
Since there is no support of `arm64_32` in LLVM 8
we compile bitcode that was generated for `watchos_arm32` to `arm64_32-apple-watchos`.
This commit is contained in:
Sergey Bogolepov
2019-10-01 19:03:45 +03:00
committed by GitHub
parent cf64202c18
commit 592f31a969
8 changed files with 61 additions and 13 deletions
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.native.interop.gen.wasm.processIdlLib
import org.jetbrains.kotlin.native.interop.indexer.*
import org.jetbrains.kotlin.native.interop.tool.*
import kotlinx.cli.ArgParser
import org.jetbrains.kotlin.konan.target.KonanTarget
import java.io.File
import java.lang.IllegalArgumentException
import java.nio.file.*
@@ -219,6 +220,13 @@ private fun processCLib(args: Array<String>, additionalArgs: Map<String, Any> =
val (nativeIndex, compilation) = buildNativeIndex(library, verbose)
// Our current approach to arm64_32 support is to compile armv7k version of bitcode
// for arm64_32. That's the reason for this substitution.
// TODO: Add proper support with the next LLVM update.
val target = when (tool.target) {
KonanTarget.WATCHOS_ARM64 -> KonanTarget.WATCHOS_ARM32
else -> tool.target
}
val configuration = InteropConfiguration(
library = compilation,
pkgName = outKtPkg,
@@ -229,7 +237,7 @@ private fun processCLib(args: Array<String>, additionalArgs: Map<String, Any> =
noStringConversion = def.config.noStringConversion.toSet(),
exportForwardDeclarations = def.config.exportForwardDeclarations,
disableDesignatedInitializerChecks = def.config.disableDesignatedInitializerChecks,
target = tool.target
target = target
)
outKtFile.parentFile.mkdirs()
@@ -103,9 +103,18 @@ internal class BitcodeCompiler(val context: Context) {
val profilingFlags = llvmProfilingFlags().map { listOf("-mllvm", it) }.flatten()
// LLVM we use does not have support for arm64_32.
// TODO: fix with LLVM update.
val targetTriple = when (context.config.target) {
KonanTarget.WATCHOS_ARM64 -> {
require(configurables is AppleConfigurables)
"arm64_32-apple-watchos${configurables.osVersionMin}"
}
else -> context.llvm.targetTriple
}
val flags = mutableListOf<String>().apply {
addNonEmpty(configurables.clangFlags)
addNonEmpty(listOf("-triple", context.llvm.targetTriple))
addNonEmpty(listOf("-triple", targetTriple))
addNonEmpty(when {
optimize -> configurables.clangOptFlags
debug -> configurables.clangDebugFlags
@@ -41,8 +41,8 @@ private class LlvmPipelineConfiguration(context: Context) {
val targetTriple: String = context.llvm.targetTriple
// Most of these values are copied from corresponding runtime.bc
// Which is using "generic" target CPU for many case.
// Some of these values are copied from corresponding runtime.bc
// which is using "generic" target CPU for many case.
// This approach is suboptimal because target-cpu="generic" limits
// the set of used cpu features.
// TODO: refactor KonanTarget so that we can explicitly specify
@@ -55,6 +55,7 @@ private class LlvmPipelineConfiguration(context: Context) {
KonanTarget.TVOS_X64 -> "core2"
KonanTarget.WATCHOS_X86 -> "i386"
KonanTarget.WATCHOS_X64 -> "core2"
KonanTarget.WATCHOS_ARM64,
KonanTarget.WATCHOS_ARM32 -> "cortex-a7"
KonanTarget.LINUX_X64 -> "x86-64"
KonanTarget.MINGW_X86 -> "pentium4"
@@ -68,7 +69,6 @@ private class LlvmPipelineConfiguration(context: Context) {
KonanTarget.ANDROID_X86 -> "i686"
KonanTarget.LINUX_MIPS32 -> "mips32r2"
KonanTarget.LINUX_MIPSEL32 -> "mips32r2"
KonanTarget.WATCHOS_ARM64,
KonanTarget.WASM32,
is KonanTarget.ZEPHYR -> error("There is no support for ${target.name} target yet.")
}
@@ -188,7 +188,7 @@ internal class BlockAdapterToFunctionGenerator(val objCExportCodeGenerator: ObjC
}
fun org.jetbrains.kotlin.backend.konan.Context.LongInt(value: Long) =
if (is64Bit()) Int64(value) else Int32(value.toInt())
if (is64BitNSInteger()) Int64(value) else Int32(value.toInt())
private fun generateDescriptorForBlockAdapterToFunction(bridge: BlockPointerBridge): ConstValue {
val numberOfParameters = bridge.numberOfParameters
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.ir.util.isInterface
import org.jetbrains.kotlin.ir.util.isReal
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.konan.target.Family
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.name.Name
internal fun TypeBridge.makeNothing() = when (this) {
@@ -679,7 +680,7 @@ private fun ObjCExportCodeGenerator.generateObjCImp(
MethodBridge.ReturnValue.Void -> null
MethodBridge.ReturnValue.HashCode -> {
val kotlinHashCode = targetResult!!
if (codegen.context.is64Bit()) zext(kotlinHashCode, int64Type) else kotlinHashCode
if (codegen.context.is64BitNSInteger()) zext(kotlinHashCode, int64Type) else kotlinHashCode
}
is MethodBridge.ReturnValue.Mapped -> kotlinToObjC(targetResult!!, returnBridge.bridge)
MethodBridge.ReturnValue.WithError.Success -> Int8(1).llvm // true
@@ -781,7 +782,7 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge(
MethodBridge.ReturnValue.Void -> null
MethodBridge.ReturnValue.HashCode -> {
if (codegen.context.is64Bit()) {
if (codegen.context.is64BitNSInteger()) {
val low = trunc(targetResult, int32Type)
val high = trunc(shr(targetResult, 32, signed = false), int32Type)
xor(low, high)
@@ -1256,7 +1257,7 @@ private val MethodBridgeParameter.objCType: LLVMTypeRef get() = when (this) {
private fun MethodBridge.ReturnValue.objCType(context: Context): LLVMTypeRef {
return when (this) {
MethodBridge.ReturnValue.Void -> voidType
MethodBridge.ReturnValue.HashCode -> if (context.is64Bit()) int64Type else int32Type
MethodBridge.ReturnValue.HashCode -> if (context.is64BitNSInteger()) int64Type else int32Type
is MethodBridge.ReturnValue.Mapped -> this.bridge.objCType
MethodBridge.ReturnValue.WithError.Success -> ObjCValueType.BOOL.llvmType
@@ -1324,4 +1325,7 @@ private val TypeBridge.objCEncoding: String get() = when (this) {
is ValueTypeBridge -> this.objCValueType.encoding
}
internal fun Context.is64Bit(): Boolean = this.config.target.architecture.bitness == 64
internal fun Context.is64BitNSInteger(): Boolean = this.config.target.let {
// We work with watchos_arm64 the same as we work with watchos_arm32.
it.architecture.bitness == 64 && it != KonanTarget.WATCHOS_ARM64
}
+27
View File
@@ -235,6 +235,33 @@ osVersionMinFlagLd.watchos_arm32 = -watchos_version_min
osVersionMinFlagClang.watchos_arm32 = -mwatchos-version-min
osVersionMin.watchos_arm32 = 5.0
# watchOS arm64_32
targetToolchain.macos_x64-watchos_arm64 = target-toolchain-10-macos_x64
dependencies.macos_x64-watchos_arm64 = \
libffi-3.2.1-3-darwin-macos \
clang-llvm-apple-8.0.0-darwin-macos
target-sysroot-10-watchos_arm64.default = \
remote:internal
arch.watchos_arm64 = arm64_32
targetSysRoot.watchos_arm64 = target-sysroot-10-watchos_arm32
clangFlags.watchos_arm64 = -cc1 -emit-obj -disable-llvm-passes -x ir -mllvm -aarch64-watch-bitcode-compatibility \
-mllvm -arm-bitcode-compatibility -mllvm -fast-isel=false -mllvm -global-isel=false
clangNooptFlags.watchos_arm64 = -O1
clangOptFlags.watchos_arm64 = -O3
clangDebugFlags.watchos_arm64 = -O0
clangDynamicFlags.watchos_arm64 =
linkerKonanFlags.watchos_arm64 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 6.0
linkerOptimizationFlags.watchos_arm64 = -dead_strip
linkerNoDebugFlags.watchos_arm64 = -S
linkerDynamicFlags.watchos_arm64 = -dylib
osVersionMinFlagLd.watchos_arm64 = -watchos_version_min
osVersionMinFlagClang.watchos_arm64 = -mwatchos-version-min
osVersionMin.watchos_arm64 = 5.0
# Apple's watchOS i386 simulator.
targetToolchain.macos_x64-watchos_x86 = target-toolchain-10-macos_x64
dependencies.macos_x64-watchos_x86 = \
@@ -97,13 +97,13 @@ class ClangArgs(private val configurables: Configurables) : Configurables by con
KonanTarget.TVOS_X64 ->
listOf("-stdlib=libc++", "-isysroot", absoluteTargetSysRoot, "-mtvos-simulator-version-min=$osVersionMin")
KonanTarget.WATCHOS_ARM64,
KonanTarget.WATCHOS_ARM32 ->
listOf("-stdlib=libc++", "-arch", "armv7k", "-isysroot", absoluteTargetSysRoot, "-mwatchos-version-min=$osVersionMin")
KonanTarget.WATCHOS_X86 ->
listOf("-stdlib=libc++", "-arch", "i386", "-isysroot", absoluteTargetSysRoot, "-mwatchos-simulator-version-min=$osVersionMin")
KonanTarget.WATCHOS_ARM64 -> TODO("implement me")
KonanTarget.WATCHOS_X64 -> TODO("implement me")
KonanTarget.ANDROID_ARM32, KonanTarget.ANDROID_ARM64,
@@ -261,6 +261,7 @@ class ClangArgs(private val configurables: Configurables) : Configurables by con
"-DKONAN_CORE_SYMBOLICATION=1",
"-DKONAN_HAS_CXX11_EXCEPTION_FUNCTIONS=1")
KonanTarget.WATCHOS_ARM64,
KonanTarget.WATCHOS_ARM32 ->
listOf("-DKONAN_OBJC_INTEROP=1",
"-DKONAN_WATCHOS",
@@ -280,7 +281,6 @@ class ClangArgs(private val configurables: Configurables) : Configurables by con
"-DKONAN_CORE_SYMBOLICATION=1",
"-DKONAN_HAS_CXX11_EXCEPTION_FUNCTIONS=1")
KonanTarget.WATCHOS_ARM64 -> TODO("implement me")
KonanTarget.WATCHOS_X64 -> TODO("implement me")
KonanTarget.ANDROID_ARM32 ->
@@ -49,6 +49,6 @@ class PlatformManager(distribution: Distribution = Distribution(), experimental:
* TODO: Don't forget to delete this field and replace all its usages to `enabled`.
*/
val filteredOutEnabledButNotSupported
get() = enabled.filterNot { it == KonanTarget.WATCHOS_X64 || it == KonanTarget.WATCHOS_ARM64 }
get() = enabled.filterNot { it == KonanTarget.WATCHOS_X64 }
}