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
parser: allow lock prefix instructions and numbered reg in asm inline #21022
Conversation
Please add tests in |
vlib/v/parser/parser.v
Outdated
p.check(.name) | ||
if p.tok.kind == .number { | ||
p.check(.number) | ||
} else { | ||
p.check(.name) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? What syntax will trigger the number check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add either a test, or an inline code comment here in the parser source, with the concrete syntax that it allows, or both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sample: fn main() {
asm amd64 {
lock orq (%rsp), 0
}
} does not compile cleanly on both
Only the parser error is different with this PR. |
This compiles cleanly with this PR 🥳 , but cgen errors on master: fn main() {
asm amd64 {
lock inc eax
}
} |
This is a parser error on master, but it is fine here: Later with tcc, it generates code that leads to a runtime error:
With gcc, it is a C compiler error:
since it generated: void main__main(void) {
__asm__ (
"lock orq $0, %rsp;"
);
} and apparently gcc does check the inline assembly. |
Oh sorry. I missed to update the PR description. vfmt just showed me the proper syntax for the (%reg) stuff, so I have declined some changes on the PR and so I focused on the numbered constraint and lock-prefix. The correct test case for the PR is: $if amd64 {
asm amd64 {
lock cmpxchgb '%1', '%2'
; =a (rv)
+m (*&u8(atom))
; q (xchg)
0 (cmp)
; memory
}
} |
And: $if i386 {
asm i386 {
lock orl '(%esp)', 0
}
} $else $if amd64 {
asm amd64 {
lock orq '(%rsp)', 0
}
} |
vlib/v/parser/parser.v
Outdated
allowed_ins := ['add', 'adc', 'and', 'btc', 'btr', 'bts', 'cmpxchg', 'cmpxch8b', | ||
'cmpxchg16b', 'dec', 'inc', 'neg', 'not', 'or', 'sbb', 'sub', 'xor', 'xadd', | ||
'xchg'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be a const instead? I think this may be used in future as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it would be a bit nicer as a constant, for code that uses lots of inline assembly, it will avoid some allocations. On the other hand, such code is rare, while a constant will be initialized every time the compiler is ran 🤔 .
Still, I think that the benefit of not doing allocations each time is greater.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent work.
Allow asm inline cases like: