-
Notifications
You must be signed in to change notification settings - Fork 273
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
cmsis: add __BKPT #540
cmsis: add __BKPT #540
Conversation
hold on. It seems this implementation errors at call site when invoked:
|
To preserve the immediate value and match the CMSIS implementation I see two alternatives:
macro_rules! __BKPT {
($value:expr) => {
asm!(concat!("bkpt ", stringify!($value)) : : : : "volatile")
};
} With this
#[inline]
pub unsafe fn __BKPT(value: u8) {
match value {
0 => asm!("bkpt 0" : : : : "volatile"),
1 => asm!("bkpt 1" : : : : "volatile"),
// ..
254 => asm!("bkpt 254" : : : : "volatile"),
_ => asm!("bkpt 255" : : : : "volatile"),
}
} This also works but produces terrible machine code when compiled without optimizations -- all the The other option is to deviate from the CMSIS specification and omit the immediate value in the #[inline]
pub unsafe fn __BKPT() {
asm!("bkpt" : : : : "volatile")
} From the ARM documentation:
(emphasis mine) So, I don't much is lost by not providing a way to set the immediate value. The immediate value is I would vote for providing the Thoughts? @Amanieu @paoloteti |
FWIW, this is what we do for all others intrinsics having the same issue: There is a proc macro you can use to enforce that the value passed as the immediate is a const: The plan was to, once we have const generics, require these arguments to be const using that feature, somehow. Also, by "terrible code" you probably mean that this bloats the binary (by 1-2kb) and will trash the icache. However, opt-level=1 is typically enough to remove this, so if someone uses this intrinsic a lot enabling opt-level=1 in debug builds is probably a good solution (and if 1kb of code size matter, probably necessary anyways). |
There are 2 versions of BKPT and the ARMC implementation is
Where:
So I guess, Not sure exist a llvm.arm.bkpt or llvm.dbg.bkpt you can use. I don't know if it works on Rust, but may be you can do something like
to modify on the fly the BKPT istruction using .inst. |
There is one x86 intrinsic that takes an What we decided to do back then is to just not provide the intrinsic and wait for const generics, which should solve this issue (e.g. you can pass the const as a type level value For 256 values, the constify macros work just fine with opt-level=1, and even opt-level=0 if you don't care that much about bloated binaries and trashing the icache in debug builds. The @alexcrichton has mentioned a couple of times that we should avoid exporting macros for this because exporting macros from the std library is too tricky. So I think that you should weight:
I'd say that if For // coresimd:
pub unsafe fn __breakpoint_hack<T: BreakPointHack>(x: T) {
... T::VALUE ...
}
pub trait BreakPointHack { const VALUE: i16; }
// user code:
struct Eight;
impl BreakPointHack for Eight { const VALUE: i16 = 8; }
__breakpoint_hack(Eight); Once we get const generics, we can then deprecate |
Some processors can change between ARM mode and Thumb mode at runtime, I think. Should we provide two versions of BKPT one with signature
I use BKPT a lot but without the immediate value: that is I use In stable I have to call BKPT via FFI because inline assembly is not stable. This is very annoying because FFI always involves a function call so the debugger will end in the wrong stack frame and I'll have to manually pop the last frame to see from where __bkpt was called. Having a way to inline the BKPT instruction on stable would be a great improvement to the debugging experience.
They don't appear that often in my code. I would say that, while developing / debugging, I will have at least one instance; at most I would probably have 3 or 4 instances. When I use semihosting BKPT appears a lot most often because it's used in the implementation of In conclusion: to me having a stable version of BKPT without immediate value is much more important than having an unstable way to use BKPT with an immediate value. |
More than a runtime switch is a double support. Cortex-R boot-up in ARM mode, but then can use thumb istructions (boot code shall be in ARM mode). So I agree on an |
Forwarding a comment by @nagisa from another thread (rust-embedded/wg#63 (comment)):
|
I'm getting old and I used |
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.
Before merging more CMSIS intrinsics we should resolve whether CMSIS is the right spec to implement.
I've re-opened #437 to discuss this.
This discussion is something that has to happen for the RFC anyways, so we might just as well have it now.
I think we could add The signature of |
This is fine, and there is precedence for this for some of the x86 intrinsics (e.g. has_cpuid etc.). Just add a reference to the ARMCC compiler documentations in the intrinsic docs.
Improving this later is a backwards compatible change (enabling new code to compile that did not compile before), so I think this would be fine.
|
Closing in favor of #558 |
I overlooked this intrinsic in my previous PR because the reference implementation implemented it as a macro rather than as a function.