diff --git a/.gitignore b/.gitignore index 8b0d17d..e17efac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ nlvm/nlvm nlvm/nlvmr +nlvm/*.dSYM nimcache *.s /nlvm/nlvm.self @@ -22,3 +23,4 @@ tools dist/ /megatest.nim .vscode +.DS_Store \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 46a7f95..074f912 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "Nim"] path = Nim - url = https://github.com/arnetheduck/Nim.git + url = https://github.com/gushromp/Nim.git branch = nlvm diff --git a/Makefile b/Makefile index c94093d..2d9d6d3 100644 --- a/Makefile +++ b/Makefile @@ -17,12 +17,21 @@ LLVM_PAT=0 LLVM_DIR=llvm-$(LLVM_MAJ).$(LLVM_MIN).$(LLVM_PAT).src +OS := $(shell uname) +ifeq ($(OS),Darwin) + SHALIB_EXT := dylib +else ifeq ($(OS),Linux) + SHALIB_EXT := so +else + $(error "Unsupported OS. Exiting.") +endif + ifdef STATIC_LLVM NLVMCFLAGS=-d:staticLLVM --dynliboverrideall LLVM_DEP=ext/$(LLVM_DIR)/sta/bin/llvm-config export PATH := $(PWD)/ext/$(LLVM_DIR)/sta/bin:$(PATH) else - LLVM_DEP=ext/$(LLVM_DIR)/sha/lib/libLLVM-$(LLVM_MAJ).so + LLVM_DEP=ext/$(LLVM_DIR)/sha/lib/libLLVM-$(LLVM_MAJ).$(SHALIB_EXT) NLVMCFLAGS?= endif @@ -98,7 +107,7 @@ self: nlvm/nlvm.self clean: rm -rf $(NLVMC) $(NLVMR) nlvm/nlvm.ll nlvm/nlvm.self.ll nlvm/nlvm.self Nim/testresults/ -ext/$(LLVM_DIR)/sha/lib/libLLVM-$(LLVM_MAJ).so: +ext/$(LLVM_DIR)/sha/lib/libLLVM-$(LLVM_MAJ).$(SHALIB_EXT): sh ./make-llvm.sh $(LLVM_MAJ) $(LLVM_MIN) $(LLVM_PAT) sha \ -DLLVM_BUILD_LLVM_DYLIB=1 \ -DLLVM_LINK_LLVM_DYLIB=1 \ diff --git a/Nim b/Nim index ab9af74..a07140a 160000 --- a/Nim +++ b/Nim @@ -1 +1 @@ -Subproject commit ab9af74892783e5b763902c7d12a4ae2c4ea3c8a +Subproject commit a07140a5d91634e1d3eaec7f35fb527651b59838 diff --git a/dl-llvm.sh b/dl-llvm.sh index b93ac94..6fbbf34 100755 --- a/dl-llvm.sh +++ b/dl-llvm.sh @@ -1,5 +1,26 @@ #!/bin/bash +OS="`uname`" +ARCH="`uname -m`" + +if [ $ARCH == "arm64" ]; then + echo "LLVM doesn't provide precompiled binaries for arm64 yet :(. Remove STATIC_LLVM=1 and try again. Exiting..." + exit 1 +fi + +case $OS in + 'Linux') + SUFFIX="$ARCH-linux-gnu-ubuntu-18.04" + ;; + 'Darwin') + SUFFIX="$ARCH-apple-darwin" + ;; + *) + echo "Unsupported OS: $OS" + exit 1 + ;; +esac + [ $# -ge 4 ] || { echo "$0 major minor patch output_dir" exit 1 @@ -13,7 +34,6 @@ cd ext VER="$1.$2" VER2="$VER.$3" TGT="$4" -SUFFIX="x86_64-linux-gnu-ubuntu-18.04" LLVM_ROOT=llvm-$VER2.src diff --git a/llvm/llvm.nim b/llvm/llvm.nim index d6292d7..ab9f879 100644 --- a/llvm/llvm.nim +++ b/llvm/llvm.nim @@ -3,42 +3,75 @@ # See the LICENSE file for license info (doh!) import strutils +import strformat +import os + +static: + if not (defined(linux) or defined(macosx)): + echo "Unsupported platform. Exiting." + quit(-1) const - LLVMLib = "libLLVM-14.so" - LLVMRoot = "../ext/llvm-14.0.0.src/" - LLDRoot = "../ext/lld-14.0.0.src/" + Root = currentSourcePath.parentDir().parentDir() LLVMVersion* = "14.0.0" + LLVMRoot = fmt"{Root}/ext/llvm-{LLVMVersion}.src" + LLDRoot = fmt"{Root}/ext/lld-{LLVMVersion}.src" {.passL: "-llldELF" .} {.passL: "-llldWasm" .} {.passL: "-llldMinGW" .} {.passL: "-llldCommon" .} +{.passL: "-llldMachO" .} {.passL: "-lz" .} +when defined(macosx): + {.passL: "-lxar" .} when defined(staticLLVM): const - LLVMOut = LLVMRoot & "sta/" + LLVMOut = fmt"{LLVMRoot}/sta" + + {.passL: gorge(fmt"{LLVMRoot}/sta/bin/llvm-config --libs all").} - {.passL: gorge(LLVMRoot & "sta/bin/llvm-config --libs all").} + when defined(macosx): + const SDKRoot = gorge("xcrun --sdk macosx --show-sdk-path") + {.passC: fmt"-isysroot{SDKRoot}".} + {.passL: fmt"-Wl,-syslibroot,{SDKRoot}".} else: const - LLVMOut = LLVMRoot & "sha/" + LLVMOut = fmt"{LLVMRoot}/sha" + + when defined(macosx): + {.passL: "-lLLVM".} + {.passL: fmt"-Wl,-rpath,@loader_path/../ext/llvm-{LLVMVersion}.src/sha/lib".} + + elif defined(linux): + {.passL: "-lLLVM-14".} + {.passL: fmt"-Wl,'-rpath=$ORIGIN/../ext/llvm-{LLVMVersion}.src/sha/lib'".} + - {.passL: "-lLLVM-14".} - {.passL: "-Wl,'-rpath=$ORIGIN/" & LLVMOut & "lib/'".} +{.passC: fmt"-I{LLVMRoot}/include".} +{.passC: fmt"-I{LLVMOut}/include".} -{.passC: "-I" & LLVMRoot & "include".} -{.passC: "-I" & LLVMOut & "include".} +{.passC: fmt"-I{LLDRoot}/include".} -{.passC: "-I" & LLDRoot & "include".} +when defined(linux): + {.passL: "-Wl,--as-needed".} +else: + {.passL: "-Wl".} + +{.passL: gorge(fmt"{LLVMOut}/bin/llvm-config --ldflags").} +{.passL: gorge(fmt"{LLVMOut}/bin/llvm-config --system-libs").} -{.passL: "-Wl,--as-needed".} -{.passL: gorge(LLVMOut & "bin/llvm-config --ldflags").} -{.passL: gorge(LLVMOut & "bin/llvm-config --system-libs").} +{.compile("wrapper.cc", "-std=c++14").} -{.compile: "wrapper.cc".} +when defined(linux): + const + LLVMLib = "libLLVM-14.so" +elif defined(macosx): + const + LLVMLib = "libLLVM.dylib" + LLDBinary* = fmt"{LLVMOut}/bin/ld64.lld" # Includes and helpers for generated code type @@ -264,6 +297,18 @@ proc nimLLDLinkElf*(args: openArray[string]): string = result = strip($tmp) disposeMessage(tmp) +proc nimLLDLinkMachO*( + argv: cstringArray, argc: cint): cstring {.importc: "LLVMNimLLDLinkMachO".} + +proc nimLLDLinkMachO*(args: openArray[string]): string = + let argv = allocCStringArray(args) + defer: deallocCStringArray(argv) + + let tmp = nimLLDLinkMachO(argv, args.len.cint) + if not tmp.isNil: + result = strip($tmp) + disposeMessage(tmp) + proc nimLLDLinkWasm*( argv: cstringArray, argc: cint): cstring {.importc: "LLVMNimLLDLinkWasm".} diff --git a/llvm/wrapper.cc b/llvm/wrapper.cc index a6027bb..84bf5d6 100644 --- a/llvm/wrapper.cc +++ b/llvm/wrapper.cc @@ -8,6 +8,8 @@ #include "llvm-c/Types.h" #include "llvm-c/Core.h" +#include + using namespace llvm; typedef DIBuilder *LLVMNimDIBuilderRef; @@ -49,12 +51,27 @@ extern "C" const char* LLVMNimLLDLinkElf(const char **args, size_t arg_count) { SmallVector osv, esv; raw_svector_ostream os(osv), es(esv); - if (!lld::elf::link(array_ref_args, os, es, false, false)) { + if (lld::elf::link(array_ref_args, os, es, false, false)) { osv.push_back(0); return LLVMCreateMessage(&osv[0]); + } else { + esv.push_back(0); + return LLVMCreateMessage(&esv[0]); } +} + +extern "C" const char* LLVMNimLLDLinkMachO(const char **args, size_t arg_count) { + ArrayRef array_ref_args(args, arg_count); + SmallVector osv, esv; + raw_svector_ostream os(osv), es(esv); - return nullptr; + if (lld::macho::link(array_ref_args, os, es, false, false)) { + osv.push_back(0); + return LLVMCreateMessage(&osv[0]); + } else { + esv.push_back(0); + return LLVMCreateMessage(&esv[0]); + } } extern "C" const char* LLVMNimLLDLinkWasm(const char **args, size_t arg_count) { @@ -62,10 +79,11 @@ extern "C" const char* LLVMNimLLDLinkWasm(const char **args, size_t arg_count) { SmallVector osv, esv; raw_svector_ostream os(osv), es(esv); - if (!lld::wasm::link(array_ref_args, os, es, false, false)) { + if (lld::wasm::link(array_ref_args, os, es, false, false)) { osv.push_back(0); return LLVMCreateMessage(&osv[0]); + } else { + esv.push_back(0); + return LLVMCreateMessage(&esv[0]); } - - return nullptr; } diff --git a/make-llvm.sh b/make-llvm.sh index 27fde5b..c6a9cd9 100755 --- a/make-llvm.sh +++ b/make-llvm.sh @@ -3,6 +3,20 @@ # Build llvm, as used in the Makefile # A bit broken because it doesn't track cmake options and deps correctly +OS="`uname`" +case $OS in + 'Linux') + ADDITIONAL_CMAKE_ARGS="-DLLVM_USE_LINKER=gold" + ;; + 'Darwin') + ADDITIONAL_CMAKE_ARGS="" + ;; + *) + echo "Unsupported OS: $OS" + exit 1 + ;; +esac + [ $# -gt 4 ] || { echo "$0 major minor patch output_dir cmake_options*" exit 1 @@ -39,7 +53,7 @@ LLD_ROOT=lld-$VER2.src [ -d $LLVM_ROOT/projects/lld ] || { rm -rf $LLVM_ROOT/projects/lld cd $LLVM_ROOT/projects - ln -sfr ../../$LLD_ROOT lld + ln -sf ../../$LLD_ROOT lld cd ../.. } @@ -49,7 +63,7 @@ LLD_ROOT=lld-$VER2.src [ -f libunwind-$VER2/CMakeLists.txt ] || { tar xf libunwind-$VER2.src.tar.xz - cp -ar libunwind-$VER2.src/include/mach-o $LLD_ROOT/include + cp -a libunwind-$VER2.src/include/mach-o $LLD_ROOT/include } cd $LLVM_ROOT @@ -58,6 +72,6 @@ mkdir -p $TGT cd $TGT shift 4 -cmake -GNinja -DLLVM_USE_LINKER=gold LLVM_INCLUDE_BENCHMARKS=OFF "$@" .. +cmake -GNinja "$@" .. ninja diff --git a/nlvm-lib/nlvmbase-amd64-MacOSX.ll b/nlvm-lib/nlvmbase-amd64-MacOSX.ll new file mode 100644 index 0000000..15745b6 --- /dev/null +++ b/nlvm-lib/nlvmbase-amd64-MacOSX.ll @@ -0,0 +1,708 @@ +; Workarounds for: +; * bugs in nlvm +; * nim standard library including macros from header files +; * stuff in nimbase.h +; For this to go away, one would have to patch upstream to +; avoid depending on c headers in the stdlib, and fix some bugs +; in nlvm + +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-macos" + +; ioctls.h +@FIONCLEX = linkonce_odr constant i32 21584 +@FIOCLEX = linkonce_odr constant i32 21585 + +; pthreads.h +@PTHREAD_MUTEX_RECURSIVE = linkonce_odr constant i32 1 + +; signal.h +@SIG_ERR = global void (i32)* inttoptr (i32 -1 to void (i32)*), align 8 +@SIG_DFL = global void (i32)* inttoptr (i32 0 to void (i32)*), align 8 +@SIG_IGN = global void (i32)* inttoptr (i32 1 to void (i32)*), align 8 +@SEGV_MAPERR = linkonce_odr constant i32 1 +@SIGEV_NONE = linkonce_odr constant i32 1 +@SIGEV_SIGNAL = linkonce_odr constant i32 2 +@SIGEV_THREAD = linkonce_odr constant i32 3 +@SIGABRT = linkonce_odr constant i32 6 +@SIGALRM = linkonce_odr constant i32 14 +@SIGBUS = linkonce_odr constant i32 10 +@SIGCHLD = linkonce_odr constant i32 20 +@SIGCONT = linkonce_odr constant i32 19 +@SIGFPE = linkonce_odr constant i32 8 +@SIGHUP = linkonce_odr constant i32 1 +@SIGILL = linkonce_odr constant i32 4 +@SIGINT = linkonce_odr constant i32 2 +@SIGKILL = linkonce_odr constant i32 9 +@SIGPIPE = linkonce_odr constant i32 13 +@SIGQUIT = linkonce_odr constant i32 3 +@SIGSEGV = linkonce_odr constant i32 11 +@SIGSTOP = linkonce_odr constant i32 17 +@SIGTERM = linkonce_odr constant i32 15 +@SIGTSTP = linkonce_odr constant i32 18 +@SIGTTIN = linkonce_odr constant i32 21 +@SIGTTOU = linkonce_odr constant i32 22 +@SIGUSR1 = linkonce_odr constant i32 30 +@SIGUSR2 = linkonce_odr constant i32 31 +@SIGPOLL = linkonce_odr constant i32 23 +@SIGPROF = linkonce_odr constant i32 27 +@SIGSYS = linkonce_odr constant i32 12 +@SIGTRAP = linkonce_odr constant i32 5 +@SIGURG = linkonce_odr constant i32 16 +@SIGVTALRM = linkonce_odr constant i32 26 +@SIGXCPU = linkonce_odr constant i32 24 +@SIGXFSZ = linkonce_odr constant i32 25 +@SA_NOCLDSTOP = linkonce_odr constant i32 1 +@SIG_BLOCK = linkonce_odr constant i32 1 +@SIG_UNBLOCK = linkonce_odr constant i32 2 +@SIG_SETMASK = linkonce_odr constant i32 0 +@SS_ONSTACK = linkonce_odr constant i32 1 +@SS_DISABLE = linkonce_odr constant i32 2 +@MINSIGSTKSZ = linkonce_odr constant i32 2048 +@SIGSTKSZ = linkonce_odr constant i32 8192 + +; errno.h +@EACCES = linkonce_odr constant i32 13 +@EADDRINUSE = linkonce_odr constant i32 48 +@EADDRNOTAVAIL = linkonce_odr constant i32 49 +@EAFNOSUPPORT = linkonce_odr constant i32 47 +@EAGAIN = linkonce_odr constant i32 35 +@EALREADY = linkonce_odr constant i32 37 +@EBADF = linkonce_odr constant i32 9 +@EBADMSG = linkonce_odr constant i32 94 +@EBUSY = linkonce_odr constant i32 16 +@ECANCELED = linkonce_odr constant i32 89 +@ECHILD = linkonce_odr constant i32 10 +@ECONNABORTED = linkonce_odr constant i32 53 +@ECONNREFUSED = linkonce_odr constant i32 61 +@ECONNRESET = linkonce_odr constant i32 54 +@EDEADLK = linkonce_odr constant i32 11 +@EDESTADDRREQ = linkonce_odr constant i32 39 +@EDOM = linkonce_odr constant i32 33 +@EDQUOT = linkonce_odr constant i32 69 +@EEXIST = linkonce_odr constant i32 17 +@EFAULT = linkonce_odr constant i32 14 +@EFBIG = linkonce_odr constant i32 27 +@EHOSTUNREACH = linkonce_odr constant i32 65 +@EIDRM = linkonce_odr constant i32 90 +@EILSEQ = linkonce_odr constant i32 92 +@EINPROGRESS = linkonce_odr constant i32 36 +@EINTR = linkonce_odr constant i32 4 +@EINVAL = linkonce_odr constant i32 22 +@EIO = linkonce_odr constant i32 5 +@EISCONN = linkonce_odr constant i32 56 +@EISDIR = linkonce_odr constant i32 21 +@ELOOP = linkonce_odr constant i32 62 +@EMFILE = linkonce_odr constant i32 24 +@EMLINK = linkonce_odr constant i32 31 +@EMSGSIZE = linkonce_odr constant i32 40 +@EMULTIHOP = linkonce_odr constant i32 95 +@ENAMETOOLONG = linkonce_odr constant i32 63 +@ENETDOWN = linkonce_odr constant i32 50 +@ENETRESET = linkonce_odr constant i32 52 +@ENETUNREACH = linkonce_odr constant i32 51 +@ENFILE = linkonce_odr constant i32 23 +@ENOBUFS = linkonce_odr constant i32 55 +@ENODATA = linkonce_odr constant i32 96 +@ENODEV = linkonce_odr constant i32 19 +@ENOENT = linkonce_odr constant i32 2 +@ENOEXEC = linkonce_odr constant i32 8 +@ENOLCK = linkonce_odr constant i32 77 +@ENOLINK = linkonce_odr constant i32 97 +@ENOMEM = linkonce_odr constant i32 12 +@ENOMSG = linkonce_odr constant i32 91 +@ENOPROTOOPT = linkonce_odr constant i32 42 +@ENOSPC = linkonce_odr constant i32 28 +@ENOSR = linkonce_odr constant i32 98 +@ENOSTR = linkonce_odr constant i32 99 +@ENOSYS = linkonce_odr constant i32 78 +@ENOTCONN = linkonce_odr constant i32 57 +@ENOTDIR = linkonce_odr constant i32 20 +@ENOTEMPTY = linkonce_odr constant i32 66 +@ENOTSOCK = linkonce_odr constant i32 38 +@ENOTSUP = linkonce_odr constant i32 45 +@ENOTTY = linkonce_odr constant i32 25 +@ENXIO = linkonce_odr constant i32 6 +@EOPNOTSUPP = linkonce_odr constant i32 102 +@EOVERFLOW = linkonce_odr constant i32 84 +@EPERM = linkonce_odr constant i32 1 +@EPIPE = linkonce_odr constant i32 32 +@EPROTO = linkonce_odr constant i32 100 +@EPROTONOSUPPORT = linkonce_odr constant i32 43 +@EPROTOTYPE = linkonce_odr constant i32 41 +@ERANGE = linkonce_odr constant i32 34 +@EROFS = linkonce_odr constant i32 30 +@ESPIPE = linkonce_odr constant i32 29 +@ESRCH = linkonce_odr constant i32 3 +@ESTALE = linkonce_odr constant i32 70 +@ETIME = linkonce_odr constant i32 101 +@ETIMEDOUT = linkonce_odr constant i32 60 +@ETXTBSY = linkonce_odr constant i32 26 +@EWOULDBLOCK = linkonce_odr constant i32 35 +@EXDEV = linkonce_odr constant i32 18 + +; spawn.h +@POSIX_SPAWN_RESETIDS = linkonce_odr constant i32 1 +@POSIX_SPAWN_SETPGROUP = linkonce_odr constant i32 2 +@POSIX_SPAWN_SETSCHEDPARAM = linkonce_odr constant i32 16 +@POSIX_SPAWN_SETSCHEDULER = linkonce_odr constant i32 32 +@POSIX_SPAWN_SETSIGDEF = linkonce_odr constant i32 4 +@POSIX_SPAWN_SETSIGMASK = linkonce_odr constant i32 8 +@POSIX_SPAWN_USEVFORK = linkonce_odr constant i32 64 + +; sys/stat.h +@S_IFBLK = linkonce_odr constant i32 24576 +@S_IFCHR = linkonce_odr constant i32 8192 +@S_IFDIR = linkonce_odr constant i32 16384 +@S_IFIFO = linkonce_odr constant i32 4096 +@S_IFLNK = linkonce_odr constant i32 40960 +@S_IFMT = linkonce_odr constant i32 61440 +@S_IFREG = linkonce_odr constant i32 32768 +@S_IFSOCK = linkonce_odr constant i32 49152 +@S_IRGRP = linkonce_odr constant i32 32 +@S_IROTH = linkonce_odr constant i32 4 +@S_IRUSR = linkonce_odr constant i32 256 +@S_IRWXG = linkonce_odr constant i32 56 +@S_IRWXO = linkonce_odr constant i32 7 +@S_IRWXU = linkonce_odr constant i32 448 +@S_ISGID = linkonce_odr constant i32 1024 +@S_ISUID = linkonce_odr constant i32 2048 +@S_ISVTX = linkonce_odr constant i32 512 +@S_IWGRP = linkonce_odr constant i32 16 +@S_IWOTH = linkonce_odr constant i32 2 +@S_IWUSR = linkonce_odr constant i32 128 +@S_IXGRP = linkonce_odr constant i32 8 +@S_IXOTH = linkonce_odr constant i32 1 +@S_IXUSR = linkonce_odr constant i32 64 + +; stdio.h +@_IOFBF = linkonce_odr constant i32 0 +@_IOLBF = linkonce_odr constant i32 1 +@_IONBF = linkonce_odr constant i32 2 +@L_ctermid = linkonce_odr constant i32 9 + +; syscall.h +@SYS_getrandom = linkonce_odr constant i32 318 + +; sys/ioctl.h +@TIOCGWINSZ = linkonce_odr constant i32 21523 + +; time.h +@CLOCK_REALTIME = linkonce_odr constant i32 0 +@CLOCKS_PER_SEC = linkonce_odr constant i64 1000000 + +; termios.h +@VINTR = linkonce_odr constant i32 0 +@VQUIT = linkonce_odr constant i32 1 +@VERASE = linkonce_odr constant i32 2 +@VKILL = linkonce_odr constant i32 3 +@VEOF = linkonce_odr constant i32 4 +@VTIME = linkonce_odr constant i32 5 +@VMIN = linkonce_odr constant i32 6 +@VSTART = linkonce_odr constant i32 8 +@VSTOP = linkonce_odr constant i32 9 +@VSUSP = linkonce_odr constant i32 10 +@VEOL = linkonce_odr constant i32 11 +@IGNBRK = linkonce_odr constant i32 1 +@BRKINT = linkonce_odr constant i32 2 +@IGNPAR = linkonce_odr constant i32 4 +@PARMRK = linkonce_odr constant i32 8 +@INPCK = linkonce_odr constant i32 16 +@ISTRIP = linkonce_odr constant i32 32 +@INLCR = linkonce_odr constant i32 64 +@IGNCR = linkonce_odr constant i32 128 +@ICRNL = linkonce_odr constant i32 256 +@IUCLC = linkonce_odr constant i32 512 +@IXON = linkonce_odr constant i32 1024 +@IXANY = linkonce_odr constant i32 2048 +@IXOFF = linkonce_odr constant i32 4096 +@OPOST = linkonce_odr constant i32 1 +@ONLCR = linkonce_odr constant i32 4 +@OCRNL = linkonce_odr constant i32 8 +@ONOCR = linkonce_odr constant i32 16 +@ONLRET = linkonce_odr constant i32 32 +@OFILL = linkonce_odr constant i32 64 +@OFDEL = linkonce_odr constant i32 128 +@NLDLY = linkonce_odr constant i32 256 +@NL0 = linkonce_odr constant i32 0 +@NL1 = linkonce_odr constant i32 256 +@CRDLY = linkonce_odr constant i32 1536 +@CR0 = linkonce_odr constant i32 0 +@CR1 = linkonce_odr constant i32 512 +@CR2 = linkonce_odr constant i32 1024 +@CR3 = linkonce_odr constant i32 1536 +@TABDLY = linkonce_odr constant i32 6144 +@TAB0 = linkonce_odr constant i32 0 +@TAB1 = linkonce_odr constant i32 2048 +@TAB2 = linkonce_odr constant i32 4096 +@TAB3 = linkonce_odr constant i32 6144 +@BSDLY = linkonce_odr constant i32 8192 +@BS0 = linkonce_odr constant i32 0 +@BS1 = linkonce_odr constant i32 8192 +@FFDLY = linkonce_odr constant i32 32768 +@FF0 = linkonce_odr constant i32 0 +@FF1 = linkonce_odr constant i32 32768 +@VTDLY = linkonce_odr constant i32 16384 +@VT0 = linkonce_odr constant i32 0 +@VT1 = linkonce_odr constant i32 16384 +@B0 = linkonce_odr constant i32 0 +@B50 = linkonce_odr constant i32 1 +@B75 = linkonce_odr constant i32 2 +@B110 = linkonce_odr constant i32 3 +@B134 = linkonce_odr constant i32 4 +@B150 = linkonce_odr constant i32 5 +@B200 = linkonce_odr constant i32 6 +@B300 = linkonce_odr constant i32 7 +@B600 = linkonce_odr constant i32 8 +@B1200 = linkonce_odr constant i32 9 +@B1800 = linkonce_odr constant i32 10 +@B2400 = linkonce_odr constant i32 11 +@B4800 = linkonce_odr constant i32 12 +@B9600 = linkonce_odr constant i32 13 +@B19200 = linkonce_odr constant i32 14 +@B38400 = linkonce_odr constant i32 15 +@EXTA = linkonce_odr constant i32 14 +@EXTB = linkonce_odr constant i32 15 +@CSIZE = linkonce_odr constant i32 48 +@CS5 = linkonce_odr constant i32 0 +@CS6 = linkonce_odr constant i32 16 +@CS7 = linkonce_odr constant i32 32 +@CS8 = linkonce_odr constant i32 48 +@CSTOPB = linkonce_odr constant i32 64 +@CREAD = linkonce_odr constant i32 128 +@PARENB = linkonce_odr constant i32 256 +@PARODD = linkonce_odr constant i32 512 +@HUPCL = linkonce_odr constant i32 1024 +@CLOCAL = linkonce_odr constant i32 2048 +@ISIG = linkonce_odr constant i32 1 +@ICANON = linkonce_odr constant i32 2 +@ECHO = linkonce_odr constant i32 8 +@ECHOE = linkonce_odr constant i32 16 +@ECHOK = linkonce_odr constant i32 32 +@ECHONL = linkonce_odr constant i32 64 +@NOFLSH = linkonce_odr constant i32 128 +@TOSTOP = linkonce_odr constant i32 256 +@IEXTEN = linkonce_odr constant i32 32768 +@TCOOFF = linkonce_odr constant i32 0 +@TCOON = linkonce_odr constant i32 1 +@TCIOFF = linkonce_odr constant i32 2 +@TCION = linkonce_odr constant i32 3 +@TCIFLUSH = linkonce_odr constant i32 0 +@TCOFLUSH = linkonce_odr constant i32 1 +@TCIOFLUSH = linkonce_odr constant i32 2 +@TCSANOW = linkonce_odr constant i32 0 +@TCSADRAIN = linkonce_odr constant i32 1 +@TCSAFLUSH = linkonce_odr constant i32 2 + +; fcntl.h +@F_GETFD = linkonce_odr constant i32 1 +@F_SETFD = linkonce_odr constant i32 2 +@FD_CLOEXEC = linkonce_odr constant i32 1 + +; sys/wait.h +@WNOHANG = linkonce_odr constant i32 1 +@WUNTRACED = linkonce_odr constant i32 2 +@WEXITED = linkonce_odr constant i32 4 +@WSTOPPED = linkonce_odr constant i32 2 +@WCONTINUED = linkonce_odr constant i32 8 +@WNOWAIT = linkonce_odr constant i32 16777216 + +; copyfile.h +@COPYFILE_ACL = linkonce_odr constant i32 1 +@COPYFILE_STAT = linkonce_odr constant i32 2 +@COPYFILE_XATTR = linkonce_odr constant i32 4 +@COPYFILE_DATA = linkonce_odr constant i32 8 + +; sys/wait.h +; proc WEXITSTATUS*(s: cint): cint = (s and 0xff00) shr 8 +; proc WTERMSIG*(s:cint): cint = s and 0x7f +; proc WSTOPSIG*(s:cint): cint = WEXITSTATUS(s) +; proc WIFEXITED*(s:cint) : bool = WTERMSIG(s) == 0 +; proc WIFSIGNALED*(s:cint) : bool = (cast[int8]((s and 0x7f) + 1) shr 1) > 0 +; proc WIFSTOPPED*(s:cint) : bool = (s and 0xff) == 0x7f +; proc WIFCONTINUED*(s:cint) : bool = s == WCONTINUED + +define linkonce_odr i32 @WEXITSTATUS(i32 %m) { + %1 = and i32 %m, 65280 + %2 = ashr i32 %1, 8 + ret i32 %2 +} + +define linkonce_odr i32 @WTERMSIG(i32 %m) { + %1 = and i32 %m, 127 + ret i32 %1 +} + +; unistd.h +define linkonce_odr i8 @S_ISDIR(i32 %m) { + %1 = and i32 %m, 61440 + %2 = icmp eq i32 %1, 16384 + %3 = zext i1 %2 to i8 + ret i8 %3 +} +define linkonce_odr i8 @S_ISCHR(i32 %m) { + %1 = and i32 %m, 61440 + %2 = icmp eq i32 %1, 8192 + %3 = zext i1 %2 to i8 + ret i8 %3 +} +define linkonce_odr i8 @S_ISBLK(i32 %m) { + %1 = and i32 %m, 61440 + %2 = icmp eq i32 %1, 24576 + %3 = zext i1 %2 to i8 + ret i8 %3 +} +define linkonce_odr i8 @S_ISREG(i32 %m) { + %1 = and i32 %m, 61440 + %2 = icmp eq i32 %1, 32768 + %3 = zext i1 %2 to i8 + ret i8 %3 +} +define linkonce_odr i8 @S_ISFIFO(i32 %m) { + %1 = and i32 %m, 61440 + %2 = icmp eq i32 %1, 4096 + %3 = zext i1 %2 to i8 + ret i8 %3 +} +define linkonce_odr i8 @S_ISLNK(i32 %m) { + %1 = and i32 %m, 61440 + %2 = icmp eq i32 %1, 40960 + %3 = zext i1 %2 to i8 + ret i8 %3 +} +define linkonce_odr i8 @S_ISSOCK(i32 %m) { + %1 = and i32 %m, 61440 + %2 = icmp eq i32 %1, 49152 + %3 = zext i1 %2 to i8 + ret i8 %3 +} +; sys/select.h +%fd_set = type { [16 x i64] } + +define linkonce_odr void @FD_ZERO(%fd_set* %0) { + %2 = alloca %fd_set*, align 8 + %3 = alloca i32, align 4 + %4 = alloca %fd_set*, align 8 + store %fd_set* %0, %fd_set** %2, align 8 + br label %5 + +5: ; preds = %1 + %6 = load %fd_set*, %fd_set** %2, align 8 + store %fd_set* %6, %fd_set** %4, align 8 + store i32 0, i32* %3, align 4 + br label %7 + +7: ; preds = %17, %5 + %8 = load i32, i32* %3, align 4 + %9 = zext i32 %8 to i64 + %10 = icmp ult i64 %9, 16 + br i1 %10, label %11, label %20 + +11: ; preds = %7 + %12 = load %fd_set*, %fd_set** %4, align 8 + %13 = getelementptr inbounds %fd_set, %fd_set* %12, i32 0, i32 0 + %14 = load i32, i32* %3, align 4 + %15 = zext i32 %14 to i64 + %16 = getelementptr inbounds [16 x i64], [16 x i64]* %13, i64 0, i64 %15 + store i64 0, i64* %16, align 8 + br label %17 + +17: ; preds = %11 + %18 = load i32, i32* %3, align 4 + %19 = add i32 %18, 1 + store i32 %19, i32* %3, align 4 + br label %7 + +20: ; preds = %7 + br label %21 + +21: ; preds = %20 + ret void +} + +define linkonce_odr void @FD_SET(i32 %0, %fd_set* %1) { + %3 = alloca i32, align 4 + %4 = alloca %fd_set*, align 8 + store i32 %0, i32* %3, align 4 + store %fd_set* %1, %fd_set** %4, align 8 + %5 = load i32, i32* %3, align 4 + %6 = srem i32 %5, 64 + %7 = zext i32 %6 to i64 + %8 = shl i64 1, %7 + %9 = load %fd_set*, %fd_set** %4, align 8 + %10 = getelementptr inbounds %fd_set, %fd_set* %9, i32 0, i32 0 + %11 = load i32, i32* %3, align 4 + %12 = sdiv i32 %11, 64 + %13 = sext i32 %12 to i64 + %14 = getelementptr inbounds [16 x i64], [16 x i64]* %10, i64 0, i64 %13 + %15 = load i64, i64* %14, align 8 + %16 = or i64 %15, %8 + store i64 %16, i64* %14, align 8 + ret void +} + +define linkonce_odr i32 @FD_ISSET(i32 %0, %fd_set* %1) { + %3 = alloca i32, align 4 + %4 = alloca %fd_set*, align 8 + store i32 %0, i32* %3, align 4 + store %fd_set* %1, %fd_set** %4, align 8 + %5 = load %fd_set*, %fd_set** %4, align 8 + %6 = getelementptr inbounds %fd_set, %fd_set* %5, i32 0, i32 0 + %7 = load i32, i32* %3, align 4 + %8 = sdiv i32 %7, 64 + %9 = sext i32 %8 to i64 + %10 = getelementptr inbounds [16 x i64], [16 x i64]* %6, i64 0, i64 %9 + %11 = load i64, i64* %10, align 8 + %12 = load i32, i32* %3, align 4 + %13 = srem i32 %12, 64 + %14 = zext i32 %13 to i64 + %15 = shl i64 1, %14 + %16 = and i64 %11, %15 + %17 = icmp ne i64 %16, 0 + %18 = zext i1 %17 to i32 + ret i32 %18 +} + +define linkonce_odr i8 @WIFEXITED(i32 %m) { + %1 = and i32 %m, 127 + %2 = icmp eq i32 %1, 0 + %3 = zext i1 %2 to i8 + ret i8 %3 +} + +define linkonce_odr i8 @WIFSIGNALED(i32 %m) { + %1 = shl i32 %m, 24 + %2 = and i32 %1, 2130706432 + %3 = add nuw i32 %2, 16777216 + %4 = ashr i32 %3, 25 + %5 = icmp sgt i32 %4, 0 + %6 = zext i1 %5 to i8 + ret i8 %6 +} +; nimbase.h + +declare void @llvm.memset.p0i8.i64(i8*, i8, i64, i32, i1) + +define linkonce_odr void @zeroMem(i8* %p, i64 %s) { + call void @llvm.memset.p0i8.i64(i8* %p, i8 0, i64 %s, i32 0, i1 false) + ret void +} + +declare i32 @memcmp(i8*, i8*, i64) + +define linkonce_odr i8 @equalMem(i8* %a, i8* %b, i64 %l) { + %1 = call i32 @memcmp(i8* %a, i8* %b, i64 %l) + %2 = icmp eq i32 %1, 0 + %3 = zext i1 %2 to i8 + ret i8 %3 +} + +define linkonce_odr i1 @likely(i1 %a) { + ret i1 %a +} + +define linkonce_odr i1 @unlikely(i1 %a) { + ret i1 %a +} + +declare i32 @llvm.bswap.i32(i32) + +define linkonce_odr zeroext i8 @IN6_IS_ADDR_UNSPECIFIED(i8* nocapture readonly) local_unnamed_addr { + %2 = bitcast i8* %0 to i32* + %3 = load i32, i32* %2, align 4 + %4 = icmp eq i32 %3, 0 + br i1 %4, label %5, label %20 + +;