aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Gabriel Smith <ga29smith@gmail.com> 2018-08-12 18:46:50 -0400
committerGravatar Gabriel Smith <ga29smith@gmail.com> 2018-08-12 18:46:50 -0400
commit73e0b2a25d1766debe4f603dd13a732de2f1993d (patch)
treed574ed4dee9ba3bc9ec195f6cb31b1c567226d83
parent743b8fc282f16ab54ff9ff2540f8db337f3562ad (diff)
downloadcortex-m-73e0b2a25d1766debe4f603dd13a732de2f1993d.tar.gz
cortex-m-73e0b2a25d1766debe4f603dd13a732de2f1993d.tar.zst
cortex-m-73e0b2a25d1766debe4f603dd13a732de2f1993d.zip
Change pre-init to use an empty function that is overwridden instead of a sentinel
Using a sentinel creates a conditional branch that cannot be optimized out whereas an empty default function keeps the codepath linear and can be optimized out in the best case. Signed-off-by: Gabriel Smith <ga29smith@gmail.com>
-rw-r--r--cortex-m-rt/link.x.in2
-rw-r--r--cortex-m-rt/src/lib.rs17
2 files changed, 10 insertions, 9 deletions
diff --git a/cortex-m-rt/link.x.in b/cortex-m-rt/link.x.in
index c2511f7..23f406d 100644
--- a/cortex-m-rt/link.x.in
+++ b/cortex-m-rt/link.x.in
@@ -54,7 +54,7 @@ EXTERN(__INTERRUPTS); /* `static` variable similar to `__EXCEPTIONS` */
/* # Pre-initialization function */
/* If the user overrides this using the `pre_init!` macro or by creating a `__pre_init` function,
then the function this points to will be called before the RAM is initialized. */
-PROVIDE(__pre_init = 1);
+PROVIDE(__pre_init = DefaultPreInit);
/* # Sections */
SECTIONS
diff --git a/cortex-m-rt/src/lib.rs b/cortex-m-rt/src/lib.rs
index 04d5b9e..cecb5f8 100644
--- a/cortex-m-rt/src/lib.rs
+++ b/cortex-m-rt/src/lib.rs
@@ -237,11 +237,10 @@
//! have a size of 32 vectors (on ARMv6-M) or 240 vectors (on ARMv7-M). This array is located after
//! `__EXCEPTIONS` in the `.vector_table` section.
//!
-//! - `__pre_init`. This is a function to be run before RAM is initialized. It defaults pointing at
-//! `1` and if not changed to point to another address, usually by calling the `pre_init!` macro,
-//! the `_pre_init` function is skipped. The function cannot default to `0` as the compiler
-//! optimizes out the check for `0` under the assumption that a function pointer cannot point to
-//! `0`.
+//! - `__pre_init`. This is a function to be run before RAM is initialized. It defaults to an empty
+//! function. The function called can be changed by calling the `pre_init!` macro. The empty
+//! function is not optimized out by default, but if an empty function is passed to `pre_init!` the
+//! function call will be optimized out.
//!
//! If you override any exception handler you'll find it as an unmangled symbol, e.g. `SysTick` or
//! `SVCall`, in the output of `objdump`,
@@ -493,9 +492,7 @@ pub unsafe extern "C" fn Reset() -> ! {
}
let pre_init: unsafe extern "C" fn() = __pre_init;
- if pre_init as usize != 1 {
- pre_init();
- }
+ pre_init();
// Initialize RAM
r0::zero_bss(&mut __sbss, &mut __ebss);
@@ -552,6 +549,10 @@ pub unsafe extern "C" fn DefaultUserHardFault() {
}
}
+#[doc(hidden)]
+#[no_mangle]
+pub unsafe extern "C" fn DefaultPreInit() {}
+
/// Macro to define the entry point of the program
///
/// **NOTE** This macro must be invoked once and must be invoked from an accessible module, ideally