summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgstmts.nim34
-rw-r--r--compiler/extccomp.nim5
-rw-r--r--compiler/nimrod.ini1
-rw-r--r--doc/manual.txt25
-rw-r--r--lib/pure/math.nim2
-rw-r--r--tests/compile/tvarious.nim2
6 files changed, 56 insertions, 13 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index 6f362a615..8115abc2f 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -814,31 +814,47 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
     exprBlock(p, t.sons[i].sons[0], d)
   linefmt(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", safePoint)
 
-proc genAsmOrEmitStmt(p: BProc, t: PNode): PRope = 
-  for i in countup(0, sonsLen(t) - 1): 
+proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): PRope =
+  var res = ""
+  for i in countup(0, sonsLen(t) - 1):
     case t.sons[i].Kind
-    of nkStrLit..nkTripleStrLit: 
-      app(result, t.sons[i].strVal)
-    of nkSym: 
+    of nkStrLit..nkTripleStrLit:
+      res.add(t.sons[i].strVal)
+    of nkSym:
       var sym = t.sons[i].sym
       if sym.kind in {skProc, skIterator, skMethod}: 
         var a: TLoc
         initLocExpr(p, t.sons[i], a)
-        app(result, rdLoc(a))
-      else: 
+        res.add(rdLoc(a).ropeToStr)
+      else:
         var r = sym.loc.r
         if r == nil: 
           # if no name has already been given,
           # it doesn't matter much:
           r = mangleName(sym)
           sym.loc.r = r       # but be consequent!
-        app(result, r)
+        res.add(r.ropeToStr)
     else: InternalError(t.sons[i].info, "genAsmOrEmitStmt()")
+  
+  if isAsmStmt and hasGnuAsm in CC[ccompiler].props:
+    for x in splitLines(res):
+      var j = 0
+      while x[j] in {' ', '\t'}: inc(j)
+      if x[j] == ':' and x[j+1] == '"' or x[j] == '"':
+        # some clobber register list:
+        app(result, x); app(result, tnl)
+      elif x[j] != '\0':
+        # ignore empty lines
+        app(result, "\"")
+        app(result, x)
+        app(result, "\\n\"\n")
+  else:
+    result = res.toRope
 
 proc genAsmStmt(p: BProc, t: PNode) = 
   assert(t.kind == nkAsmStmt)
   genLineDir(p, t)
-  var s = genAsmOrEmitStmt(p, t)
+  var s = genAsmOrEmitStmt(p, t, isAsmStmt=true)
   lineF(p, cpsStmts, CC[ccompiler].asmStmtFrmt, [s])
 
 proc genEmit(p: BProc, t: PNode) = 
diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim
index efb8e5908..488ed18fb 100644
--- a/compiler/extccomp.nim
+++ b/compiler/extccomp.nim
@@ -22,7 +22,8 @@ type
     hasComputedGoto,          # CC has computed goto (GNU C extension)
     hasCpp,                   # CC is/contains a C++ compiler
     hasAssume,                # CC has __assume (Visual C extension)
-    hasGcGuard                # CC supports GC_GUARD to keep stack roots
+    hasGcGuard,               # CC supports GC_GUARD to keep stack roots
+    hasGnuAsm                 # CC's asm uses the absurd GNU assembler syntax
   TInfoCCProps* = set[TInfoCCProp]
   TInfoCC* = tuple[
     name: string,        # the short name of the compiler
@@ -72,7 +73,7 @@ compiler gcc:
     debug: "",
     pic: "-fPIC",
     asmStmtFrmt: "asm($1);$n",
-    props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard})
+    props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm})
     
 compiler gpp:
   result = gcc()
diff --git a/compiler/nimrod.ini b/compiler/nimrod.ini
index 482fe63c9..22623993c 100644
--- a/compiler/nimrod.ini
+++ b/compiler/nimrod.ini
@@ -3,6 +3,7 @@ Name: "Nimrod"
 Version: "$version"
 OS: "windows;linux;macosx;solaris;freebsd;netbsd;openbsd"
 CPU: "i386;amd64;powerpc64;arm"  # ;sparc
+
 Authors: "Andreas Rumpf"
 Description: """This is the Nimrod Compiler. Nimrod is a new statically typed,
 imperative programming language, that supports procedural, functional, object
diff --git a/doc/manual.txt b/doc/manual.txt
index db309c4eb..914e6eaf5 100644
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -2166,6 +2166,31 @@ specified in the statement's pragmas. The default special character is ``'`'``:
       theEnd:
     """
 
+If the GNU assembler is used, quotes and newlines are inserted automatically:
+
+.. code-block:: nimrod
+  proc addInt(a, b: int): int =
+    asm """
+      addl %%ecx, %%eax
+      jno 1
+      call `raiseOverflow`
+      1:
+      :"=a"(`result`)
+      :"a"(`a`), "c"(`b`)
+    """
+
+Instead of:
+
+.. code-block:: nimrod
+  proc addInt(a, b: int): int =
+    asm """
+      "addl %%ecx, %%eax\n"
+      "jno 1\n"
+      "call `raiseOverflow`\n"
+      "1: \n"
+      :"=a"(`result`)
+      :"a"(`a`), "c"(`b`)
+    """
 
 Using statement
 ---------------
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index f04a1a8c1..35b9607e0 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -17,7 +17,7 @@
 
 {.push checks:off, line_dir:off, stack_trace:off.}
 
-when defined(Posix): 
+when defined(Posix) and not defined(haiku):
   {.passl: "-lm".}
 
 const
diff --git a/tests/compile/tvarious.nim b/tests/compile/tvarious.nim
index 25f48bb30..5883ba62f 100644
--- a/tests/compile/tvarious.nim
+++ b/tests/compile/tvarious.nim
@@ -27,7 +27,7 @@ proc getPA(): PA =
   return nil

 
 # bug #501
-proc f(): int = result
+proc f(): int = 54
 

 var

   global: int