better support for GNU's assembler
This commit is contained in:
parent
39da6979ad
commit
891f871ba7
6 changed files with 58 additions and 13 deletions
|
|
@ -814,17 +814,18 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
||||||
exprBlock(p, t.sons[i].sons[0], d)
|
exprBlock(p, t.sons[i].sons[0], d)
|
||||||
linefmt(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", safePoint)
|
linefmt(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", safePoint)
|
||||||
|
|
||||||
proc genAsmOrEmitStmt(p: BProc, t: PNode): PRope =
|
proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): PRope =
|
||||||
|
var res = ""
|
||||||
for i in countup(0, sonsLen(t) - 1):
|
for i in countup(0, sonsLen(t) - 1):
|
||||||
case t.sons[i].Kind
|
case t.sons[i].Kind
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
app(result, t.sons[i].strVal)
|
res.add(t.sons[i].strVal)
|
||||||
of nkSym:
|
of nkSym:
|
||||||
var sym = t.sons[i].sym
|
var sym = t.sons[i].sym
|
||||||
if sym.kind in {skProc, skIterator, skMethod}:
|
if sym.kind in {skProc, skIterator, skMethod}:
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, t.sons[i], a)
|
initLocExpr(p, t.sons[i], a)
|
||||||
app(result, rdLoc(a))
|
res.add(rdLoc(a).ropeToStr)
|
||||||
else:
|
else:
|
||||||
var r = sym.loc.r
|
var r = sym.loc.r
|
||||||
if r == nil:
|
if r == nil:
|
||||||
|
|
@ -832,13 +833,28 @@ proc genAsmOrEmitStmt(p: BProc, t: PNode): PRope =
|
||||||
# it doesn't matter much:
|
# it doesn't matter much:
|
||||||
r = mangleName(sym)
|
r = mangleName(sym)
|
||||||
sym.loc.r = r # but be consequent!
|
sym.loc.r = r # but be consequent!
|
||||||
app(result, r)
|
res.add(r.ropeToStr)
|
||||||
else: InternalError(t.sons[i].info, "genAsmOrEmitStmt()")
|
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) =
|
proc genAsmStmt(p: BProc, t: PNode) =
|
||||||
assert(t.kind == nkAsmStmt)
|
assert(t.kind == nkAsmStmt)
|
||||||
genLineDir(p, t)
|
genLineDir(p, t)
|
||||||
var s = genAsmOrEmitStmt(p, t)
|
var s = genAsmOrEmitStmt(p, t, isAsmStmt=true)
|
||||||
lineF(p, cpsStmts, CC[ccompiler].asmStmtFrmt, [s])
|
lineF(p, cpsStmts, CC[ccompiler].asmStmtFrmt, [s])
|
||||||
|
|
||||||
proc genEmit(p: BProc, t: PNode) =
|
proc genEmit(p: BProc, t: PNode) =
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@ type
|
||||||
hasComputedGoto, # CC has computed goto (GNU C extension)
|
hasComputedGoto, # CC has computed goto (GNU C extension)
|
||||||
hasCpp, # CC is/contains a C++ compiler
|
hasCpp, # CC is/contains a C++ compiler
|
||||||
hasAssume, # CC has __assume (Visual C extension)
|
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]
|
TInfoCCProps* = set[TInfoCCProp]
|
||||||
TInfoCC* = tuple[
|
TInfoCC* = tuple[
|
||||||
name: string, # the short name of the compiler
|
name: string, # the short name of the compiler
|
||||||
|
|
@ -72,7 +73,7 @@ compiler gcc:
|
||||||
debug: "",
|
debug: "",
|
||||||
pic: "-fPIC",
|
pic: "-fPIC",
|
||||||
asmStmtFrmt: "asm($1);$n",
|
asmStmtFrmt: "asm($1);$n",
|
||||||
props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard})
|
props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm})
|
||||||
|
|
||||||
compiler gpp:
|
compiler gpp:
|
||||||
result = gcc()
|
result = gcc()
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ Name: "Nimrod"
|
||||||
Version: "$version"
|
Version: "$version"
|
||||||
OS: "windows;linux;macosx;solaris;freebsd;netbsd;openbsd"
|
OS: "windows;linux;macosx;solaris;freebsd;netbsd;openbsd"
|
||||||
CPU: "i386;amd64;powerpc64;arm" # ;sparc
|
CPU: "i386;amd64;powerpc64;arm" # ;sparc
|
||||||
|
|
||||||
Authors: "Andreas Rumpf"
|
Authors: "Andreas Rumpf"
|
||||||
Description: """This is the Nimrod Compiler. Nimrod is a new statically typed,
|
Description: """This is the Nimrod Compiler. Nimrod is a new statically typed,
|
||||||
imperative programming language, that supports procedural, functional, object
|
imperative programming language, that supports procedural, functional, object
|
||||||
|
|
|
||||||
|
|
@ -2166,6 +2166,33 @@ specified in the statement's pragmas. The default special character is ``'`'``:
|
||||||
theEnd:
|
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
|
If expression
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
{.push checks:off, line_dir:off, stack_trace:off.}
|
{.push checks:off, line_dir:off, stack_trace:off.}
|
||||||
|
|
||||||
when defined(Posix):
|
when defined(Posix) and not defined(haiku):
|
||||||
{.passl: "-lm".}
|
{.passl: "-lm".}
|
||||||
|
|
||||||
const
|
const
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ proc getPA(): PA =
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
# bug #501
|
# bug #501
|
||||||
proc f(): int = result
|
proc f(): int = 54
|
||||||
|
|
||||||
var
|
var
|
||||||
global: int
|
global: int
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue