parser: fix asm modifier parsing (allow for =r, =&r, +r, +&r,=m,=rm,=@ccl, =*r) (fix #25070) (#25072)
Some checks are pending
Graphics CI / gg-regressions (push) Waiting to run
vlib modules CI / build-module-docs (push) Waiting to run
native backend CI / native-backend-ubuntu (push) Waiting to run
native backend CI / native-backend-windows (push) Waiting to run
Shy and PV CI / v-compiles-puzzle-vibes (push) Waiting to run
Sanitized CI / sanitize-address-msvc (push) Waiting to run
Sanitized CI / sanitize-undefined-clang (push) Waiting to run
Sanitized CI / sanitize-undefined-gcc (push) Waiting to run
Sanitized CI / tests-sanitize-address-clang (push) Waiting to run
Sanitized CI / sanitize-address-gcc (push) Waiting to run
Sanitized CI / sanitize-memory-clang (push) Waiting to run
sdl CI / v-compiles-sdl-examples (push) Waiting to run
Time CI / time-linux (push) Waiting to run
Time CI / time-macos (push) Waiting to run
Time CI / time-windows (push) Waiting to run
toml CI / toml-module-pass-external-test-suites (push) Waiting to run
Tools CI / tools-linux (clang) (push) Waiting to run
Tools CI / tools-linux (gcc) (push) Waiting to run
Tools CI / tools-linux (tcc) (push) Waiting to run
Tools CI / tools-macos (clang) (push) Waiting to run
Tools CI / tools-windows (gcc) (push) Waiting to run
Tools CI / tools-windows (msvc) (push) Waiting to run
Tools CI / tools-windows (tcc) (push) Waiting to run
Tools CI / tools-docker-ubuntu-musl (push) Waiting to run
vab CI / vab-compiles-v-examples (push) Waiting to run
vab CI / v-compiles-os-android (push) Waiting to run
wasm backend CI / wasm-backend (ubuntu-22.04) (push) Waiting to run
wasm backend CI / wasm-backend (windows-2022) (push) Waiting to run

This commit is contained in:
kbkpbot 2025-08-09 15:29:05 +08:00 committed by GitHub
parent 4e8b24694b
commit 5eebd91425
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 63 additions and 32 deletions

View file

@ -592,40 +592,51 @@ fn (mut p Parser) asm_ios(output bool) []ast.AsmIO {
if p.tok.kind == .lpar {
constraint = if output { '+r' } else { 'r' } // default constraint, though vfmt fmts to `+r` and `r`
} else {
constraint += match p.tok.kind {
.assign {
'='
}
.plus {
'+'
}
.mod {
'%'
}
.amp {
'&'
}
else {
''
}
}
if constraint != '' {
p.next()
}
constraint += p.tok.lit
if p.tok.kind == .at {
p.next()
} else {
if p.tok.kind == .number {
// Numbered constraints - https://gcc.gnu.org/onlinedocs/gcc/Simple-Constraints.html
if p.tok.lit.int() >= 10 {
p.error_with_pos('The digit must be between 0 and 9 only', pos)
return []
}
p.check(.number)
// https://gcc.gnu.org/onlinedocs/gcc/Modifiers.html
if output {
// Output constraint
if p.tok.kind == .assign {
constraint += '='
} else if p.tok.kind == .plus {
constraint += '+'
} else {
p.check(.name)
p.error_with_pos('Output constraint must starts with `=` or `+`',
pos)
return []
}
p.next()
if p.tok.kind == .amp {
constraint += '&'
p.next()
} else if p.tok.kind == .mul {
constraint += '*'
p.next()
}
} else {
// Input constraint
if p.tok.kind == .mod {
constraint += '%'
p.next()
} else if p.tok.kind == .mul {
constraint += '*'
p.next()
}
}
if p.tok.kind == .at {
// hack: `@ccl` is a single token .at, not .at + .name
constraint += p.tok.lit
p.next()
} else if p.tok.kind == .number && !output {
// Numbered constraints - https://gcc.gnu.org/onlinedocs/gcc/Simple-Constraints.html
if p.tok.lit.int() >= 10 {
p.error_with_pos('The digit must be between 0 and 9 only', pos)
return []
}
constraint += p.tok.lit
p.check(.number)
} else {
constraint += p.tok.lit
p.check(.name)
}
}
mut expr := p.expr(0)

View file

@ -110,6 +110,26 @@ fn test_inline_asm() {
; ; eax
}
assert o.str()[0].is_capital()
x := u64(100)
y := u64(200)
mut hi := u64(0)
mut lo := u64(0)
asm amd64 {
mov rax, x
mulq y
mov lo, rax
mov hi, rdx
; =*m (lo)
=&r (hi)
; rm (x)
r (y)
; rax
rdx
cc
}
assert hi == 0
assert lo == 20000
}
@[packed]