From 3c4246dd24fd734908edb3fb7133e3d792b2dcbc Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Wed, 25 Dec 2024 16:23:25 +0800 Subject: [PATCH] fixes #23114; Nim v2 regression emit / asm var param dereference inconsistency (#24547) fixes #23114 As in https://github.com/nim-lang/Nim/pull/22074, expressions in bracketed emit are strictly typechecked, this PR applies the same check for symbols in asm statements in order to keep them consistent. --- changelog.md | 2 ++ compiler/nim.cfg | 1 + compiler/pragmas.nim | 5 +++- tests/compiler/tasm2.nim | 54 ++++++++++++++++++++++++++++++++++++++++ tests/config.nims | 1 + 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 tests/compiler/tasm2.nim diff --git a/changelog.md b/changelog.md index 6f764791c4..b9671147f0 100644 --- a/changelog.md +++ b/changelog.md @@ -17,6 +17,8 @@ rounding guarantees (via the - Unknown warnings and hints now gives warnings `warnUnknownNotes` instead of errors. +- With `-d:nimPreviewAsmSemSymbol`, backticked symbols are type checked in the `asm/emit` statements. + ## Standard library additions and changes [//]: # "Additions:" diff --git a/compiler/nim.cfg b/compiler/nim.cfg index 0d34401dc9..c0e4491503 100644 --- a/compiler/nim.cfg +++ b/compiler/nim.cfg @@ -10,6 +10,7 @@ define:nimPreviewProcConversion define:nimPreviewRangeDefault define:nimPreviewNonVarDestructor define:nimPreviewCheckedClose +define:nimPreviewAsmSemSymbol threads:off #import:"$projectpath/testability" diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index c38fa2e62a..098ce36d58 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -637,7 +637,10 @@ proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode = # XXX what to do here if 'amb' is true? if e != nil: incl(e.flags, sfUsed) - result.add newSymNode(e) + if isDefined(con.config, "nimPreviewAsmSemSymbol"): + result.add con.semExprWithType(con, newSymNode(e), {efTypeAllowed}) + else: + result.add newSymNode(e) else: result.add newStrNode(nkStrLit, sub) else: diff --git a/tests/compiler/tasm2.nim b/tests/compiler/tasm2.nim new file mode 100644 index 0000000000..a139d0d303 --- /dev/null +++ b/tests/compiler/tasm2.nim @@ -0,0 +1,54 @@ +discard """ + targets: "c cpp" + disabled: "arm64" +""" + +import std/strutils + +block: # bug #23114 + func ccopy_x86_asm(ctl: uint64, x: var uint64, y: uint64) = + asm """ + testq %[ctl], %[ctl] + cmovnzq %[y], %[x] + : [x] "+r" (`x`) + : [ctl] "r" (`ctl`), [y] "r" (`y`) + : "cc" + """ + + func ccopy_x86_emit(ctl: uint64, x: var uint64, y: uint64) = + {.emit:[ + """ + asm volatile( + "testq %[ctl], %[ctl]\n" + "cmovnzq %[y], %[x]\n" + : [x] "+r" (""", x, """) + : [ctl] "r" (""", ctl, """), [y] "r" (""", y, """) + : "cc" + );"""].} + + + let x = 0x1111111'u64 + let y = 0xFFFFFFF'u64 + + block: + let ctl = 1'u64 + var a0 = x + ctl.ccopy_x86_asm(a0, y) + + var a1 = x + ctl.ccopy_x86_emit(a1, y) + + doAssert a0.toHex() == "000000000FFFFFFF" + doAssert a0 == a1 + + block: + let ctl = 0'u64 + var a0 = x + ctl.ccopy_x86_asm(a0, y) + + var a1 = x + ctl.ccopy_x86_emit(a1, y) + + doAssert a0.toHex() == "0000000001111111" + doAssert a0 == a1 + diff --git a/tests/config.nims b/tests/config.nims index 808ddbd83d..71825774c8 100644 --- a/tests/config.nims +++ b/tests/config.nims @@ -38,6 +38,7 @@ switch("define", "nimPreviewHashRef") switch("define", "nimPreviewRangeDefault") switch("define", "nimPreviewNonVarDestructor") switch("define", "nimPreviewCheckedClose") +switch("define", "nimPreviewAsmSemSymbol") switch("warningAserror", "UnnamedBreak") when not defined(testsConciseTypeMismatch):