better support for GNU's assembler

This commit is contained in:
Araq
2013-09-03 23:44:31 +02:00
parent 39da6979ad
commit 891f871ba7
6 changed files with 58 additions and 13 deletions

View File

@@ -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) =

View File

@@ -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()

View File

@@ -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

View File

@@ -2166,6 +2166,33 @@ 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`)
"""
If expression
-------------

View File

@@ -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

View File

@@ -27,7 +27,7 @@ proc getPA(): PA =
return nil
# bug #501
proc f(): int = result
proc f(): int = 54
var
global: int