Add compiler configuration for Nintendo Switch and it's CPU

This commit is contained in:
Joey Yakimowich-Payne 2018-06-19 17:07:10 +09:00
commit c40ececccb
4 changed files with 54 additions and 5 deletions

View file

@ -83,6 +83,31 @@ compiler gcc:
props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm, props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm,
hasAttribute}) 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++ # LLVM Frontend for GCC/G++
compiler llvmGcc: compiler llvmGcc:
result = gcc() # Uses settings from GCC result = gcc() # Uses settings from GCC
@ -316,6 +341,7 @@ compiler ucc:
const const
CC*: array[succ(low(TSystemCC))..high(TSystemCC), TInfoCC] = [ CC*: array[succ(low(TSystemCC))..high(TSystemCC), TInfoCC] = [
gcc(), gcc(),
aarch64NoneElfGCC(),
llvmGcc(), llvmGcc(),
clang(), clang(),
lcc(), lcc(),
@ -556,14 +582,20 @@ proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile): string =
else: else:
cfile.obj 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) objfile = quoteShell(objfile)
cf = quoteShell(cf) cf = quoteShell(cf)
result = quoteShell(compilePattern % [ result = quoteShell(compilePattern % [
"dfile", dfile,
"file", cf, "objfile", objfile, "options", options, "file", cf, "objfile", objfile, "options", options,
"include", includeCmd, "nim", getPrefixDir(conf), "include", includeCmd, "nim", getPrefixDir(conf),
"nim", getPrefixDir(conf), "lib", conf.libpath]) "nim", getPrefixDir(conf), "lib", conf.libpath])
add(result, ' ') add(result, ' ')
addf(result, CC[c].compileTmpl, [ addf(result, CC[c].compileTmpl, [
"dfile", dfile,
"file", cf, "objfile", objfile, "file", cf, "objfile", objfile,
"options", options, "include", includeCmd, "options", options, "include", includeCmd,
"nim", quoteShell(getPrefixDir(conf)), "nim", quoteShell(getPrefixDir(conf)),
@ -659,16 +691,24 @@ proc getLinkCmd(conf: ConfigRef; projectfile, objfiles: string): string =
if optCDebug in conf.globalOptions: if optCDebug in conf.globalOptions:
writeDebugInfo(exefile.changeFileExt("ndb")) writeDebugInfo(exefile.changeFileExt("ndb"))
exefile = quoteShell(exefile) 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) & " " & let linkOptions = getLinkOptions(conf) & " " &
getConfigVar(conf, conf.cCompiler, ".options.linker") getConfigVar(conf, conf.cCompiler, ".options.linker")
var linkTmpl = getConfigVar(conf, conf.cCompiler, ".linkTmpl") var linkTmpl = getConfigVar(conf, conf.cCompiler, ".linkTmpl")
if linkTmpl.len == 0: if linkTmpl.len == 0:
linkTmpl = CC[conf.cCompiler].linkTmpl linkTmpl = CC[conf.cCompiler].linkTmpl
result = quoteShell(result % ["builddll", builddll, result = quoteShell(result % ["builddll", builddll,
"mapfile", mapfile,
"buildgui", buildgui, "options", linkOptions, "objfiles", objfiles, "buildgui", buildgui, "options", linkOptions, "objfiles", objfiles,
"exefile", exefile, "nim", getPrefixDir(conf), "lib", conf.libpath]) "exefile", exefile, "nim", getPrefixDir(conf), "lib", conf.libpath])
result.add ' ' result.add ' '
addf(result, linkTmpl, ["builddll", builddll, addf(result, linkTmpl, ["builddll", builddll,
"mapfile", mapfile,
"buildgui", buildgui, "options", linkOptions, "buildgui", buildgui, "options", linkOptions,
"objfiles", objfiles, "exefile", exefile, "objfiles", objfiles, "exefile", exefile,
"nim", quoteShell(getPrefixDir(conf)), "nim", quoteShell(getPrefixDir(conf)),

View file

@ -15,6 +15,7 @@ Platforms: """
dragonfly: i386;amd64 dragonfly: i386;amd64
haiku: i386;amd64 haiku: i386;amd64
android: i386;arm;arm64 android: i386;arm;arm64
nintendoswitch: armv8a57
""" """
Authors: "Andreas Rumpf" Authors: "Andreas Rumpf"

View file

@ -124,7 +124,7 @@ type
disabledSf, writeOnlySf, readOnlySf, v2Sf disabledSf, writeOnlySf, readOnlySf, v2Sf
TSystemCC* = enum 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 ccTcc, ccPcc, ccUcc, ccIcl, ccIcc
CfileFlag* {.pure.} = enum CfileFlag* {.pure.} = enum
@ -356,6 +356,8 @@ proc isDefined*(conf: ConfigRef; symbol: string): bool =
of "mswindows", "win32": result = conf.target.targetOS == osWindows of "mswindows", "win32": result = conf.target.targetOS == osWindows
of "macintosh": result = conf.target.targetOS in {osMacos, osMacosx} of "macintosh": result = conf.target.targetOS in {osMacos, osMacosx}
of "sunos": result = conf.target.targetOS == osSolaris 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 "littleendian": result = CPU[conf.target.targetCPU].endian == platform.littleEndian
of "bigendian": result = CPU[conf.target.targetCPU].endian == platform.bigEndian of "bigendian": result = CPU[conf.target.targetCPU].endian == platform.bigEndian
of "cpu8": result = CPU[conf.target.targetCPU].bit == 8 of "cpu8": result = CPU[conf.target.targetCPU].bit == 8

View file

@ -22,7 +22,7 @@ type
osNone, osDos, osWindows, osOs2, osLinux, osMorphos, osSkyos, osSolaris, osNone, osDos, osWindows, osOs2, osLinux, osMorphos, osSkyos, osSolaris,
osIrix, osNetbsd, osFreebsd, osOpenbsd, osDragonfly, osAix, osPalmos, osQnx, osIrix, osNetbsd, osFreebsd, osOpenbsd, osDragonfly, osAix, osPalmos, osQnx,
osAmiga, osAtari, osNetware, osMacos, osMacosx, osHaiku, osAndroid, osVxworks osAmiga, osAtari, osNetware, osMacos, osMacosx, osHaiku, osAndroid, osVxworks
osGenode, osJS, osNimVM, osStandalone osGenode, osJS, osNimVM, osStandalone, osNintendoSwitch
type type
TInfoOSProp* = enum TInfoOSProp* = enum
@ -168,7 +168,12 @@ const
(name: "Standalone", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", (name: "Standalone", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", 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 type
TSystemCPU* = enum # Also add CPU for in initialization section and TSystemCPU* = enum # Also add CPU for in initialization section and
@ -176,7 +181,7 @@ type
cpuNone, cpuI386, cpuM68k, cpuAlpha, cpuPowerpc, cpuPowerpc64, cpuNone, cpuI386, cpuM68k, cpuAlpha, cpuPowerpc, cpuPowerpc64,
cpuPowerpc64el, cpuSparc, cpuVm, cpuIa64, cpuAmd64, cpuMips, cpuMipsel, cpuPowerpc64el, cpuSparc, cpuVm, cpuIa64, cpuAmd64, cpuMips, cpuMipsel,
cpuArm, cpuArm64, cpuJS, cpuNimVM, cpuAVR, cpuMSP430, cpuSparc64, cpuArm, cpuArm64, cpuJS, cpuNimVM, cpuAVR, cpuMSP430, cpuSparc64,
cpuMips64, cpuMips64el, cpuRiscV64 cpuMips64, cpuMips64el, cpuRiscV64, cpuArmv8A57
type type
TEndian* = enum TEndian* = enum
@ -208,7 +213,8 @@ const
(name: "sparc64", intSize: 64, endian: bigEndian, floatSize: 64, bit: 64), (name: "sparc64", intSize: 64, endian: bigEndian, floatSize: 64, bit: 64),
(name: "mips64", 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: "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 type
Target* = object Target* = object