Skip to content

Commit 9ee7f57

Browse files
committed
s390x: Use reg_addr register class
Refs: rust-lang/rust#119431
1 parent 2b9b7f9 commit 9ee7f57

File tree

5 files changed

+473
-31
lines changed

5 files changed

+473
-31
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ jobs:
179179
target: riscv64gc-unknown-linux-gnu
180180
- rust: nightly
181181
target: s390x-unknown-linux-gnu
182+
- rust: nightly-2024-01-04 # Rust 1.77, LLVM 17 (newest version that does not support reg_addr register class)
183+
target: s390x-unknown-linux-gnu
182184
- rust: nightly-2023-05-09 # Rust 1.71, LLVM 16 (oldest version we can implement atomic RMWs on this target)
183185
target: s390x-unknown-linux-gnu
184186
- rust: '1.59'

build.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ fn main() {
6767
&& version.probe(71, 2023, 5, 8)
6868
&& is_allowed_feature("asm_experimental_arch")
6969
{
70+
// https://github.com/rust-lang/rust/pull/119431 merged in Rust 1.77 (nightly-2024-01-05).
71+
if !version.probe(77, 2024, 1, 4) {
72+
println!("cargo:rustc-cfg=atomic_maybe_uninit_s390x_no_reg_addr");
73+
}
7074
println!("cargo:rustc-cfg=atomic_maybe_uninit_unstable_asm_experimental_arch");
7175
}
7276
}

src/arch/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ mod powerpc;
9797
mod riscv;
9898
#[cfg(target_arch = "s390x")]
9999
#[cfg(atomic_maybe_uninit_unstable_asm_experimental_arch)]
100+
#[cfg_attr(atomic_maybe_uninit_s390x_no_reg_addr, path = "s390x_no_reg_addr.rs")]
100101
mod s390x;
101102
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
102103
mod x86;

src/arch/s390x.rs

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,8 @@ macro_rules! atomic_load_store {
5353
asm!(
5454
// (atomic) load from src to out
5555
concat!("l", $l_suffix, " {out}, 0({src})"),
56-
src = in(reg) ptr_reg!(src),
56+
src = in(reg_addr) ptr_reg!(src),
5757
out = lateout(reg) out,
58-
out("r0") _,
5958
options(nostack, preserves_flags),
6059
);
6160
}
@@ -79,9 +78,8 @@ macro_rules! atomic_load_store {
7978
// (atomic) store val to dst
8079
concat!("st", $asm_suffix, " {val}, 0({dst})"),
8180
$fence,
82-
dst = in(reg) ptr_reg!(dst),
81+
dst = in(reg_addr) ptr_reg!(dst),
8382
val = in(reg) val,
84-
out("r0") _,
8583
options(nostack, preserves_flags),
8684
)
8785
};
@@ -126,13 +124,13 @@ macro_rules! atomic {
126124
// atomic swap is always SeqCst.
127125
asm!(
128126
// (atomic) swap (CAS loop)
129-
concat!("l", $asm_suffix, " %r0, 0({dst})"),
127+
concat!("l", $asm_suffix, " {out}, 0({dst})"),
130128
"2:",
131-
concat!("cs", $asm_suffix, " %r0, {val}, 0({dst})"),
129+
concat!("cs", $asm_suffix, " {out}, {val}, 0({dst})"),
132130
"jl 2b",
133-
dst = in(reg) ptr_reg!(dst),
131+
dst = in(reg_addr) ptr_reg!(dst),
134132
val = in(reg) val,
135-
out("r0") out,
133+
out = out(reg) out,
136134
// Do not use `preserves_flags` because CS modifies the condition code.
137135
options(nostack),
138136
);
@@ -158,13 +156,13 @@ macro_rules! atomic {
158156
// compare_exchange is always SeqCst.
159157
asm!(
160158
// (atomic) CAS
161-
concat!("cs", $asm_suffix, " %r0, {new}, 0({dst})"),
159+
concat!("cs", $asm_suffix, " {old}, {new}, 0({dst})"),
162160
// store condition code
163161
"ipm {r}",
164-
dst = in(reg) ptr_reg!(dst),
162+
dst = in(reg_addr) ptr_reg!(dst),
165163
new = in(reg) new,
166164
r = lateout(reg) r,
167-
inout("r0") old => out,
165+
old = inout(reg) old => out,
168166
// Do not use `preserves_flags` because CS modifies the condition code.
169167
options(nostack),
170168
);
@@ -195,21 +193,21 @@ macro_rules! atomic_sub_word {
195193
// Based on assemblies generated by rustc/LLVM.
196194
// See also create_sub_word_mask_values.
197195
asm!(
198-
"l %r0, 0({dst})",
196+
"l {prev}, 0({dst})",
199197
"2:",
200-
"rll {tmp}, %r0, 0({shift})",
198+
"rll {tmp}, {prev}, 0({shift})",
201199
concat!("risbg {tmp}, {val}, 32, ", $risbg_swap),
202200
"rll {tmp}, {tmp}, 0({shift_c})",
203-
"cs %r0, {tmp}, 0({dst})",
201+
"cs {prev}, {tmp}, 0({dst})",
204202
"jl 2b",
205-
concat!("rll {out}, %r0, ", $bits ,"({shift})"),
206-
dst = in(reg) ptr_reg!(dst),
203+
concat!("rll {out}, {prev}, ", $bits ,"({shift})"),
204+
dst = in(reg_addr) ptr_reg!(dst),
207205
val = in(reg) val,
208206
out = lateout(reg) out,
209-
shift = in(reg) shift as u32,
210-
shift_c = in(reg) complement(shift as u32),
207+
shift = in(reg_addr) shift as u32,
208+
shift_c = in(reg_addr) complement(shift as u32),
211209
tmp = out(reg) _,
212-
out("r0") _, // prev
210+
prev = out(reg) _,
213211
// Do not use `preserves_flags` because CS modifies the condition code.
214212
options(nostack),
215213
);
@@ -239,26 +237,26 @@ macro_rules! atomic_sub_word {
239237
asm!(
240238
"l {prev}, 0({dst})",
241239
"2:",
242-
concat!("rll %r0, {prev}, ", $bits ,"({shift})"),
243-
concat!("risbg {new}, %r0, 32, ", $risbg_cas, ", 0"),
244-
concat!("ll", $asm_suffix, "r %r0, %r0"),
245-
"cr %r0, {old}",
240+
concat!("rll {out}, {prev}, ", $bits ,"({shift})"),
241+
concat!("risbg {new}, {out}, 32, ", $risbg_cas, ", 0"),
242+
concat!("ll", $asm_suffix, "r {out}, {out}"),
243+
"cr {out}, {old}",
246244
"jlh 3f",
247245
concat!("rll {tmp}, {new}, -", $bits ,"({shift_c})"),
248246
"cs {prev}, {tmp}, 0({dst})",
249247
"jl 2b",
250248
"3:",
251249
// store condition code
252250
"ipm {r}",
253-
dst = in(reg) ptr_reg!(dst),
251+
dst = in(reg_addr) ptr_reg!(dst),
254252
prev = out(reg) _,
255253
old = in(reg) crate::utils::zero_extend(old),
256254
new = inout(reg) new => _,
257-
shift = in(reg) shift as u32,
258-
shift_c = in(reg) complement(shift as u32),
255+
shift = in(reg_addr) shift as u32,
256+
shift_c = in(reg_addr) complement(shift as u32),
259257
tmp = out(reg) _,
260258
r = lateout(reg) r,
261-
out("r0") out,
259+
out = out(reg) out,
262260
// Do not use `preserves_flags` because CS modifies the condition code.
263261
options(nostack),
264262
);
@@ -298,7 +296,7 @@ macro_rules! atomic128 {
298296
asm!(
299297
// (atomic) load from src to out pair
300298
"lpq %r0, 0({src})",
301-
src = in(reg) ptr_reg!(src),
299+
src = in(reg_addr) ptr_reg!(src),
302300
// Quadword atomic instructions work with even/odd pair of specified register and subsequent register.
303301
out("r0") prev_hi,
304302
out("r1") prev_lo,
@@ -326,7 +324,7 @@ macro_rules! atomic128 {
326324
// (atomic) store val pair to dst
327325
"stpq %r0, 0({dst})",
328326
$fence,
329-
dst = in(reg) ptr_reg!(dst),
327+
dst = in(reg_addr) ptr_reg!(dst),
330328
// Quadword atomic instructions work with even/odd pair of specified register and subsequent register.
331329
in("r0") val.pair.hi,
332330
in("r1") val.pair.lo,
@@ -373,7 +371,7 @@ macro_rules! atomic128 {
373371
"2:",
374372
"cdsg %r0, %r12, 0({dst})",
375373
"jl 2b",
376-
dst = inout(reg) ptr_reg!(dst) => _,
374+
dst = in(reg_addr) ptr_reg!(dst),
377375
// Quadword atomic instructions work with even/odd pair of specified register and subsequent register.
378376
out("r0") prev_hi,
379377
out("r1") prev_lo,
@@ -409,7 +407,7 @@ macro_rules! atomic128 {
409407
"cdsg %r0, %r12, 0({dst})",
410408
// store condition code
411409
"ipm {r}",
412-
dst = in(reg) ptr_reg!(dst),
410+
dst = in(reg_addr) ptr_reg!(dst),
413411
r = lateout(reg) r,
414412
// Quadword atomic instructions work with even/odd pair of specified register and subsequent register.
415413
inout("r0") old.pair.hi => prev_hi,

0 commit comments

Comments
 (0)