-
Notifications
You must be signed in to change notification settings - Fork 8
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
What state is asm allowed to modify? #5
Comments
I believe that is UB with LLVM.
Shouldn't initialization code use |
I think that in the same way that we're probably going to assume stack usage and then let people specify "nostack", we should probably assume status is altered and then let people specify if they know it won't be. |
The main issue here is that we should explicitly and exhaustively specify exactly what state is & isn't allowed to be modified by asm code. |
Right. I was only speaking to Case 1. Case 2 I'm not familiar with because I guess it's some Intel thing? I only do assembly on old ARM devices (ARMv4T), and I'm not familiar with the term "segment registers". Case 3 sounds dag near impossible to tackle and I'm glad I don't have to solve that one myself. |
For case 2, the ARM equivalent would be the the |
|
Not sure how that's relevant. They were deprecated because compiler-generated code can always clobber EFLAGS. But this issue is about what asm blocks are allowed to clobber. When it comes to the condition flags within EFLAGS, the answer is "can clobber unless |
If we allow inline assembly to clobber flags, we should specify what happens with those flags when we exit the inline assembly. Are they restored to their previous value ? Are they left unchanged ? If they are left unchanged, the user might expect: asm!("modify EFLAGS to state A");
asm!("assert EFLAGS is in state A"); to never panic, but we cannot currently guarantee that. Also, if they are left unchanged, then e.g. leaving An alternative would be to "restore" all flags to some safe state after an inline assembly statement without |
The intent is that In between asm blocks, the compiler is free to modify the flags in any way whatsoever, so a second asm block cannot assume any initial value for the flags. To clarify, when I talk about flags I am only referring to some bits of the EFLAGS register. Specifically the status bits (CF, PF, AF, ZF, SF, OF) and the direction flag (DF). The other bits are system-level control flags which are not used by the compiler. |
You also mentioned MXCSR which allows changing the default floating-point environment in the OP. It might be worth it to more precisely spell out which "flags" are being discussed here on each architecture, and to which values they can be modified when |
OK so let's go with this definition of what is covered by The general rule I used is that it covers the parts of flags registers that is not preserved across function calls. (ARM, AArch64, x86) |
Everything outside of these flags is basically considered global state, which you modify at your own risk and which is outside the scope of this RFC. Regarding case 3, I think we can defer that for now. As a future extension we may offer a |
Also add ABI-clobbers as a future extension. Fixes rust-lang#5
Also add ABI-clobbers as a future extension. Fixes rust-lang#5
Also add ABI-clobbers as a future extension. Fixes rust-lang#5
While the input/output operands make it clear what general purpose registers inline asm code is allowed to modify/clobber, it is not clear what other registers are allowed to be modified.
The following examples are x86-specific, but the general principles should apply to all architectures. For the purposes of this discussion, "modified" means that a register is not restored to its original value at the end of the asm.
Case 1: Flags
Is asm code allowed to modify the condition flags? What about other flags in the EFLAGS register? What about floating-point status registers, such as FPCR, FPSR, MXCSR?
Which of these are/aren't covered by
preserves_flags
?Case 2: Segment registers
Is asm code allowed to modify the segment registers? For example, initialization code may need to change the
fs
register to point to the thread-local storage area. Does this conflict with the compiler's use offs
?Case 3: Future registers
Suppose that some new registers are added in the future, such as
xmm[32-63]
. How can current asm code be forward-compatible if they call a function which may clobber these registers?The text was updated successfully, but these errors were encountered: