Skip to content

Commit

Permalink
Add aarch64 support for macOS/darwin targets (#10348)
Browse files Browse the repository at this point in the history
* libc: add aarch64-darwin target

* Interpret arm64 target triple for Apple Silicon properly

* Fix failing spec for Number#cis on Apple M1

Seems to return slightly higher precision on this platform

* aarch64-darwin: make VaList a Char* as per Apple documentation

https://developer.apple.com/documentation/xcode/writing_arm64_code_for_apple_platforms

Co-authored-by: Romain Franceschini <franceschini.romain@gmail.com>
  • Loading branch information
maxfierke and RomainFranceschini committed Feb 12, 2021
1 parent 4204ebf commit 8ae10e8
Show file tree
Hide file tree
Showing 38 changed files with 972 additions and 2 deletions.
1 change: 1 addition & 0 deletions spec/compiler/codegen/target_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ describe Crystal::Codegen::Target do
it "normalizes triples" do
Target.new("i686-unknown-linux-gnu").to_s.should eq("i386-unknown-linux-gnu")
Target.new("amd64-unknown-openbsd").to_s.should eq("x86_64-unknown-openbsd")
Target.new("arm64-apple-darwin20.2.0").to_s.should eq("aarch64-apple-darwin20.2.0")
end

it "parses freebsd version" do
Expand Down
6 changes: 5 additions & 1 deletion spec/std/complex_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,11 @@ describe "Complex" do
end

it "cis" do
2.4.cis.should eq(Complex.new(-0.7373937155412454, 0.675463180551151))
{% if flag?(:aarch64) && flag?(:darwin) %}
2.4.cis.should eq(Complex.new(-0.7373937155412454, 0.6754631805511511))
{% else %}
2.4.cis.should eq(Complex.new(-0.7373937155412454, 0.675463180551151))
{% end %}
end

it "conj" do
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/crystal/codegen/target.cr
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class Crystal::Codegen::Target
@architecture = "i386"
when "amd64"
@architecture = "x86_64"
when "arm64"
@architecture = "aarch64"
when .starts_with?("arm")
@architecture = "arm"
else
Expand Down
9 changes: 9 additions & 0 deletions src/lib_c/aarch64-darwin/c/arpa/inet.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
require "../netinet/in"
require "../stdint"

lib LibC
fun htons(x0 : UShort) : UShort
fun ntohs(x0 : UShort) : UShort
fun inet_ntop(x0 : Int, x1 : Void*, x2 : Char*, x3 : SocklenT) : Char*
fun inet_pton(x0 : Int, x1 : Char*, x2 : Void*) : Int
end
23 changes: 23 additions & 0 deletions src/lib_c/aarch64-darwin/c/dirent.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require "./sys/types"

lib LibC
type DIR = Void

DT_UNKNOWN = 0
DT_DIR = 4
DT_LINK = 10

struct Dirent
d_ino : InoT
d_seekoff : UInt64
d_reclen : UShort
d_namlen : UShort
d_type : UChar
d_name : StaticArray(Char, 256)
end

fun closedir(x0 : DIR*) : Int
fun opendir(name : Char*) : DIR*
fun readdir(dirp : DIR*) : Dirent*
fun rewinddir(x0 : DIR*) : Void
end
22 changes: 22 additions & 0 deletions src/lib_c/aarch64-darwin/c/dlfcn.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@[Link("dl")]
lib LibC
RTLD_LAZY = 0x1
RTLD_NOW = 0x2
RTLD_GLOBAL = 0x8
RTLD_LOCAL = 0x4
RTLD_DEFAULT = Pointer(Void).new(-2)
RTLD_NEXT = Pointer(Void).new(-1)

struct DlInfo
dli_fname : Char*
dli_fbase : Void*
dli_sname : Char*
dli_saddr : Void*
end

fun dlclose(handle : Void*) : Int
fun dlerror : Char*
fun dlopen(path : Char*, mode : Int) : Void*
fun dlsym(handle : Void*, symbol : Char*) : Void*
fun dladdr(x0 : Void*, x1 : DlInfo*) : Int
end
83 changes: 83 additions & 0 deletions src/lib_c/aarch64-darwin/c/errno.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
lib LibC
E2BIG = 7
EACCES = 13
EADDRINUSE = 48
EADDRNOTAVAIL = 49
EAFNOSUPPORT = 47
EAGAIN = 35
EALREADY = 37
EBADF = 9
EBADMSG = 94
EBUSY = 16
ECANCELED = 89
ECHILD = 10
ECONNABORTED = 53
ECONNREFUSED = 61
ECONNRESET = 54
EDEADLK = 11
EDESTADDRREQ = 39
EDOM = 33
EDQUOT = 69
EEXIST = 17
EFAULT = 14
EFBIG = 27
EHOSTUNREACH = 65
EIDRM = 90
EILSEQ = 92
EINPROGRESS = 36
EINTR = 4
EINVAL = 22
EIO = 5
EISCONN = 56
EISDIR = 21
ELOOP = 62
EMFILE = 24
EMLINK = 31
EMSGSIZE = 40
EMULTIHOP = 95
ENAMETOOLONG = 63
ENETDOWN = 50
ENETRESET = 52
ENETUNREACH = 51
ENFILE = 23
ENOBUFS = 55
ENODEV = 19
ENOENT = 2
ENOEXEC = 8
ENOLCK = 77
ENOLINK = 97
ENOMEM = 12
ENOMSG = 91
ENOPROTOOPT = 42
ENOSPC = 28
ENOSYS = 78
ENOTCONN = 57
ENOTDIR = 20
ENOTEMPTY = 66
ENOTRECOVERABLE = 104
ENOTSOCK = 38
ENOTSUP = 45
ENOTTY = 25
ENXIO = 6
EOPNOTSUPP = 102
EOVERFLOW = 84
EOWNERDEAD = 105
EPERM = 1
EPIPE = 32
EPROTO = 100
EPROTONOSUPPORT = 43
EPROTOTYPE = 41
ERANGE = 34
EROFS = 30
ESPIPE = 29
ESRCH = 3
ESTALE = 70
ETIMEDOUT = 60
ETXTBSY = 26
EWOULDBLOCK = LibC::EAGAIN
EXDEV = 18
ENODATA = 96
ENOSR = 98
ENOSTR = 99
ETIME = 101
end
32 changes: 32 additions & 0 deletions src/lib_c/aarch64-darwin/c/fcntl.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
require "./sys/types"
require "./sys/stat"
require "./unistd"

lib LibC
F_GETFD = 1
F_SETFD = 2
F_GETFL = 3
F_SETFL = 4
FD_CLOEXEC = 1
O_CLOEXEC = 0x1000000
O_CREAT = 0x0200
O_NOFOLLOW = 0x0100
O_TRUNC = 0x0400
O_APPEND = 0x0008
O_NONBLOCK = 0x0004
O_SYNC = 0x0080
O_RDONLY = 0x0000
O_RDWR = 0x0002
O_WRONLY = 0x0001

struct Flock
l_start : OffT
l_len : OffT
l_pid : PidT
l_type : Short
l_whence : Short
end

fun fcntl(x0 : Int, x1 : Int, ...) : Int
fun open(x0 : Char*, x1 : Int, ...) : Int
end
11 changes: 11 additions & 0 deletions src/lib_c/aarch64-darwin/c/grp.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
lib LibC
struct Group
gr_name : Char*
gr_passwd : Char*
gr_gid : GidT
gr_mem : Char**
end

fun getgrnam_r(name : Char*, grp : Group*, buf : Char*, bufsize : SizeT, result : Group**) : Int
fun getgrgid_r(gid : GidT, grp : Group*, buf : Char*, bufsize : SizeT, result : Group**) : Int
end
10 changes: 10 additions & 0 deletions src/lib_c/aarch64-darwin/c/iconv.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require "./stddef"

@[Link("iconv")]
lib LibC
type IconvT = Void*

fun iconv(x0 : IconvT, x1 : Char**, x2 : SizeT*, x3 : Char**, x4 : SizeT*) : SizeT
fun iconv_close(x0 : IconvT) : Int
fun iconv_open(x0 : Char*, x1 : Char*) : IconvT
end
9 changes: 9 additions & 0 deletions src/lib_c/aarch64-darwin/c/mach/mach_time.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
lib LibC
struct MachTimebaseInfo
numer : UInt32
denom : UInt32
end

fun mach_timebase_info(info : MachTimebaseInfo*) : LibC::Int
fun mach_absolute_time : UInt64
end
39 changes: 39 additions & 0 deletions src/lib_c/aarch64-darwin/c/netdb.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require "./netinet/in"
require "./sys/socket"
require "./stdint"

lib LibC
AI_PASSIVE = 0x00000001
AI_CANONNAME = 0x00000002
AI_NUMERICHOST = 0x00000004
AI_NUMERICSERV = 0x00001000
AI_V4MAPPED = 0x00000800
AI_ALL = 0x00000100
AI_ADDRCONFIG = 0x00000400
EAI_AGAIN = 2
EAI_BADFLAGS = 3
EAI_FAIL = 4
EAI_FAMILY = 5
EAI_MEMORY = 6
EAI_NONAME = 8
EAI_SERVICE = 9
EAI_SOCKTYPE = 10
EAI_SYSTEM = 11
EAI_OVERFLOW = 14

struct Addrinfo
ai_flags : Int
ai_family : Int
ai_socktype : Int
ai_protocol : Int
ai_addrlen : SocklenT
ai_canonname : Char*
ai_addr : Sockaddr*
ai_next : Addrinfo*
end

fun freeaddrinfo(x0 : Addrinfo*) : Void
fun gai_strerror(x0 : Int) : Char*
fun getaddrinfo(x0 : Char*, x1 : Char*, x2 : Addrinfo*, x3 : Addrinfo**) : Int
fun getnameinfo(x0 : Sockaddr*, x1 : SocklenT, x2 : Char*, x3 : SocklenT, x4 : Char*, x5 : SocklenT, x6 : Int) : Int
end
70 changes: 70 additions & 0 deletions src/lib_c/aarch64-darwin/c/netinet/in.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
require "../sys/socket"
require "../stdint"

lib LibC
IPPROTO_IP = 0
IPPROTO_IPV6 = 41
IPPROTO_ICMP = 1
IPPROTO_RAW = 255
IPPROTO_TCP = 6
IPPROTO_UDP = 17

alias InPortT = UShort
alias InAddrT = UInt

struct InAddr
s_addr : InAddrT
end

union In6AddrU6Addr
__u6_addr8 : StaticArray(SaFamilyT, 16)
__u6_addr16 : StaticArray(UShort, 8)
__u6_addr32 : StaticArray(UInt, 4)
end

struct In6Addr
__u6_addr : In6AddrU6Addr
end

struct SockaddrIn
sin_len : SaFamilyT
sin_family : SaFamilyT
sin_port : InPortT
sin_addr : InAddr
sin_zero : StaticArray(Char, 8)
end

struct SockaddrIn6
sin6_len : SaFamilyT
sin6_family : SaFamilyT
sin6_port : InPortT
sin6_flowinfo : UInt
sin6_addr : In6Addr
sin6_scope_id : UInt
end

IP_MULTICAST_IF = 9
IPV6_MULTICAST_IF = 9

IP_MULTICAST_TTL = 10
IPV6_MULTICAST_HOPS = 10

IP_MULTICAST_LOOP = 11
IPV6_MULTICAST_LOOP = 11

IP_ADD_MEMBERSHIP = 12
IPV6_JOIN_GROUP = 12

IP_DROP_MEMBERSHIP = 13
IPV6_LEAVE_GROUP = 13

struct IpMreq
imr_multiaddr : InAddr
imr_interface : InAddr
end

struct Ipv6Mreq
ipv6mr_multiaddr : In6Addr
ipv6mr_interface : UInt
end
end
6 changes: 6 additions & 0 deletions src/lib_c/aarch64-darwin/c/netinet/tcp.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
lib LibC
TCP_NODELAY = 0x01
TCP_KEEPINTVL = 0x101
TCP_KEEPCNT = 0x102
TCP_KEEPALIVE = 0x10
end
28 changes: 28 additions & 0 deletions src/lib_c/aarch64-darwin/c/pthread.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
require "./sys/types"

lib LibC
PTHREAD_MUTEX_ERRORCHECK = 1

fun pthread_condattr_destroy(x0 : PthreadCondattrT*) : Int
fun pthread_condattr_init(x0 : PthreadCondattrT*) : Int
fun pthread_cond_broadcast(x0 : PthreadCondT*) : Int
fun pthread_cond_destroy(x0 : PthreadCondT*) : Int
fun pthread_cond_init(x0 : PthreadCondT*, x1 : PthreadCondattrT*) : Int
fun pthread_cond_signal(x0 : PthreadCondT*) : Int
fun pthread_cond_timedwait_relative_np(x0 : PthreadCondT*, x1 : PthreadMutexT*, x2 : Timespec*) : Int
fun pthread_cond_wait(x0 : PthreadCondT*, x1 : PthreadMutexT*) : Int
fun pthread_create(x0 : PthreadT*, x1 : PthreadAttrT*, x2 : Void* -> Void*, x3 : Void*) : Int
fun pthread_detach(x0 : PthreadT) : Int
fun pthread_get_stackaddr_np(x0 : PthreadT) : Void*
fun pthread_get_stacksize_np(x0 : PthreadT) : SizeT
fun pthread_join(x0 : PthreadT, x1 : Void**) : Int
fun pthread_mutexattr_destroy(x0 : PthreadMutexattrT*) : Int
fun pthread_mutexattr_init(x0 : PthreadMutexattrT*) : Int
fun pthread_mutexattr_settype(x0 : PthreadMutexattrT*, x1 : Int) : Int
fun pthread_mutex_destroy(x0 : PthreadMutexT*) : Int
fun pthread_mutex_init(x0 : PthreadMutexT*, x1 : PthreadMutexattrT*) : Int
fun pthread_mutex_lock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
end

0 comments on commit 8ae10e8

Please sign in to comment.