summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--changelog.md5
-rw-r--r--compiler/commands.nim2
-rw-r--r--compiler/extccomp.nim38
-rw-r--r--compiler/options.nim1
-rw-r--r--doc/advopt.txt1
5 files changed, 39 insertions, 8 deletions
diff --git a/changelog.md b/changelog.md
index caead21b4..5b2509663 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,4 +1,4 @@
-# x.x - xxxx-xx-xx
+# 1.2 - xxxx-xx-xx
 
 
 ## Changes affecting backwards compatibility
@@ -77,7 +77,8 @@
 
 - JS target indent is all spaces, instead of mixed spaces and tabs, for
   generated JavaScript.
-
+- The Nim compiler now supports the ``--asm`` command option for easier
+  inspection of the produced assembler code.
 
 
 ## Bugfixes
diff --git a/compiler/commands.nim b/compiler/commands.nim
index b0adaae83..88f6bef57 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -626,6 +626,8 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
       conf.implicitIncludes.add findModule(conf, arg, toFullPath(conf, info)).string
   of "listcmd":
     processOnOffSwitchG(conf, {optListCmd}, arg, pass, info)
+  of "asm":
+    processOnOffSwitchG(conf, {optProduceAsm}, arg, pass, info)
   of "genmapping":
     processOnOffSwitchG(conf, {optGenMapping}, arg, pass, info)
   of "os":
diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim
index 9b5d16457..5c63f246b 100644
--- a/compiler/extccomp.nim
+++ b/compiler/extccomp.nim
@@ -48,6 +48,7 @@ type
                          # used on some platforms
     asmStmtFrmt: string, # format of ASM statement
     structStmtFmt: string, # Format for struct statement
+    produceAsm: string,   # Format how to produce assembler listings
     props: TInfoCCProps] # properties of the C compiler
 
 
@@ -58,6 +59,9 @@ type
 template compiler(name, settings: untyped): untyped =
   proc name: TInfoCC {.compileTime.} = settings
 
+const
+  gnuAsmListing = "-Wa,-acdl=$asmfile -g -fverbose-asm -masm=intel"
+
 # GNU C and C++ Compiler
 compiler gcc:
   result = (
@@ -80,6 +84,7 @@ compiler gcc:
     pic: "-fPIC",
     asmStmtFrmt: "asm($1);$n",
     structStmtFmt: "$1 $3 $2 ", # struct|union [packed] $name
+    produceAsm: gnuAsmListing,
     props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm,
             hasAttribute})
 
@@ -105,6 +110,7 @@ compiler nintendoSwitchGCC:
     pic: "-fPIE",
     asmStmtFrmt: "asm($1);$n",
     structStmtFmt: "$1 $3 $2 ", # struct|union [packed] $name
+    produceAsm: gnuAsmListing,
     props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm,
             hasAttribute})
 
@@ -151,6 +157,7 @@ compiler vcc:
     pic: "",
     asmStmtFrmt: "__asm{$n$1$n}$n",
     structStmtFmt: "$3$n$1 $2",
+    produceAsm: "/Fa$asmfile",
     props: {hasCpp, hasAssume, hasDeclspec})
 
 compiler clangcl:
@@ -196,6 +203,7 @@ compiler lcc:
     pic: "",
     asmStmtFrmt: "_asm{$n$1$n}$n",
     structStmtFmt: "$1 $2",
+    produceAsm: "",
     props: {})
 
 # Borland C Compiler
@@ -220,6 +228,7 @@ compiler bcc:
     pic: "",
     asmStmtFrmt: "__asm{$n$1$n}$n",
     structStmtFmt: "$1 $2",
+    produceAsm: "",
     props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard,
             hasAttribute})
 
@@ -245,6 +254,7 @@ compiler dmc:
     pic: "",
     asmStmtFrmt: "__asm{$n$1$n}$n",
     structStmtFmt: "$3$n$1 $2",
+    produceAsm: "",
     props: {hasCpp})
 
 # Watcom C Compiler
@@ -269,6 +279,7 @@ compiler wcc:
     pic: "",
     asmStmtFrmt: "__asm{$n$1$n}$n",
     structStmtFmt: "$1 $2",
+    produceAsm: "",
     props: {hasCpp})
 
 # Tiny C Compiler
@@ -293,6 +304,7 @@ compiler tcc:
     pic: "",
     asmStmtFrmt: "__asm{$n$1$n}$n",
     structStmtFmt: "$1 $2",
+    produceAsm: "",
     props: {hasSwitchRange, hasComputedGoto})
 
 # Pelles C Compiler
@@ -318,6 +330,7 @@ compiler pcc:
     pic: "",
     asmStmtFrmt: "__asm{$n$1$n}$n",
     structStmtFmt: "$1 $2",
+    produceAsm: "",
     props: {})
 
 # Your C Compiler
@@ -342,6 +355,7 @@ compiler ucc:
     pic: "",
     asmStmtFrmt: "__asm{$n$1$n}$n",
     structStmtFmt: "$1 $2",
+    produceAsm: "",
     props: {})
 
 const
@@ -572,7 +586,8 @@ proc getLinkerExe(conf: ConfigRef; compiler: TSystemCC): string =
            elif optMixedMode in conf.globalOptions and conf.cmd != cmdCompileToCpp: CC[compiler].cppCompiler
            else: getCompilerExe(conf, compiler, AbsoluteFile"")
 
-proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile, isMainFile = false): string =
+proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile,
+                         isMainFile = false; produceOutput = false): string =
   var c = conf.cCompiler
   var options = cFileSpecificOptions(conf, cfile.nimname)
   var exe = getConfigVar(conf, c, ".exe")
@@ -614,19 +629,30 @@ proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile, isMainFile = false): str
 
   # D files are required by nintendo switch libs for
   # compilation. They are basically a list of all includes.
-  let dfile = objfile.changeFileExt(".d").quoteShell()
+  let dfile = objfile.changeFileExt(".d").quoteShell
 
-  objfile = quoteShell(objfile)
   let cfsh = quoteShell(cf)
   result = quoteShell(compilePattern % [
     "dfile", dfile,
-    "file", cfsh, "objfile", objfile, "options", options,
+    "file", cfsh, "objfile", quoteShell(objfile), "options", options,
     "include", includeCmd, "nim", getPrefixDir(conf).string,
     "lib", conf.libpath.string])
+
+  if optProduceAsm in conf.globalOptions:
+    if CC[conf.cCompiler].produceAsm.len > 0:
+      let asmfile = objfile.changeFileExt(".asm").quoteShell
+      addOpt(result, CC[conf.cCompiler].produceAsm % ["asmfile", asmfile])
+      if produceOutput:
+        rawMessage(conf, hintUserRaw, "Produced assembler here: " & asmfile)
+    else:
+      if produceOutput:
+        rawMessage(conf, hintUserRaw, "Couldn't produce assembler listing " &
+          "for the selected C compiler: " & CC[conf.cCompiler].name)
+
   add(result, ' ')
   addf(result, CC[c].compileTmpl, [
     "dfile", dfile,
-    "file", cfsh, "objfile", objfile,
+    "file", cfsh, "objfile", quoteShell(objfile),
     "options", options, "include", includeCmd,
     "nim", quoteShell(getPrefixDir(conf)),
     "lib", quoteShell(conf.libpath),
@@ -680,7 +706,7 @@ proc compileCFiles(conf: ConfigRef; list: CfileList, script: var Rope, cmds: var
   for it in list:
     # call the C compiler for the .c file:
     if it.flags.contains(CfileFlag.Cached): continue
-    var compileCmd = getCompileCFileCmd(conf, it, currIdx == list.len - 1)
+    var compileCmd = getCompileCFileCmd(conf, it, currIdx == list.len - 1, produceOutput=true)
     inc currIdx
     if optCompileOnly notin conf.globalOptions:
       add(cmds, compileCmd)
diff --git a/compiler/options.nim b/compiler/options.nim
index 52ba8254a..2da73ec85 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -89,6 +89,7 @@ type                          # please make sure we have under 32 options
     optMultiMethods
     optNimV019
     optBenchmarkVM            # Enables cpuTime() in the VM
+    optProduceAsm             # produce assembler code
 
   TGlobalOptions* = set[TGlobalOption]
 
diff --git a/doc/advopt.txt b/doc/advopt.txt
index 5209a0737..fef9f6895 100644
--- a/doc/advopt.txt
+++ b/doc/advopt.txt
@@ -117,6 +117,7 @@ Advanced options:
   --dynlibOverrideAll
                             disables the effects of the dynlib pragma
   --listCmd                 list the commands used to execute external programs
+  --asm                     produce assembler code
   --parallelBuild:0|1|...   perform a parallel build
                             value = number of processors (0 for auto-detect)
   --incremental:on|off      only recompile the changed modules (experimental!)
523' href='#n523'>523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588