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

Clarify requires of Prefix/Directive validity requirements #1588

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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: 8 additions & 7 deletions src/inline-assembly.md
Original file line number Diff line number Diff line change
Expand Up @@ -650,10 +650,6 @@ r[asm.rules.not-exactly-once]
- You cannot assume that an `asm!` block will appear exactly once in the output binary.
The compiler is allowed to instantiate multiple copies of the `asm!` block, for example when the function containing it is inlined in multiple places.

r[asm.rules.x86-prefix-restriction]
- On x86, inline assembly must not end with an instruction prefix (such as `LOCK`) that would apply to instructions generated by the compiler.
- The compiler is currently unable to detect this due to the way inline assembly is compiled, but may catch and reject this in the future.

r[asm.rules.preserves_flags]
> **Note**: As a general rule, the flags covered by `preserves_flags` are those which are *not* preserved when performing a function call.

Expand Down Expand Up @@ -684,6 +680,14 @@ and the rules for assembly may include thousands of pages of architectural refer
Programmers should exercise appropriate care, as invoking this `unsafe` capability comes with
assuming the responsibility of not violating rules of both the compiler or the architecture.

r[asm.validity.stateful]
If inline assembly includes any "stateful" directive that modifies how subsequent assembly is processed, the block must undo the effects of any such directives before the inline assembly ends. If this constraint is violated, an error may be issued if it can be detected, but otherwise the result of executing the program that contains it is undefined - regardless of whether or not the inline assembly block that contains is eventually evaluated by that execution.

r[asm.validity.prefix-restriction]
Inline assembly must not end with an instruction prefix (such as `LOCK`) that would apply to instructions generated by the compiler. If this constraint is violated, an error may be issued if it can be detected, but otherwise the result of executing the program that contains it is undefined - regardless of whether or not the inline assembly block that contains is eventually evaluated by that execution.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would generalize this even more: at the end of the asm block, the CPU must be in a state where it is ready to start a new instruction. Alternatively, the asm block must end at an instruction boundary. This covers cases where you use .byte to only emit a part of an instruction, or leaving the assembler at an unaligned address for architectures that require aligned instructions (e.g. aarch64).


> **Note:** The two previous constraints are not currently checked but may be in the future.

### Directives Support

r[asm.directives]
Expand All @@ -692,9 +696,6 @@ r[asm.directives.subset-supported]
Inline assembly supports a subset of the directives supported by both GNU AS and LLVM's internal assembler, given as follows.
The result of using other directives is assembler-specific (and may cause an error, or may be accepted as-is).

r[asm.directives.stateful]
If inline assembly includes any "stateful" directive that modifies how subsequent assembly is processed, the block must undo the effects of any such directives before the inline assembly ends.

r[asm.directives.supported-directives]
The following directives are guaranteed to be supported by the assembler:

Expand Down