Skip to content

Commit ee31866

Browse files
japaricgnzlbg
authored andcommitted
acle: add ldrex, clrex and strex
1 parent ac5493a commit ee31866

File tree

2 files changed

+119
-0
lines changed

2 files changed

+119
-0
lines changed

crates/core_arch/src/acle/ex.rs

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// Reference: Section 5.4.4 "LDREX / STREX" of ACLE
2+
3+
/// Removes the exclusive lock created by LDREX
4+
// Supported: v6, v6K, v7-M, v7-A, v7-R
5+
// Not supported: v5, v6-M
6+
#[cfg(any(
7+
all(target_feature = "v6", not(target_feature = "mclass")), // excludes v6-M
8+
all(target_feature = "v7", target_feature = "mclass"), // v7-M
9+
))]
10+
pub unsafe fn __clrex() {
11+
extern "C" {
12+
#[link_name = "llvm.arm.clrex"]
13+
fn clrex();
14+
}
15+
16+
clrex()
17+
}
18+
19+
/// Executes a exclusive LDR instruction for 8 bit value.
20+
// Supported: v6K, v7-M, v7-A, v7-R
21+
// Not supported: v5, v6, v6-M
22+
#[cfg(
23+
target_feature = "v6k", // includes v7-M but excludes v6-M
24+
)]
25+
pub unsafe fn __ldrexb(p: *const u8) -> u8 {
26+
extern "C" {
27+
#[link_name = "llvm.arm.ldrex.p0i8"]
28+
fn ldrex8(p: *const u8) -> u32;
29+
}
30+
31+
ldrex8(p) as u8
32+
}
33+
34+
/// Executes a exclusive LDR instruction for 16 bit value.
35+
// Supported: v6K, v7-M, v7-A, v7-R, v8
36+
// Not supported: v5, v6, v6-M
37+
#[cfg(
38+
target_feature = "v6k", // includes v7-M but excludes v6-M
39+
)]
40+
pub unsafe fn __ldrexh(p: *const u16) -> u16 {
41+
extern "C" {
42+
#[link_name = "llvm.arm.ldrex.p0i16"]
43+
fn ldrex16(p: *const u16) -> u32;
44+
}
45+
46+
ldrex16(p) as u16
47+
}
48+
49+
/// Executes a exclusive LDR instruction for 32 bit value.
50+
// Supported: v6, v7-M, v6K, v7-A, v7-R, v8
51+
// Not supported: v5, v6-M
52+
#[cfg(any(
53+
all(target_feature = "v6", not(target_feature = "mclass")), // excludes v6-M
54+
all(target_feature = "v7", target_feature = "mclass"), // v7-M
55+
))]
56+
pub unsafe fn __ldrex(p: *const u32) -> u32 {
57+
extern "C" {
58+
#[link_name = "llvm.arm.ldrex.p0i32"]
59+
fn ldrex32(p: *const u32) -> u32;
60+
}
61+
62+
ldrex32(p)
63+
}
64+
65+
/// Executes a exclusive STR instruction for 8 bit values
66+
///
67+
/// Returns `0` if the operation succeeded, or `1` if it failed
68+
// supported: v6K, v7-M, v7-A, v7-R
69+
// Not supported: v5, v6, v6-M
70+
#[cfg(
71+
target_feature = "v6k", // includes v7-M but excludes v6-M
72+
)]
73+
pub unsafe fn __strexb(value: u32, addr: *const u8) -> u32 {
74+
extern "C" {
75+
#[link_name = "llvm.arm.strex.p0i8"]
76+
fn strex8(value: u32, addr: *const u8) -> u32;
77+
}
78+
79+
strex8(value, addr)
80+
}
81+
82+
/// Executes a exclusive STR instruction for 16 bit values
83+
///
84+
/// Returns `0` if the operation succeeded, or `1` if it failed
85+
// Supported: v6K, v7-M, v7-A, v7-R, v8
86+
// Not supported: v5, v6, v6-M
87+
#[cfg(
88+
target_feature = "v6k", // includes v7-M but excludes v6-M
89+
)]
90+
pub unsafe fn __strexh(value: u16, addr: *const u16) -> u32 {
91+
extern "C" {
92+
#[link_name = "llvm.arm.strex.p0i16"]
93+
fn strex16(value: u32, addr: *const u16) -> u32;
94+
}
95+
96+
strex16(value as u32, addr)
97+
}
98+
99+
/// Executes a exclusive STR instruction for 32 bit values
100+
///
101+
/// Returns `0` if the operation succeeded, or `1` if it failed
102+
// Supported: v6, v7-M, v6K, v7-A, v7-R, v8
103+
// Not supported: v5, v6-M
104+
#[cfg(any(
105+
all(target_feature = "v6", not(target_feature = "mclass")), // excludes v6-M
106+
all(target_feature = "v7", target_feature = "mclass"), // v7-M
107+
))]
108+
pub unsafe fn __strex(value: u32, addr: *const u32) -> u32 {
109+
extern "C" {
110+
#[link_name = "llvm.arm.strex.p0i32"]
111+
fn strex32(value: u32, addr: *const u32) -> u32;
112+
}
113+
114+
strex32(value, addr)
115+
}

crates/core_arch/src/acle/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ mod registers;
5959

6060
pub use self::registers::*;
6161

62+
mod ex;
63+
64+
pub use self::ex::*;
65+
6266
// Supported arches: 5TE, 7E-M. See Section 10.1 of ACLE (e.g. QADD)
6367
// We also include the A profile even though DSP is deprecated on that profile as of ACLE 2.0 (see
6468
// section 5.4.7)

0 commit comments

Comments
 (0)