summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2013-10-06 00:10:45 +0200
committerAraq <rumpf_a@web.de>2013-10-06 00:10:45 +0200
commitac474a281204fbbc5cfa817106c0b4c745240f18 (patch)
tree23f375796f3f67f88422d1906c8e70411d5e2b7b /compiler
parent422327c01005ae0c7c7238636a96e741923a77d8 (diff)
downloadNim-ac474a281204fbbc5cfa817106c0b4c745240f18.tar.gz
'noStackFrame' implies 'naked' in the generated C code
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ast.nim4
-rw-r--r--compiler/cgen.nim12
-rw-r--r--compiler/extccomp.nim9
-rw-r--r--compiler/semthreads.nim6
-rw-r--r--compiler/semtypes.nim1
-rw-r--r--compiler/semtypinst.nim1
6 files changed, 21 insertions, 12 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index c9c049137..2a7d8a551 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -387,7 +387,7 @@ type
     tfNeedsInit,      # type constains a "not nil" constraint somewhere or some
                       # other type so that it requires inititalization
     tfHasShared,      # type constains a "shared" constraint modifier somewhere
-    tfHasMeta,        # type has "typedesc" or "expr" somewhere
+    tfHasMeta,        # type has "typedesc" or "expr" somewhere; or uses '|'
     tfHasGCedMem,     # type contains GC'ed memory
 
   TTypeFlags* = set[TTypeFlag]
@@ -1210,7 +1210,7 @@ proc newSons(father: PNode, length: int) =
     setlen(father.sons, length)
 
 proc propagateToOwner*(owner, elem: PType) =
-  const HaveTheirOwnEmpty =  {tySequence, tySet}
+  const HaveTheirOwnEmpty = {tySequence, tySet}
   owner.flags = owner.flags + (elem.flags * {tfHasShared, tfHasMeta,
                                              tfHasGCedMem})
   if tfNotNil in elem.flags:
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index d61d3055e..910e675e1 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -761,6 +761,7 @@ proc genProcAux(m: BModule, prc: PSym) =
       if skipTypes(res.typ, abstractInst).kind == tyArray: 
         incl(res.loc.flags, lfIndirect)
         res.loc.s = OnUnknown
+    
   for i in countup(1, sonsLen(prc.typ.n) - 1): 
     var param = prc.typ.n.sons[i].sym
     if param.typ.isCompileTimeOnly: continue
@@ -768,7 +769,9 @@ proc genProcAux(m: BModule, prc: PSym) =
   closureSetup(p, prc)
   genStmts(p, prc.getBody) # modifies p.locals, p.init, etc.
   var generatedProc: PRope
-  if sfPure in prc.flags: 
+  if sfPure in prc.flags:
+    if hasNakedDeclspec in extccomp.CC[extccomp.ccompiler].props:
+      header = con("__declspec(naked) ", header)
     generatedProc = rfmt(nil, "$N$1 {$n$2$3$4}$N$N",
                          header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts))
   else:
@@ -801,8 +804,11 @@ proc genProcPrototype(m: BModule, sym: PSym) =
       app(m.s[cfsVars], rfmt(nil, "extern $1 $2;$n",
                         getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)))
       if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
-  elif not ContainsOrIncl(m.declaredProtos, sym.id): 
-    app(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", genProcHeader(m, sym)))
+  elif not ContainsOrIncl(m.declaredProtos, sym.id):
+    var header = genProcHeader(m, sym)
+    if sfPure in sym.flags and hasNakedAttribute in CC[ccompiler].props:
+      header.app(" __attribute__((naked))")
+    app(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", header))
 
 proc genProcNoForward(m: BModule, prc: PSym) = 
   fillProcLoc(prc)
diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim
index 89524bc53..d7f3386e3 100644
--- a/compiler/extccomp.nim
+++ b/compiler/extccomp.nim
@@ -23,7 +23,9 @@ type
     hasCpp,                   # CC is/contains a C++ compiler
     hasAssume,                # CC has __assume (Visual C extension)
     hasGcGuard,               # CC supports GC_GUARD to keep stack roots
-    hasGnuAsm                 # CC's asm uses the absurd GNU assembler syntax
+    hasGnuAsm,                # CC's asm uses the absurd GNU assembler syntax
+    hasNakedDeclspec,         # CC has __declspec(naked)
+    hasNakedAttribute         # CC has __attribute__((naked))
   TInfoCCProps* = set[TInfoCCProp]
   TInfoCC* = tuple[
     name: string,        # the short name of the compiler
@@ -73,7 +75,8 @@ compiler gcc:
     debug: "",
     pic: "-fPIC",
     asmStmtFrmt: "asm($1);$n",
-    props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm})
+    props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm,
+            hasNakedAttribute})
     
 compiler gpp:
   result = gcc()
@@ -120,7 +123,7 @@ compiler vcc:
     debug: " /GZ /Zi ",
     pic: "",
     asmStmtFrmt: "__asm{$n$1$n}$n",
-    props: {hasCpp, hasAssume})
+    props: {hasCpp, hasAssume, hasNakedDeclspec})
 
 compiler icl:
   # Intel compilers try to imitate the native ones (gcc and msvc)
diff --git a/compiler/semthreads.nim b/compiler/semthreads.nim
index 6f24e1f6d..595ab0454 100644
--- a/compiler/semthreads.nim
+++ b/compiler/semthreads.nim
@@ -333,13 +333,11 @@ proc analyse(c: PProcCtx, n: PNode): TThreadOwner =
     result = toNil
     for i in countup(0, sonsLen(n) - 1):
       var it = n.sons[i]
-      case it.kind
-      of nkElifExpr:
+      if it.len == 2:
         discard analyse(c, it.sons[0])
         aggregateOwner(result, analyse(c, it.sons[1]))
-      of nkElseExpr:
+      else:
         aggregateOwner(result, analyse(c, it.sons[0]))
-      else: internalError(n.info, "analyseIfExpr()")
   of nkStmtListExpr, nkBlockExpr:
     var n = if n.kind == nkBlockExpr: n.sons[1] else: n
     var L = sonsLen(n)
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index d61a1d481..b9893d037 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -924,6 +924,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
           result.addSonSkipIntLit(t1)
           result.addSonSkipIntLit(t2)
           result.flags.incl(if op.id == ord(wAnd): tfAll else: tfAny)
+          result.flags.incl(tfHasMeta)
       elif op.id == ord(wNot):
         checkSonsLen(n, 3)
         result = semTypeNode(c, n.sons[1], prev)
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index b638449d2..61c31a4fe 100644
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -211,6 +211,7 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
     result = ReplaceTypeVarsT(cl, lastSon(t))
   of tyInt:
     result = skipIntLit(t)
+    # XXX now there are also float literals
   else:
     if t.kind == tyArray:
       let idxt = t.sons[0]