platform.nim 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2012 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. # This module contains data about the different processors
  10. # and operating systems.
  11. # Note: Unfortunately if an OS or CPU is listed here this does not mean that
  12. # Nim has been tested on this platform or that the RTL has been ported.
  13. # Feel free to test for your excentric platform!
  14. import
  15. strutils
  16. when defined(nimPreviewSlimSystem):
  17. import std/assertions
  18. type
  19. TSystemOS* = enum # Also add OS in initialization section and alias
  20. # conditionals to condsyms (end of module).
  21. osNone, osDos, osWindows, osOs2, osLinux, osMorphos, osSkyos, osSolaris,
  22. osIrix, osNetbsd, osFreebsd, osOpenbsd, osDragonfly, osCrossos, osAix, osPalmos, osQnx,
  23. osAmiga, osAtari, osNetware, osMacos, osMacosx, osIos, osHaiku, osAndroid, osVxWorks
  24. osGenode, osJS, osNimVM, osStandalone, osNintendoSwitch, osFreeRTOS, osZephyr,
  25. osNuttX, osAny
  26. type
  27. TInfoOSProp* = enum
  28. ospNeedsPIC, # OS needs PIC for libraries
  29. ospCaseInsensitive, # OS filesystem is case insensitive
  30. ospPosix, # OS is posix-like
  31. ospLacksThreadVars # OS lacks proper __threadvar support
  32. TInfoOSProps* = set[TInfoOSProp]
  33. TInfoOS* = tuple[name: string, parDir: string, dllFrmt: string,
  34. altDirSep: string, objExt: string, newLine: string,
  35. pathSep: string, dirSep: string, scriptExt: string,
  36. curDir: string, exeExt: string, extSep: string,
  37. props: TInfoOSProps]
  38. const
  39. OS*: array[succ(low(TSystemOS))..high(TSystemOS), TInfoOS] = [
  40. (name: "DOS",
  41. parDir: "..", dllFrmt: "$1.dll", altDirSep: "/", objExt: ".obj",
  42. newLine: "\x0D\x0A", pathSep: ";", dirSep: "\\", scriptExt: ".bat",
  43. curDir: ".", exeExt: ".exe", extSep: ".", props: {ospCaseInsensitive}),
  44. (name: "Windows", parDir: "..", dllFrmt: "$1.dll", altDirSep: "/",
  45. objExt: ".obj", newLine: "\x0D\x0A", pathSep: ";", dirSep: "\\",
  46. scriptExt: ".bat", curDir: ".", exeExt: ".exe", extSep: ".",
  47. props: {ospCaseInsensitive}),
  48. (name: "OS2", parDir: "..",
  49. dllFrmt: "$1.dll", altDirSep: "/",
  50. objExt: ".obj", newLine: "\x0D\x0A",
  51. pathSep: ";", dirSep: "\\",
  52. scriptExt: ".bat", curDir: ".",
  53. exeExt: ".exe", extSep: ".",
  54. props: {ospCaseInsensitive}),
  55. (name: "Linux", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
  56. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  57. scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
  58. props: {ospNeedsPIC, ospPosix}),
  59. (name: "MorphOS", parDir: "..",
  60. dllFrmt: "lib$1.so", altDirSep: "/",
  61. objExt: ".o", newLine: "\x0A",
  62. pathSep: ":", dirSep: "/",
  63. scriptExt: ".sh", curDir: ".",
  64. exeExt: "", extSep: ".",
  65. props: {ospNeedsPIC, ospPosix}),
  66. (name: "SkyOS", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
  67. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  68. scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
  69. props: {ospNeedsPIC, ospPosix}),
  70. (name: "Solaris", parDir: "..",
  71. dllFrmt: "lib$1.so", altDirSep: "/",
  72. objExt: ".o", newLine: "\x0A",
  73. pathSep: ":", dirSep: "/",
  74. scriptExt: ".sh", curDir: ".",
  75. exeExt: "", extSep: ".",
  76. props: {ospNeedsPIC, ospPosix}),
  77. (name: "Irix", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
  78. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  79. scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
  80. props: {ospNeedsPIC, ospPosix}),
  81. (name: "NetBSD", parDir: "..",
  82. dllFrmt: "lib$1.so", altDirSep: "/",
  83. objExt: ".o", newLine: "\x0A",
  84. pathSep: ":", dirSep: "/",
  85. scriptExt: ".sh", curDir: ".",
  86. exeExt: "", extSep: ".",
  87. props: {ospNeedsPIC, ospPosix}),
  88. (name: "FreeBSD", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
  89. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  90. scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
  91. props: {ospNeedsPIC, ospPosix}),
  92. (name: "OpenBSD", parDir: "..",
  93. dllFrmt: "lib$1.so", altDirSep: "/",
  94. objExt: ".o", newLine: "\x0A",
  95. pathSep: ":", dirSep: "/",
  96. scriptExt: ".sh", curDir: ".",
  97. exeExt: "", extSep: ".",
  98. props: {ospNeedsPIC, ospPosix}),
  99. (name: "DragonFly", parDir: "..",
  100. dllFrmt: "lib$1.so", altDirSep: "/",
  101. objExt: ".o", newLine: "\x0A",
  102. pathSep: ":", dirSep: "/",
  103. scriptExt: ".sh", curDir: ".",
  104. exeExt: "", extSep: ".",
  105. props: {ospNeedsPIC, ospPosix}),
  106. (name: "CROSSOS", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
  107. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  108. scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
  109. props: {ospNeedsPIC, ospPosix}),
  110. (name: "AIX", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
  111. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  112. scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
  113. props: {ospNeedsPIC, ospPosix}),
  114. (name: "PalmOS", parDir: "..",
  115. dllFrmt: "lib$1.so", altDirSep: "/",
  116. objExt: ".o", newLine: "\x0A",
  117. pathSep: ":", dirSep: "/",
  118. scriptExt: ".sh", curDir: ".",
  119. exeExt: "", extSep: ".",
  120. props: {ospNeedsPIC}),
  121. (name: "QNX",
  122. parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", objExt: ".o",
  123. newLine: "\x0A", pathSep: ":", dirSep: "/", scriptExt: ".sh", curDir: ".",
  124. exeExt: "", extSep: ".", props: {ospNeedsPIC, ospPosix}),
  125. (name: "Amiga",
  126. parDir: "..", dllFrmt: "$1.library", altDirSep: "/", objExt: ".o",
  127. newLine: "\x0A", pathSep: ":", dirSep: "/", scriptExt: ".sh", curDir: ".",
  128. exeExt: "", extSep: ".", props: {ospNeedsPIC}),
  129. (name: "Atari",
  130. parDir: "..", dllFrmt: "$1.dll", altDirSep: "/", objExt: ".o",
  131. newLine: "\x0A", pathSep: ":", dirSep: "/", scriptExt: "", curDir: ".",
  132. exeExt: ".tpp", extSep: ".", props: {ospNeedsPIC}),
  133. (name: "Netware",
  134. parDir: "..", dllFrmt: "$1.nlm", altDirSep: "/", objExt: "",
  135. newLine: "\x0D\x0A", pathSep: ":", dirSep: "/", scriptExt: ".sh",
  136. curDir: ".", exeExt: ".nlm", extSep: ".", props: {ospCaseInsensitive}),
  137. (name: "MacOS", parDir: "::", dllFrmt: "$1Lib", altDirSep: ":",
  138. objExt: ".o", newLine: "\x0D", pathSep: ",", dirSep: ":", scriptExt: "",
  139. curDir: ":", exeExt: "", extSep: ".", props: {ospCaseInsensitive}),
  140. (name: "MacOSX", parDir: "..", dllFrmt: "lib$1.dylib", altDirSep: ":",
  141. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  142. scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
  143. props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}),
  144. (name: "iOS", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
  145. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  146. scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
  147. props: {ospNeedsPIC, ospPosix}),
  148. (name: "Haiku", parDir: "..", dllFrmt: "lib$1.so", altDirSep: ":",
  149. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  150. scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
  151. props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}),
  152. (name: "Android", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
  153. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  154. scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
  155. props: {ospNeedsPIC, ospPosix}),
  156. (name: "VxWorks", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
  157. objExt: ".o", newLine: "\x0A", pathSep: ";", dirSep: "\\",
  158. scriptExt: ".sh", curDir: ".", exeExt: ".vxe", extSep: ".",
  159. props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}),
  160. (name: "Genode", pardir: "..", dllFrmt: "$1.lib.so", altDirSep: "/",
  161. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  162. scriptExt: "", curDir: "/", exeExt: "", extSep: ".",
  163. props: {ospNeedsPIC, ospLacksThreadVars}),
  164. (name: "JS", parDir: "..",
  165. dllFrmt: "lib$1.so", altDirSep: "/",
  166. objExt: ".o", newLine: "\x0A",
  167. pathSep: ":", dirSep: "/",
  168. scriptExt: ".sh", curDir: ".",
  169. exeExt: "", extSep: ".", props: {}),
  170. (name: "NimVM", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
  171. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  172. scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", props: {}),
  173. (name: "Standalone", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
  174. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  175. scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
  176. props: {}),
  177. (name: "NintendoSwitch", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
  178. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  179. scriptExt: ".sh", curDir: ".", exeExt: ".elf", extSep: ".",
  180. props: {ospNeedsPIC, ospPosix}),
  181. (name: "FreeRTOS", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
  182. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  183. scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
  184. props: {ospPosix}),
  185. (name: "Zephyr", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
  186. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  187. scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
  188. props: {ospPosix}),
  189. (name: "NuttX", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
  190. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  191. scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
  192. props: {ospPosix}),
  193. (name: "Any", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
  194. objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
  195. scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
  196. props: {}),
  197. ]
  198. type
  199. TSystemCPU* = enum # Also add CPU for in initialization section and
  200. # alias conditionals to condsyms (end of module).
  201. cpuNone, cpuI386, cpuM68k, cpuAlpha, cpuPowerpc, cpuPowerpc64,
  202. cpuPowerpc64el, cpuSparc, cpuVm, cpuHppa, cpuIa64, cpuAmd64, cpuMips,
  203. cpuMipsel, cpuArm, cpuArm64, cpuJS, cpuNimVM, cpuAVR, cpuMSP430,
  204. cpuSparc64, cpuMips64, cpuMips64el, cpuRiscV32, cpuRiscV64, cpuEsp, cpuWasm32,
  205. cpuE2k, cpuLoongArch64
  206. type
  207. TInfoCPU* = tuple[name: string, intSize: int, endian: Endianness,
  208. floatSize, bit: int]
  209. const
  210. EndianToStr*: array[Endianness, string] = ["littleEndian", "bigEndian"]
  211. CPU*: array[succ(low(TSystemCPU))..high(TSystemCPU), TInfoCPU] = [
  212. (name: "i386", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
  213. (name: "m68k", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
  214. (name: "alpha", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
  215. (name: "powerpc", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
  216. (name: "powerpc64", intSize: 64, endian: bigEndian, floatSize: 64,bit: 64),
  217. (name: "powerpc64el", intSize: 64, endian: littleEndian, floatSize: 64,bit: 64),
  218. (name: "sparc", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
  219. (name: "vm", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
  220. (name: "hppa", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
  221. (name: "ia64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
  222. (name: "amd64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64), # a.k.a. x86_64, covers both amd and intel
  223. (name: "mips", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
  224. (name: "mipsel", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
  225. (name: "arm", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
  226. (name: "arm64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
  227. (name: "js", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
  228. (name: "nimvm", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
  229. # xxx this seems buggy; on a 64bit machine, sizeof(int) is 64 in nimvm.
  230. (name: "avr", intSize: 16, endian: littleEndian, floatSize: 32, bit: 16),
  231. (name: "msp430", intSize: 16, endian: littleEndian, floatSize: 32, bit: 16),
  232. (name: "sparc64", intSize: 64, endian: bigEndian, floatSize: 64, bit: 64),
  233. (name: "mips64", intSize: 64, endian: bigEndian, floatSize: 64, bit: 64),
  234. (name: "mips64el", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
  235. (name: "riscv32", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
  236. (name: "riscv64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
  237. (name: "esp", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
  238. (name: "wasm32", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
  239. (name: "e2k", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
  240. (name: "loongarch64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64)]
  241. type
  242. Target* = object
  243. targetCPU*, hostCPU*: TSystemCPU
  244. targetOS*, hostOS*: TSystemOS
  245. intSize*: int
  246. floatSize*: int
  247. ptrSize*: int
  248. tnl*: string # target newline
  249. proc setTarget*(t: var Target; o: TSystemOS, c: TSystemCPU) =
  250. assert(c != cpuNone)
  251. assert(o != osNone)
  252. #echo "new Target: OS: ", o, " CPU: ", c
  253. t.targetCPU = c
  254. t.targetOS = o
  255. t.intSize = CPU[c].intSize div 8
  256. t.floatSize = CPU[c].floatSize div 8
  257. t.ptrSize = CPU[c].bit div 8
  258. t.tnl = OS[o].newLine
  259. proc nameToOS*(name: string): TSystemOS =
  260. for i in succ(osNone)..high(TSystemOS):
  261. if cmpIgnoreStyle(name, OS[i].name) == 0:
  262. return i
  263. result = osNone
  264. proc listOSnames*(): seq[string] =
  265. result = @[]
  266. for i in succ(osNone)..high(TSystemOS):
  267. result.add OS[i].name
  268. proc nameToCPU*(name: string): TSystemCPU =
  269. for i in succ(cpuNone)..high(TSystemCPU):
  270. if cmpIgnoreStyle(name, CPU[i].name) == 0:
  271. return i
  272. result = cpuNone
  273. proc listCPUnames*(): seq[string] =
  274. result = @[]
  275. for i in succ(cpuNone)..high(TSystemCPU):
  276. result.add CPU[i].name
  277. proc setTargetFromSystem*(t: var Target) =
  278. t.hostOS = nameToOS(system.hostOS)
  279. t.hostCPU = nameToCPU(system.hostCPU)
  280. t.setTarget(t.hostOS, t.hostCPU)