From c40ececccb4082bf1adb3647594720f186613d84 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Tue, 19 Jun 2018 17:07:10 +0900 Subject: [PATCH] Add compiler configuration for Nintendo Switch and it's CPU --- compiler/extccomp.nim | 40 ++++++++++++++++++++++++++++++++++++++++ compiler/installer.ini | 1 + compiler/options.nim | 4 +++- compiler/platform.nim | 14 ++++++++++---- 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 615b8c1e1..5a890b790 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -83,6 +83,31 @@ compiler gcc: props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm, hasAttribute}) +# GNU C and C++ Compiler +compiler aarch64NoneElfGCC: + result = ( + name: "switch_gcc", + objExt: "o", + optSpeed: " -O3 -ffast-math ", + optSize: " -Os -ffast-math ", + compilerExe: "aarch64-none-elf-gcc", + cppCompiler: "aarch64-none-elf-g++", + compileTmpl: "-MMD -MP -MF $dfile -c $options $include -o $objfile $file", + buildGui: " -mwindows", + buildDll: " -shared", + buildLib: "aarch64-none-elf-gcc-ar rcs $libfile $objfiles", + linkerExe: "aarch64-none-elf-gcc", + linkTmpl: "$buildgui $builddll -Wl,-Map,$mapfile -o $exefile $objfiles $options", + includeCmd: " -I", + linkDirCmd: " -L", + linkLibCmd: " -l$1", + debug: "", + pic: "-fPIE", + asmStmtFrmt: "asm($1);$n", + structStmtFmt: "$1 $3 $2 ", # struct|union [packed] $name + props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm, + hasAttribute}) + # LLVM Frontend for GCC/G++ compiler llvmGcc: result = gcc() # Uses settings from GCC @@ -316,6 +341,7 @@ compiler ucc: const CC*: array[succ(low(TSystemCC))..high(TSystemCC), TInfoCC] = [ gcc(), + aarch64NoneElfGCC(), llvmGcc(), clang(), lcc(), @@ -556,14 +582,20 @@ proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile): string = else: cfile.obj + # D files are required by nintendo switch libs for + # compilation. They are basically a list of all includes. + let dfile = objfile.replace(".o", ".d").quoteShell() + objfile = quoteShell(objfile) cf = quoteShell(cf) result = quoteShell(compilePattern % [ + "dfile", dfile, "file", cf, "objfile", objfile, "options", options, "include", includeCmd, "nim", getPrefixDir(conf), "nim", getPrefixDir(conf), "lib", conf.libpath]) add(result, ' ') addf(result, CC[c].compileTmpl, [ + "dfile", dfile, "file", cf, "objfile", objfile, "options", options, "include", includeCmd, "nim", quoteShell(getPrefixDir(conf)), @@ -659,16 +691,24 @@ proc getLinkCmd(conf: ConfigRef; projectfile, objfiles: string): string = if optCDebug in conf.globalOptions: writeDebugInfo(exefile.changeFileExt("ndb")) exefile = quoteShell(exefile) + + # Map files are required by Nintendo Switch compilation. They are a list + # of all function calls in the library and where they come from. + var mapfile = getNimcacheDir(conf) / splitFile(projectFile).name & ".map" + mapfile = quoteShell(mapfile) + let linkOptions = getLinkOptions(conf) & " " & getConfigVar(conf, conf.cCompiler, ".options.linker") var linkTmpl = getConfigVar(conf, conf.cCompiler, ".linkTmpl") if linkTmpl.len == 0: linkTmpl = CC[conf.cCompiler].linkTmpl result = quoteShell(result % ["builddll", builddll, + "mapfile", mapfile, "buildgui", buildgui, "options", linkOptions, "objfiles", objfiles, "exefile", exefile, "nim", getPrefixDir(conf), "lib", conf.libpath]) result.add ' ' addf(result, linkTmpl, ["builddll", builddll, + "mapfile", mapfile, "buildgui", buildgui, "options", linkOptions, "objfiles", objfiles, "exefile", exefile, "nim", quoteShell(getPrefixDir(conf)), diff --git a/compiler/installer.ini b/compiler/installer.ini index 2847e4e62..7ee986229 100644 --- a/compiler/installer.ini +++ b/compiler/installer.ini @@ -15,6 +15,7 @@ Platforms: """ dragonfly: i386;amd64 haiku: i386;amd64 android: i386;arm;arm64 + nintendoswitch: armv8a57 """ Authors: "Andreas Rumpf" diff --git a/compiler/options.nim b/compiler/options.nim index 1d6ddb09f..aea55e94f 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -124,7 +124,7 @@ type disabledSf, writeOnlySf, readOnlySf, v2Sf TSystemCC* = enum - ccNone, ccGcc, ccLLVM_Gcc, ccCLang, ccLcc, ccBcc, ccDmc, ccWcc, ccVcc, + ccNone, ccGcc, ccaarch64NoneElfGcc, ccLLVM_Gcc, ccCLang, ccLcc, ccBcc, ccDmc, ccWcc, ccVcc, ccTcc, ccPcc, ccUcc, ccIcl, ccIcc CfileFlag* {.pure.} = enum @@ -356,6 +356,8 @@ proc isDefined*(conf: ConfigRef; symbol: string): bool = of "mswindows", "win32": result = conf.target.targetOS == osWindows of "macintosh": result = conf.target.targetOS in {osMacos, osMacosx} of "sunos": result = conf.target.targetOS == osSolaris + of "nintendoswitch": + result = conf.target.targetOS == osNintendoSwitch of "littleendian": result = CPU[conf.target.targetCPU].endian == platform.littleEndian of "bigendian": result = CPU[conf.target.targetCPU].endian == platform.bigEndian of "cpu8": result = CPU[conf.target.targetCPU].bit == 8 diff --git a/compiler/platform.nim b/compiler/platform.nim index 0db16f26c..14ce4e0f7 100644 --- a/compiler/platform.nim +++ b/compiler/platform.nim @@ -22,7 +22,7 @@ type osNone, osDos, osWindows, osOs2, osLinux, osMorphos, osSkyos, osSolaris, osIrix, osNetbsd, osFreebsd, osOpenbsd, osDragonfly, osAix, osPalmos, osQnx, osAmiga, osAtari, osNetware, osMacos, osMacosx, osHaiku, osAndroid, osVxworks - osGenode, osJS, osNimVM, osStandalone + osGenode, osJS, osNimVM, osStandalone, osNintendoSwitch type TInfoOSProp* = enum @@ -168,7 +168,12 @@ const (name: "Standalone", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", - props: {})] + props: {}), + (name: "NintendoSwitch", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", + objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", + scriptExt: ".sh", curDir: ".", exeExt: ".elf", extSep: ".", + props: {ospNeedsPIC, ospPosix}), + ] type TSystemCPU* = enum # Also add CPU for in initialization section and @@ -176,7 +181,7 @@ type cpuNone, cpuI386, cpuM68k, cpuAlpha, cpuPowerpc, cpuPowerpc64, cpuPowerpc64el, cpuSparc, cpuVm, cpuIa64, cpuAmd64, cpuMips, cpuMipsel, cpuArm, cpuArm64, cpuJS, cpuNimVM, cpuAVR, cpuMSP430, cpuSparc64, - cpuMips64, cpuMips64el, cpuRiscV64 + cpuMips64, cpuMips64el, cpuRiscV64, cpuArmv8A57 type TEndian* = enum @@ -208,7 +213,8 @@ const (name: "sparc64", intSize: 64, endian: bigEndian, floatSize: 64, bit: 64), (name: "mips64", intSize: 64, endian: bigEndian, floatSize: 64, bit: 64), (name: "mips64el", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64), - (name: "riscv64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64)] + (name: "riscv64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64), + (name: "armv8a57", intSize: 64, endian: bigEndian, floatSize: 64, bit: 64)] type Target* = object