Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asm syntax pragma #23119

Merged
merged 7 commits into from
Dec 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions compiler/ccgstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1537,6 +1537,21 @@ proc genAsmStmt(p: BProc, t: PNode) =
assert(t.kind == nkAsmStmt)
genLineDir(p, t)
var s = newRopeAppender()

var asmSyntax = ""
if (let p = t[0]; p.kind == nkPragma):
for i in p:
if whichPragma(i) == wAsmSyntax:
asmSyntax = i[1].strVal

if asmSyntax != "" and
not (
asmSyntax == "gcc" and hasGnuAsm in CC[p.config.cCompiler].props or
asmSyntax == "vcc" and hasGnuAsm notin CC[p.config.cCompiler].props):
localError(
p.config, t.info,
"Your compiler does not support the specified inline assembler")

genAsmOrEmitStmt(p, t, isAsmStmt=true, s)
# see bug #2362, "top level asm statements" seem to be a mis-feature
# but even if we don't do this, the example in #2362 cannot possibly
Expand Down
32 changes: 18 additions & 14 deletions compiler/pragmas.nim
Original file line number Diff line number Diff line change
Expand Up @@ -153,20 +153,6 @@ proc pragmaEnsures(c: PContext, n: PNode) =
n[1] = c.semExpr(c, n[1])
closeScope(c)

proc pragmaAsm*(c: PContext, n: PNode): char =
result = '\0'
if n != nil:
for i in 0..<n.len:
let it = n[i]
if it.kind in nkPragmaCallKinds and it.len == 2 and it[0].kind == nkIdent:
case whichKeyword(it[0].ident)
of wSubsChar:
if it[1].kind == nkCharLit: result = chr(int(it[1].intVal))
else: invalidPragma(c, it)
else: invalidPragma(c, it)
else:
invalidPragma(c, it)

proc setExternName(c: PContext; s: PSym, extname: string, info: TLineInfo) =
# special cases to improve performance:
if extname == "$1":
Expand Down Expand Up @@ -307,6 +293,24 @@ proc pragmaNoForward*(c: PContext, n: PNode; flag=sfNoForward) =
"use {.experimental: \"codeReordering\".} instead; " &
(if flag == sfNoForward: "{.noForward.}" else: "{.reorder.}") & " is deprecated")

proc pragmaAsm*(c: PContext, n: PNode): char =
## Checks asm pragmas and get's the asm subschar (default: '`').
result = '\0'
if n != nil:
for i in 0..<n.len:
let it = n[i]
if it.kind in nkPragmaCallKinds and it.len == 2 and it[0].kind == nkIdent:
case whichKeyword(it[0].ident)
of wSubsChar:
if it[1].kind == nkCharLit: result = chr(int(it[1].intVal))
else: invalidPragma(c, it)
of wAsmSyntax:
let s = expectStrLit(c, it)
if s notin ["gcc", "vcc"]: invalidPragma(c, it)
else: invalidPragma(c, it)
else:
invalidPragma(c, it)

proc processCallConv(c: PContext, n: PNode) =
if n.kind in nkPragmaCallKinds and n.len == 2 and n[1].kind == nkIdent:
let sw = whichKeyword(n[1].ident)
Expand Down
2 changes: 1 addition & 1 deletion compiler/wordrecg.nim
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ type
wComputedGoto = "computedGoto", wExperimental = "experimental", wDoctype = "doctype",
wWrite = "write", wGensym = "gensym", wInject = "inject", wDirty = "dirty",
wInheritable = "inheritable", wThreadVar = "threadvar", wEmit = "emit",
wAsmNoStackFrame = "asmNoStackFrame", wImplicitStatic = "implicitStatic",
wAsmNoStackFrame = "asmNoStackFrame", wAsmSyntax = "asmSyntax", wImplicitStatic = "implicitStatic",
wGlobal = "global", wCodegenDecl = "codegenDecl", wUnchecked = "unchecked",
wGuard = "guard", wLocks = "locks", wPartial = "partial", wExplain = "explain",
wLiftLocals = "liftlocals", wEnforceNoRaises = "enforceNoRaises", wSystemRaisesDefect = "systemRaisesDefect",
Expand Down
17 changes: 17 additions & 0 deletions doc/manual_experimental.md
Original file line number Diff line number Diff line change
Expand Up @@ -2595,3 +2595,20 @@ method foo(x: Base) {.base.} = discard
```

It gives an error: method `foo` can be defined only in the same module with its type (Base).


asmSyntax pragma
================

The `asmSyntax` pragma is used to specify target inline assembler syntax in an `asm` statement.

It prevents compiling code with different of the target CC inline asm syntax, i.e. it will not allow gcc inline asm code to be compiled with vcc.

```nim
proc nothing() =
asm {.asmSyntax: "gcc".}"""
nop
"""
```

The current C(C++) backend implementation cannot generate code for gcc and for vcc at the same time. For example, `{.asmSyntax: "vcc".}` with the ICC compiler will not generate code with intel asm syntax, even though ICC can use both gcc-like and vcc-like asm.
Loading