-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Adding support for ARMv7 on linux #159
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
Changes from all commits
4737e7c
779d806
06cf35a
f57d960
e63374d
24ef52e
b46d244
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -179,4 +179,5 @@ def main(): | |
|
||
|
||
if __name__ == "__main__": | ||
main() | ||
main() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,13 +51,99 @@ class ArchType: | |
spir64 = 37 | ||
kalimba = 38 | ||
shave = 39 | ||
|
||
# Do not assume that these are 1:1 mapping. This should follow | ||
# canonical naming conventions for arm, etc. architectures. | ||
# See apple/swift PR #608 | ||
@staticmethod | ||
def to_string(value): | ||
if value == ArchType.arm: | ||
return "armv7" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isn't armv7a the more common version? |
||
if value == ArchType.armeb: | ||
return "armeb" | ||
if value == ArchType.aarch64: | ||
return "aarch64" | ||
if value == ArchType.aarch64_be: | ||
return "aarch64_be" | ||
if value == ArchType.bpfel: | ||
return "bpfel" | ||
if value == ArchType.bpfeb: | ||
return "bpfeb" | ||
if value == ArchType.hexagon: | ||
return "hexagon" | ||
if value == ArchType.mips: | ||
return "mips" | ||
if value == ArchType.mipsel: | ||
return "mipsel" | ||
if value == ArchType.mips64: | ||
return "mips64" | ||
if value == ArchType.mips64el: | ||
return "mips64el" | ||
if value == ArchType.msp430: | ||
return "msp430" | ||
if value == ArchType.ppc: | ||
return "ppc" | ||
if value == ArchType.ppc64: | ||
return "ppc64" | ||
if value == ArchType.ppc64le: | ||
return "ppc64le" | ||
if value == ArchType.r600: | ||
return "r600" | ||
if value == ArchType.amdgcn: | ||
return "amdgcn" | ||
if value == ArchType.sparc: | ||
return "sparc" | ||
if value == ArchType.sparcv9: | ||
return "sparcv9" | ||
if value == ArchType.sparcel: | ||
return "sparcel" | ||
if value == ArchType.systemz: | ||
return "systemz" | ||
if value == ArchType.tce: | ||
return "tce" | ||
if value == ArchType.thumb: | ||
return "armv7" | ||
if value == ArchType.thumbeb: | ||
return "thumbeb" | ||
if value == ArchType.x86: | ||
return "i386" | ||
if value == ArchType.x86_64: | ||
return "x86_64" | ||
if value == ArchType.xcore: | ||
return "xcore" | ||
if value == ArchType.nvptx: | ||
return "nvptx" | ||
if value == ArchType.nvptx64: | ||
return "nvptx64" | ||
if value == ArchType.le32: | ||
return "le32" | ||
if value == ArchType.le64: | ||
return "le64" | ||
if value == ArchType.amdil: | ||
return "amdil" | ||
if value == ArchType.amdil64: | ||
return "amdil64" | ||
if value == ArchType.hsail: | ||
return "hsail" | ||
if value == ArchType.hsail64: | ||
return "hsail64" | ||
if value == ArchType.spir: | ||
return "spir" | ||
if value == ArchType.spir64: | ||
return "spir64" | ||
if value == ArchType.kalimba: | ||
return "kalimba" | ||
if value == ArchType.shave: | ||
return "shave" | ||
return "unknown" | ||
# Not 1:1, See to_string | ||
@staticmethod | ||
def from_string(string): | ||
if string == "arm": | ||
return ArchType.arm | ||
# Match big endian arm first | ||
if string == "armeb": | ||
return ArchType.armeb | ||
# Catch-all for little endian arm | ||
if "arm" in string: | ||
return ArchType.arm | ||
if string == "aarch64": | ||
return ArchType.aarch64 | ||
if string == "aarch64_be": | ||
|
@@ -223,8 +309,8 @@ class Vendor: | |
|
||
class Target: | ||
triple = None | ||
sdk = OSType.MacOSX | ||
arch = ArchType.x86_64 | ||
sdk = None | ||
arch = None | ||
executable_suffix = "" | ||
dynamic_library_prefix = "lib" | ||
dynamic_library_suffix = ".dylib" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these are now incorrect if the sdk and arch are defaulted to unknown There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I added the appropriate logic to compensate below. The only issue I have with setting default values is that it increased the time it took to identify the logic bug that "ArchType.from_string(comps[0])" wasn't actually assigning anything, it was essentially a no-op. The default value made it look like everything was fine, just wrong. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fair point; I agree having an opinion about a "default" target is probably incorrect in a general sense. Just was thinking that perhaps it might be good to have these as None or some other thing to avoid any potential other trip-ups There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good call. I'll do that. |
||
|
@@ -242,20 +328,30 @@ def __init__(self, triple): | |
self.sdk = OSType.Win32 | ||
self.dynamic_library_suffix = ".dll" | ||
self.executable_suffix = ".exe" | ||
elif "darwin" in triple: | ||
self.sdk = OSType.MacOSX | ||
else: | ||
print("Unknown platform") | ||
|
||
self.triple = triple | ||
|
||
comps = triple.split('-') | ||
ArchType.from_string(comps[0]) | ||
self.arch = ArchType.from_string(comps[0]) | ||
|
||
@staticmethod | ||
def default(): | ||
triple = platform.machine() + "-" | ||
arch = ArchType.from_string(platform.machine()) | ||
triple = ArchType.to_string(arch) | ||
if platform.system() == "Linux": | ||
triple += "linux-gnu" | ||
if arch == ArchType.arm: | ||
triple += "-linux-gnueabihf" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what about "-linux-armeabi" or "-linux-android" etc? I know these are other handled cases in llvm's triple calculations There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I don't know the best way to handle that. Do you know a good way to detect what that part of the triple should be? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See http://clang.llvm.org/docs/CrossCompilation.html arch = x86, arm, thumb, mips, etc. So we probably need another field since triples are not three parts and instead five parts with three reasonably optional fields. However this method is the script's host not the target. So I am not certain which hosts we want to really support here. |
||
else: | ||
triple += "-linux-gnu" | ||
elif platform.system() == "Darwin": | ||
triple += "apple-darwin" | ||
triple += "-apple-darwin" | ||
elif platform.system() == "FreeBSD": | ||
# Make this working on 10 as well. | ||
triple += "freebsd11.0" | ||
# Make this work on 10 as well. | ||
triple += "-freebsd11.0" | ||
else: | ||
# TODO: This should be a bit more exhaustive | ||
print("unknown host os") | ||
|
@@ -264,21 +360,17 @@ def default(): | |
|
||
@property | ||
def swift_triple(self): | ||
triple = "" | ||
if self.arch == ArchType.x86_64: | ||
triple = "x86_64" | ||
else: | ||
print("unknown arch for swift") | ||
return None | ||
triple = ArchType.to_string(self.arch) | ||
if self.sdk == OSType.MacOSX: | ||
return None | ||
elif self.sdk == OSType.Linux: | ||
triple += "-pc-linux" | ||
triple += "-unknown-linux" | ||
elif self.sdk == OSType.FreeBSD: | ||
triple += "-unknown-freebsd" | ||
else: | ||
print("unknown sdk for swift") | ||
return None | ||
|
||
return triple | ||
|
||
@property | ||
|
@@ -296,13 +388,7 @@ def swift_sdk_name(self): | |
|
||
@property | ||
def swift_arch(self): | ||
arch = "" | ||
if self.arch == ArchType.x86_64: | ||
arch = "x86_64" | ||
else: | ||
print("unknown arch for swift") | ||
return None | ||
return arch | ||
return ArchType.to_string(self.arch) | ||
|
||
class TargetConditional: | ||
_sdk = None | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't the declaration of strlen
size_t strlen(const char *s)
which size_t should be unsigned in any reasonable environment typedefed by
__SIZE_TYPE__
hopefully orunsigned long
if that isn't the caseWhich os defines it as
int strlen(const char *s)
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In swift/stdlib/public/SwiftShims/LibcShims.h swift_ssize_t is defined
and later in swift/stdlib/public/stubs/LibcShims.cpp it is checked with a static assert to ensure that swift_ssize_t matches whatever the C ssize_t is. Because of this, the size of ssize_t cannot be assumed to be a long int.
I definitely don't think that this commit is the right way to do it. This is another case of trying to get it to finish building to check linking. I can revert this to what's existing for the purposes of this pull request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nah; if that is the current definition then lets roll with it and just submit a bug report on bugs.swift.org with perhaps a comment in the top of this file to explain why that is the case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done: https://bugs.swift.org/browse/SR-314
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently this is intended behavior. Jordan Rose closed the bug report.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strlen()
is returningsize_t
, notssize_t
(note the double s). I think this issue is worth further investigation.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although it's true that
size_t
(andswift_size_t
) is distinct fromswift_ssize_t
it still changes size based upon the underlying architecture. It is ultimately typedef'd from__SIZE_TYPE__
which, although I couldn't find its actual definition, is 8 bytes on x86_64 (linux or mac) and 4 bytes on 32-bit arm.I still don't think this is the best solution in this particular instance. The error we're addressing here is:
error: cannot convert value of type 'UInt32' to expected argument type 'UInt'
So, it is my expectation that we're promoting a 32-bit unsigned int to a 64-bit unsigned int, or simply removing the bit-size specialization, with it remaining 32-bits. Either way, it's safe in the 32-bit case. In 64-bit code, this should be a no-op, because it's a cast from UInt to UInt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
size_t
is supposed to be imported asInt
in Swift, the importer has a special case for it. Would you mind checking if there is an issue with that on Linux/armv7?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, It is.
At some pint strlen's return value becomes Uint32.