Skip to content

Improved ARM arch parsing #55

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 63 additions & 4 deletions Sources/SwiftDriver/Utilities/Triple.swift
Original file line number Diff line number Diff line change
Expand Up @@ -569,8 +569,67 @@ extension Triple {
}
}

enum Endianness {
case big, little

// Based on LLVM's ARM::parseArchEndian
init?<S: StringProtocol>(armArchName archName: S) {
if archName.starts(with: "armeb") || archName.starts(with: "thumbeb") || archName.starts(with: "aarch64_be") {
self = .big
} else if archName.starts(with: "arm") || archName.starts(with: "thumb") {
self = archName.hasSuffix("eb") ? .big : .little
} else if archName.starts(with: "aarch64") || archName.starts(with: "aarch64_32") {
self = .little
} else {
return nil
}
}
}

enum ARMISA {
case aarch64, thumb, arm

// Based on LLVM's ARM::parseArchISA
init?<S: StringProtocol>(archName: S) {
if archName.starts(with: "aarch64") || archName.starts(with: "arm64") {
self = .aarch64
} else if archName.starts(with: "thumb") {
self = .thumb
} else if archName.starts(with: "arm") {
self = .arm
} else {
return nil
}
}
}

// Parse ARM architectures not handled by `parse`. On its own, this is not
// enough to correctly parse an ARM architecture.
private static func parseARMArch<S: StringProtocol>(_ archName: S) -> Triple.Arch? {
fatalError("Unimplemented")
let ISA = ARMISA(archName: archName)
let endianness = Endianness(armArchName: archName)

var arch: Triple.Arch? = nil
switch (endianness, ISA) {
case (.little, .arm):
arch = .arm
case (.little, .thumb):
arch = .thumb
case (.little, .aarch64):
arch = .aarch64
case (.big, .arm):
arch = .armeb
case (.big, .thumb):
arch = .thumbeb
case (.big, .aarch64):
arch = .aarch64_be
default:
break
}

// FIXME: thumb architectures require additional validation. See LLVM's [parseARMArch](https://llvm.org/doxygen/Triple_8cpp.html#a721eb5bffb57cea96d7a9b45cbe302cf)

return arch
}

private static func parseBPFArch<S: StringProtocol>(_ archName: S) -> Triple.Arch? {
Expand All @@ -588,13 +647,13 @@ extension Triple {
}

/// Whether or not this architecture has 64-bit pointers
var is64Bit: Bool { pointerBitWidth == 64 }
public var is64Bit: Bool { pointerBitWidth == 64 }

/// Whether or not this architecture has 32-bit pointers
var is32Bit: Bool { pointerBitWidth == 32 }
public var is32Bit: Bool { pointerBitWidth == 32 }

/// Whether or not this architecture has 16-bit pointers
var is16Bit: Bool { pointerBitWidth == 16 }
public var is16Bit: Bool { pointerBitWidth == 16 }

/// The width in bits of pointers on this architecture.
var pointerBitWidth: Int {
Expand Down
164 changes: 84 additions & 80 deletions Tests/SwiftDriverTests/TripleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -196,17 +196,17 @@ final class TripleTests: XCTestCase {
XCTAssertEqual(T.os, Triple.OS.linux)
XCTAssertEqual(T.environment, Triple.Environment.musleabi)

// T = Triple("armv6hl-none-linux-gnueabi")
// XCTAssertEqual(T.arch, Triple.Arch.arm)
// XCTAssertEqual(T.os, Triple.OS.linux)
// XCTAssertEqual(T.vendor, nil)
// XCTAssertEqual(T.environment, Triple.Environment.gnueabi)
//
// T = Triple("armv7hl-none-linux-gnueabi")
// XCTAssertEqual(T.arch, Triple.Arch.arm)
// XCTAssertEqual(T.os, Triple.OS.linux)
// XCTAssertEqual(T.vendor, nil)
// XCTAssertEqual(T.environment, Triple.Environment.gnueabi)
T = Triple("armv6hl-none-linux-gnueabi")
XCTAssertEqual(T.arch, Triple.Arch.arm)
XCTAssertEqual(T.os, Triple.OS.linux)
XCTAssertEqual(T.vendor, nil)
XCTAssertEqual(T.environment, Triple.Environment.gnueabi)

T = Triple("armv7hl-none-linux-gnueabi")
XCTAssertEqual(T.arch, Triple.Arch.arm)
XCTAssertEqual(T.os, Triple.OS.linux)
XCTAssertEqual(T.vendor, nil)
XCTAssertEqual(T.environment, Triple.Environment.gnueabi)

T = Triple("amdil-unknown-unknown")
XCTAssertEqual(T.arch, Triple.Arch.amdil)
Expand Down Expand Up @@ -351,11 +351,11 @@ final class TripleTests: XCTestCase {
XCTAssertEqual(T.os, Triple.OS.freeBSD)
XCTAssertEqual(T.environment, nil)

// T = Triple("armv7hl-suse-linux-gnueabi")
// XCTAssertEqual(T.arch, Triple.Arch.arm)
// XCTAssertEqual(T.vendor, Triple.Vendor.suse)
// XCTAssertEqual(T.os, Triple.OS.linux)
// XCTAssertEqual(T.environment, Triple.Environment.gnueabi)
T = Triple("armv7hl-suse-linux-gnueabi")
XCTAssertEqual(T.arch, Triple.Arch.arm)
XCTAssertEqual(T.vendor, Triple.Vendor.suse)
XCTAssertEqual(T.os, Triple.OS.linux)
XCTAssertEqual(T.environment, Triple.Environment.gnueabi)

T = Triple("i586-pc-haiku")
XCTAssertEqual(T.arch, Triple.Arch.x86)
Expand Down Expand Up @@ -562,24 +562,24 @@ final class TripleTests: XCTestCase {
XCTAssertEqual(T.environment, Triple.Environment.gnu)
// XCTAssertEqual(T.subArch, Triple.SubArch.mipsSubArch_r6)

// T = Triple("arm-oe-linux-gnueabi")
// XCTAssertEqual(T.arch, Triple.Arch.arm)
// XCTAssertEqual(T.vendor, Triple.Vendor.openEmbedded)
// XCTAssertEqual(T.os, Triple.OS.linux)
// XCTAssertEqual(T.environment, Triple.Environment.gnueabi)
T = Triple("arm-oe-linux-gnueabi")
XCTAssertEqual(T.arch, Triple.Arch.arm)
XCTAssertEqual(T.vendor, Triple.Vendor.openEmbedded)
XCTAssertEqual(T.os, Triple.OS.linux)
XCTAssertEqual(T.environment, Triple.Environment.gnueabi)

T = Triple("aarch64-oe-linux")
XCTAssertEqual(T.arch, Triple.Arch.aarch64)
XCTAssertEqual(T.vendor, Triple.Vendor.openEmbedded)
XCTAssertEqual(T.os, Triple.OS.linux)
XCTAssertEqual(T.environment, nil)
// XCTAssertTrue(T.isArch64Bit())
XCTAssertEqual(T.arch?.is64Bit, true)

T = Triple("arm64_32-apple-ios")
XCTAssertEqual(T.arch, Triple.Arch.aarch64_32)
XCTAssertEqual(T.os, Triple.OS.ios)
XCTAssertEqual(T.environment, nil)
// XCTAssertTrue(T.isArch32Bit())
XCTAssertEqual(T.arch?.is32Bit, true)

T = Triple("huh")
XCTAssertEqual(T.arch, nil)
Expand Down Expand Up @@ -748,35 +748,39 @@ final class TripleTests: XCTestCase {
// "i686-pc-windows-elf")
}

// func testNormalizeARM() {
// assertNormalizesEqual("armv6-netbsd-eabi",
// "armv6-unknown-netbsd-eabi")
// assertNormalizesEqual("armv7-netbsd-eabi",
// "armv7-unknown-netbsd-eabi")
// assertNormalizesEqual("armv6eb-netbsd-eabi",
// "armv6eb-unknown-netbsd-eabi")
// assertNormalizesEqual("armv7eb-netbsd-eabi",
// "armv7eb-unknown-netbsd-eabi")
// assertNormalizesEqual("armv6-netbsd-eabihf",
// "armv6-unknown-netbsd-eabihf")
// assertNormalizesEqual("armv7-netbsd-eabihf",
// "armv7-unknown-netbsd-eabihf")
// assertNormalizesEqual("armv6eb-netbsd-eabihf",
// "armv6eb-unknown-netbsd-eabihf")
// assertNormalizesEqual("armv7eb-netbsd-eabihf",
// "armv7eb-unknown-netbsd-eabihf")
//
func testNormalizeARM() {
assertNormalizesEqual("armv6-netbsd-eabi",
"armv6-unknown-netbsd-eabi")
assertNormalizesEqual("armv7-netbsd-eabi",
"armv7-unknown-netbsd-eabi")
assertNormalizesEqual("armv6eb-netbsd-eabi",
"armv6eb-unknown-netbsd-eabi")
assertNormalizesEqual("armv7eb-netbsd-eabi",
"armv7eb-unknown-netbsd-eabi")
assertNormalizesEqual("armv6-netbsd-eabihf",
"armv6-unknown-netbsd-eabihf")
assertNormalizesEqual("armv7-netbsd-eabihf",
"armv7-unknown-netbsd-eabihf")
assertNormalizesEqual("armv6eb-netbsd-eabihf",
"armv6eb-unknown-netbsd-eabihf")
assertNormalizesEqual("armv7eb-netbsd-eabihf",
"armv7eb-unknown-netbsd-eabihf")

// assertNormalizesEqual("armv7-suse-linux-gnueabi",
// "armv7-suse-linux-gnueabihf")
//
// var T: Triple
// T = Triple("armv6--netbsd-eabi")
// XCTAssertEqual(.arm, T.arch)
// T = Triple("armv6eb--netbsd-eabi")
// XCTAssertEqual(.armeb, T.arch)
// T = Triple("armv7-suse-linux-gnueabihf")
// XCTAssertEqual(.gnueabihf, T.environment)
// }

var T: Triple
T = Triple("armv6--netbsd-eabi")
XCTAssertEqual(.arm, T.arch)
T = Triple("armv6eb--netbsd-eabi")
XCTAssertEqual(.armeb, T.arch)
T = Triple("arm64--netbsd-eabi")
XCTAssertEqual(.aarch64, T.arch)
T = Triple("aarch64_be--netbsd-eabi")
XCTAssertEqual(.aarch64_be, T.arch)
T = Triple("armv7-suse-linux-gnueabihf")
XCTAssertEqual(.gnueabihf, T.environment)
}

func testOSVersion() {
var T: Triple
Expand Down Expand Up @@ -842,36 +846,36 @@ final class TripleTests: XCTestCase {
XCTAssertEqual(V?.minor, 0)
XCTAssertEqual(V?.micro, 0)

// T = Triple("armv7-apple-ios")
// XCTAssertFalse(T.os?.isMacOSX)
// XCTAssertTrue(T.os?.isiOS)
//// XCTAssertFalse(T.isArch16Bit())
//// XCTAssertTrue(T.isArch32Bit())
//// XCTAssertFalse(T.isArch64Bit())
// V = T.macOSXVersion
// XCTAssertEqual(V?.major, 10)
// XCTAssertEqual(V?.minor, 4)
// XCTAssertEqual(V?.micro, 0)
// V = T.iOSVersion
// XCTAssertEqual(V?.major, 5)
// XCTAssertEqual(V?.minor, 0)
// XCTAssertEqual(V?.micro, 0)
//
// T = Triple("armv7-apple-ios7.0")
// XCTAssertFalse(T.os?.isMacOSX)
// XCTAssertTrue(T.os?.isiOS)
//// XCTAssertFalse(T.isArch16Bit())
//// XCTAssertTrue(T.isArch32Bit())
//// XCTAssertFalse(T.isArch64Bit())
// V = T.macOSXVersion
// XCTAssertEqual(V?.major, 10)
// XCTAssertEqual(V?.minor, 4)
// XCTAssertEqual(V?.micro, 0)
// V = T.iOSVersion
// XCTAssertEqual(V?.major, 7)
// XCTAssertEqual(V?.minor, 0)
// XCTAssertEqual(V?.micro, 0)
// XCTAssertFalse(T._isSimulatorEnvironment)
T = Triple("armv7-apple-ios")
XCTAssertFalse(T.os?.isMacOSX)
XCTAssertTrue(T.os?.isiOS)
XCTAssertEqual(T.arch?.is16Bit, false)
XCTAssertEqual(T.arch?.is32Bit, true)
XCTAssertEqual(T.arch?.is64Bit, false)
V = T.version(for: .macOS)
XCTAssertEqual(V?.major, 10)
XCTAssertEqual(V?.minor, 4)
XCTAssertEqual(V?.micro, 0)
V = T.version(for: .iOS(.device))
XCTAssertEqual(V?.major, 5)
XCTAssertEqual(V?.minor, 0)
XCTAssertEqual(V?.micro, 0)

T = Triple("armv7-apple-ios7.0")
XCTAssertFalse(T.os?.isMacOSX)
XCTAssertTrue(T.os?.isiOS)
XCTAssertEqual(T.arch?.is16Bit, false)
XCTAssertEqual(T.arch?.is32Bit, true)
XCTAssertEqual(T.arch?.is64Bit, false)
V = T.version(for: .macOS)
XCTAssertEqual(V?.major, 10)
XCTAssertEqual(V?.minor, 4)
XCTAssertEqual(V?.micro, 0)
V = T.version(for: .iOS(.device))
XCTAssertEqual(V?.major, 7)
XCTAssertEqual(V?.minor, 0)
XCTAssertEqual(V?.micro, 0)
XCTAssertFalse(T._isSimulatorEnvironment)

T = Triple("x86_64-apple-ios10.3-simulator")
XCTAssertTrue(T.os?.isiOS)
Expand Down