Skip to content

Commit

Permalink
Fixes #2731: Need better way to detect 32-bit platforms (#3436)
Browse files Browse the repository at this point in the history
* Enhance TargetTriple to detect all 32 bit platforms

* Add source reference

* Add tests
  • Loading branch information
ekrich committed Aug 17, 2023
1 parent 0a6d136 commit 2ae4071
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 14 deletions.
25 changes: 11 additions & 14 deletions tools/src/main/scala/scala/scalanative/build/NativeConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -83,22 +83,19 @@ sealed trait NativeConfig {

/** Are we targeting a 32-bit platform?
*
* This should perhaps list known 32-bit architectures and search for others
* containing "32" and assume everything else is 64-bit. Printing the
* architecture for a name that is not found seems excessive perhaps?
* @return
* true if 32 bit, false if 64 bit, unknown, or 16 bit
*/
def is32BitPlatform = {
configuredOrDetectedTriple.arch match {
case "x86_64" => false
case "aarch64" => false
case "arm64" => false
case "i386" => true
case "i686" => true
case o =>
println(
s"Unexpected architecture in target triple: ${o}, defaulting to 64-bit"
)
false
import TargetTriple._
val arch = configuredOrDetectedTriple.arch
if (isArch32Bit(arch)) true
else if (isArch64Bit(arch)) false
else {
println(
s"Unexpected architecture in target triple: ${arch}, defaulting to 64-bit"
)
false
}
}

Expand Down
26 changes: 26 additions & 0 deletions tools/src/main/scala/scala/scalanative/build/TargetTriple.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// ported from LLVM 887d6ab dated 2023-04-16
// updated 2023-08-16 from https://llvm.org/doxygen/Triple_8cpp_source.html

//===--- Triple.cpp - Target triple helper class --------------------------===//
//
Expand Down Expand Up @@ -35,6 +36,11 @@ private[scalanative] object TargetTriple {
)
}

def isArch32Bit(arch: String): Boolean =
Arch.getArchPointerBitWidth(arch) == 32
def isArch64Bit(arch: String): Boolean =
Arch.getArchPointerBitWidth(arch) == 64

object Arch {
def parse(str: String): String = str match {
case "i386" | "i486" | "i586" | "i686" => x86
Expand Down Expand Up @@ -125,6 +131,26 @@ private[scalanative] object TargetTriple {
unknown
}

def getArchPointerBitWidth(arch: String): Int = {
parse(arch) match {
case `unknown` => 0
case `avr` | `msp430` => 16
case `aarch64_32` | `amdil` | `arc` | `arm` | `armeb` | `csky` |
`dxil` | `hexagon` | `hsail` | `kalimba` | `lanai` | `le32` |
`loongarch32` | `m68k` | `mips` | `mipsel` | `nvptx` | `ppc` |
`ppcle` | `r600` | `renderscript32` | `riscv32` | `shave` |
`sparc` | `sparcel` | `spir` | `spirv32` | `tce` | `tcele` |
`thumb` | `thumbeb` | `wasm32` | `x86` | `xcore` | `xtensa` =>
32
case `aarch64` | `aarch64_be` | `amdgcn` | `amdil64` | `bpfeb` |
`bpfel` | `hsail64` | `le64` | `loongarch64` | `mips64` |
`mips64el` | `nvptx64` | `ppc64` | `ppc64le` | `renderscript64` |
`riscv64` | `sparcv9` | `spir64` | `spirv64` | `systemz` | `ve` |
`wasm64` | `x86_64` =>
64
}
}

private def parseArm(str: String): String = {

val isa =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,87 @@ class TargetTripleTest {
TargetTriple("x86_64", "unknown", "freebsd", "unknown")
)

// samples based on parsed to type
val cases32Bit = List(
"aarch64_32",
"amdil",
"arc",
"arm",
"armeb",
"csky",
"dxil",
"hexagon",
"hsail",
"kalimba",
"lanai",
"le32",
"loongarch32",
"m68k",
"mips",
"mipsel",
"nvptx",
"ppc",
"ppcle",
"r600",
"renderscript32",
"riscv32",
"shave",
"sparc",
"sparcel",
"spir",
"spirv32",
"tce",
"tcele",
"thumb",
"thumbeb",
"wasm32",
"i386", // parsed to x86
"xcore",
"xtensa"
)

// samples based on parsed to type
val cases64Bit = List(
"aarch64",
"aarch64_be",
"amdgcn",
"amdil64",
"bpfeb",
"bpfel",
"hsail64",
"le64",
"loongarch64",
"mips64",
"mips64el",
"nvptx64",
"ppc64",
"ppc64le",
"renderscript64",
"riscv64",
"sparcv9",
"spir64",
"spirv64",
"systemz",
"ve",
"wasm64",
"x86_64"
)

@Test
def testParser(): Unit = cases.foreach {
case (triple, expected) =>
assertEquals(triple, expected, TargetTriple.parse(triple))
}

@Test
def isArch32Bit(): Unit = cases32Bit.foreach {
case arch =>
assertEquals(arch, true, TargetTriple.isArch32Bit(arch))
}

@Test
def isArch64Bit(): Unit = cases64Bit.foreach {
case arch =>
assertEquals(arch, true, TargetTriple.isArch64Bit(arch))
}
}

0 comments on commit 2ae4071

Please sign in to comment.