forked from Amanieu/corosensei
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.rs
57 lines (50 loc) · 2.07 KB
/
build.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//! Special build-time detection for ARM targets.
//!
//! We need to determine some properties of the target for inline assembly that
//! are not otherwise easily available. Specifically:
//! - Does the target use the ARM or Thumb instruction set by default?
//! - Does the target support Thumb2?
//! - Does the target use R7 or R11 for its frame pointer?
//! - Does the target treat R9 as a reserved register?
use std::env;
fn main() {
println!("cargo:rerun-if-changed=build.rs");
// We only care about ARM.
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
if arch != "arm" {
return;
}
// Probe some registers using asm! to see if they are reserved.
let cfg = autocfg::new();
let r7_available = cfg.probe_expression("unsafe { core::arch::asm!(\"\", out(\"r7\") _) }");
let r9_available = cfg.probe_expression("unsafe { core::arch::asm!(\"\", out(\"r9\") _) }");
let r11_available = cfg.probe_expression("unsafe { core::arch::asm!(\"\", out(\"r11\") _) }");
if !r9_available {
autocfg::emit("r9_reserved");
}
match (r7_available, r11_available) {
(true, false) => {}
(false, true) => autocfg::emit("fp_is_r7"),
_ => panic!("could not determine whether frame pointer is r7 or r11"),
}
// The most reliable way is to check for the thumb-mode feature in
// CARGO_CFG_TARGET_FEATURE but this is only available on nightly. As a
// fallback we just check if the target name starts with "thumb".
let (is_thumb, has_thumb2) = if let Ok(target_features) = env::var("CARGO_CFG_TARGET_FEATURE") {
(
target_features.split(',').any(|s| s == "thumb-mode"),
target_features.split(',').any(|s| s == "thumb2"),
)
} else {
// thumbv6m-none-eabi is the only thumb target that doesn't support
// thumb2.
let target = env::var("TARGET").unwrap();
(target.starts_with("thumb"), !target.starts_with("thumbv6"))
};
if is_thumb {
autocfg::emit("is_thumb");
}
if has_thumb2 {
autocfg::emit("has_thumb2");
}
}