Skip to content

Commit e0d996f

Browse files
dpaolielloAmanieu
authored andcommitted
Enable testing for AArch64 Windows
1 parent bb93f73 commit e0d996f

File tree

7 files changed

+224
-185
lines changed

7 files changed

+224
-185
lines changed

.github/workflows/main.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,10 @@ jobs:
9898
# Windows targets
9999
- x86_64-pc-windows-msvc
100100
- i686-pc-windows-msvc
101+
- aarch64-pc-windows-msvc
101102
# FIXME: Disassembly not implemented for the # following targets:
102103
# - x86_64-pc-windows-gnu:
103104
# - i686-pc-windows-gnu:
104-
# - aarch64-pc-windows-msvc:
105105

106106
include:
107107
- target: i686-unknown-linux-gnu
@@ -148,6 +148,9 @@ jobs:
148148
os: windows-latest
149149
- target: i686-pc-windows-msvc
150150
os: windows-latest
151+
- target: aarch64-pc-windows-msvc
152+
os: windows-latest
153+
norun: true
151154
- target: i586-unknown-linux-gnu
152155
os: ubuntu-latest
153156
- target: nvptx64-nvidia-cuda
@@ -192,14 +195,19 @@ jobs:
192195

193196
# Configure some env vars based on matrix configuration
194197
- run: echo "NORUN=1" >> $GITHUB_ENV
198+
shell: bash
195199
if: matrix.norun != '' || startsWith(matrix.target, 'thumb') || matrix.target == 'nvptx64-nvidia-cuda'
196200
- run: echo "STDARCH_TEST_EVERYTHING=1" >> $GITHUB_ENV
201+
shell: bash
197202
if: matrix.test_everything != ''
198203
- run: echo "RUSTFLAGS=${{ matrix.rustflags }}" >> $GITHUB_ENV
204+
shell: bash
199205
if: matrix.rustflags != ''
200206
- run: echo "STDARCH_DISABLE_ASSERT_INSTR=1" >> $GITHUB_ENV
207+
shell: bash
201208
if: matrix.disable_assert_instr != ''
202209
- run: echo "NOSTD=1" >> $GITHUB_ENV
210+
shell: bash
203211
if: startsWith(matrix.target, 'thumb') || matrix.target == 'nvptx64-nvidia-cuda'
204212

205213
# Windows & OSX go straight to `run.sh` ...

crates/core_arch/src/aarch64/neon/generated.rs

Lines changed: 164 additions & 164 deletions
Large diffs are not rendered by default.

crates/core_arch/src/aarch64/neon/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2036,7 +2036,8 @@ pub unsafe fn vmovq_n_f64(value: f64) -> float64x2_t {
20362036
/// Duplicate vector element to vector or scalar
20372037
#[inline]
20382038
#[target_feature(enable = "neon")]
2039-
#[cfg_attr(test, assert_instr(mov))]
2039+
#[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(mov))]
2040+
#[cfg_attr(all(test, target_env = "msvc"), assert_instr(dup))]
20402041
#[stable(feature = "neon_intrinsics", since = "1.59.0")]
20412042
pub unsafe fn vget_high_f64(a: float64x2_t) -> float64x1_t {
20422043
float64x1_t(simd_extract!(a, 1))

crates/core_arch/src/aarch64/tme.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,17 @@ pub const _TMFAILURE_INT: u64 = 1 << 23;
7676
#[unstable(feature = "stdarch_aarch64_tme", issue = "117216")]
7777
pub const _TMFAILURE_TRIVIAL: u64 = 1 << 24;
7878

79+
// NOTE: Tests for these instructions are disabled on MSVC as dumpbin doesn't
80+
// understand these instructions.
81+
7982
/// Starts a new transaction. When the transaction starts successfully the return value is 0.
8083
/// If the transaction fails, all state modifications are discarded and a cause of the failure
8184
/// is encoded in the return value.
8285
///
8386
/// [ARM TME Intrinsics](https://developer.arm.com/docs/101028/0010/transactional-memory-extension-tme-intrinsics).
8487
#[inline]
8588
#[target_feature(enable = "tme")]
86-
#[cfg_attr(test, assert_instr(tstart))]
89+
#[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(tstart))]
8790
#[unstable(feature = "stdarch_aarch64_tme", issue = "117216")]
8891
pub unsafe fn __tstart() -> u64 {
8992
aarch64_tstart()
@@ -96,7 +99,7 @@ pub unsafe fn __tstart() -> u64 {
9699
/// [ARM TME Intrinsics](https://developer.arm.com/docs/101028/0010/transactional-memory-extension-tme-intrinsics).
97100
#[inline]
98101
#[target_feature(enable = "tme")]
99-
#[cfg_attr(test, assert_instr(tcommit))]
102+
#[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(tcommit))]
100103
#[unstable(feature = "stdarch_aarch64_tme", issue = "117216")]
101104
pub unsafe fn __tcommit() {
102105
aarch64_tcommit()
@@ -107,7 +110,10 @@ pub unsafe fn __tcommit() {
107110
/// [ARM TME Intrinsics](https://developer.arm.com/docs/101028/0010/transactional-memory-extension-tme-intrinsics).
108111
#[inline]
109112
#[target_feature(enable = "tme")]
110-
#[cfg_attr(test, assert_instr(tcancel, IMM16 = 0x0))]
113+
#[cfg_attr(
114+
all(test, not(target_env = "msvc")),
115+
assert_instr(tcancel, IMM16 = 0x0)
116+
)]
111117
#[rustc_legacy_const_generics(0)]
112118
#[unstable(feature = "stdarch_aarch64_tme", issue = "117216")]
113119
pub unsafe fn __tcancel<const IMM16: u64>() {
@@ -121,7 +127,7 @@ pub unsafe fn __tcancel<const IMM16: u64>() {
121127
/// [ARM TME Intrinsics](https://developer.arm.com/docs/101028/0010/transactional-memory-extension-tme-intrinsics).
122128
#[inline]
123129
#[target_feature(enable = "tme")]
124-
#[cfg_attr(test, assert_instr(ttest))]
130+
#[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(ttest))]
125131
#[unstable(feature = "stdarch_aarch64_tme", issue = "117216")]
126132
pub unsafe fn __ttest() -> u64 {
127133
aarch64_ttest()

crates/stdarch-gen-arm/neon.spec

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7213,6 +7213,8 @@ validate -2.0, 3.0, 2.0, -2.0
72137213

72147214
aarch64 = frint32x
72157215
link-aarch64 = frint32x._EXT_
7216+
// dumpbin doesn't know how to disassembly this
7217+
assert_instr_cfg = not(target_env = "msvc")
72167218
generate float32x2_t, float32x4_t
72177219

72187220
// The float64x1_t form uses a different LLVM link and isn't supported by Clang
@@ -7254,6 +7256,8 @@ validate -1.0, 2.0, 1.0, -2.0
72547256

72557257
aarch64 = frint32z
72567258
link-aarch64 = frint32z._EXT_
7259+
// dumpbin doesn't know how to disassembly this
7260+
assert_instr_cfg = not(target_env = "msvc")
72577261
generate float32x2_t, float32x4_t
72587262

72597263
// The float64x1_t form uses a different LLVM link and isn't supported by Clang
@@ -7296,6 +7300,8 @@ validate -2.0, 3.0, 2.0, -2.0
72967300

72977301
aarch64 = frint64x
72987302
link-aarch64 = frint64x._EXT_
7303+
// dumpbin doesn't know how to disassembly this
7304+
assert_instr_cfg = not(target_env = "msvc")
72997305
generate float32x2_t, float32x4_t
73007306

73017307
// The float64x1_t form uses a different LLVM link and isn't supported by Clang
@@ -7337,6 +7343,8 @@ validate -1.0, 2.0, 1.0, -2.0
73377343

73387344
aarch64 = frint64z
73397345
link-aarch64 = frint64z._EXT_
7346+
// dumpbin doesn't know how to disassembly this
7347+
assert_instr_cfg = not(target_env = "msvc")
73407348
generate float32x2_t, float32x4_t
73417349

73427350
// The float64x1_t form uses a different LLVM link and isn't supported by Clang

crates/stdarch-gen-arm/src/main.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1273,6 +1273,7 @@ fn gen_aarch64(
12731273
fixed: &[String],
12741274
multi_fn: &[String],
12751275
fn_type: Fntype,
1276+
assert_instr_cfg: &Option<String>,
12761277
) -> (String, String) {
12771278
let name = match suffix {
12781279
Normal => format!("{current_name}{}", type_to_suffix(in_t[1])),
@@ -1627,12 +1628,17 @@ fn gen_aarch64(
16271628
}
16281629
}
16291630
};
1631+
let assert_instr_cfg = if let Some(assert_instr_cfg) = assert_instr_cfg {
1632+
format!("all(test, {assert_instr_cfg})")
1633+
} else {
1634+
"test".to_string()
1635+
};
16301636
let stable = target.stability(true);
16311637
let function = format!(
16321638
r#"
16331639
{function_doc}
16341640
#[inline]{target_feature}
1635-
#[cfg_attr(test, assert_instr({current_aarch64}{const_assert}))]{const_legacy}
1641+
#[cfg_attr({assert_instr_cfg}, assert_instr({current_aarch64}{const_assert}))]{const_legacy}
16361642
#[{stable}]
16371643
{fn_decl}{{
16381644
{call_params}
@@ -3223,6 +3229,7 @@ fn main() -> io::Result<()> {
32233229
let mut target: TargetFeature = Default;
32243230
let mut fn_type: Fntype = Fntype::Normal;
32253231
let mut separate = false;
3232+
let mut assert_instr_cfg = None;
32263233

32273234
//
32283235
// THIS FILE IS GENERATED FORM neon.spec DO NOT CHANGE IT MANUALLY
@@ -3402,6 +3409,8 @@ mod test {
34023409
},
34033410
_ => Default,
34043411
}
3412+
} else if let Some(line) = line.strip_prefix("assert_instr_cfg = ") {
3413+
assert_instr_cfg = Some(String::from(line));
34053414
} else if let Some(line) = line.strip_prefix("generate ") {
34063415
let types: Vec<String> = line
34073416
.split(',')
@@ -3489,6 +3498,7 @@ mod test {
34893498
&fixed,
34903499
&multi_fn,
34913500
fn_type,
3501+
&assert_instr_cfg,
34923502
);
34933503
out_aarch64.push_str(&function);
34943504
tests_aarch64.push_str(&test);

crates/stdarch-test/src/disassembly.rs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,15 @@ pub(crate) fn disassemble_myself() -> HashSet<Function> {
4848
"x86_64-pc-windows-msvc"
4949
} else if cfg!(target_arch = "x86") {
5050
"i686-pc-windows-msvc"
51+
} else if cfg!(target_arch = "aarch64") {
52+
"aarch64-pc-windows-msvc"
5153
} else {
5254
panic!("disassembly unimplemented")
5355
};
5456
let mut cmd = cc::windows_registry::find(target, "dumpbin.exe")
5557
.expect("failed to find `dumpbin` tool");
5658
let output = cmd
57-
.arg("/DISASM")
59+
.arg("/DISASM:NOBYTES")
5860
.arg(&me)
5961
.output()
6062
.expect("failed to execute dumpbin");
@@ -138,16 +140,12 @@ fn parse(output: &str) -> HashSet<Function> {
138140
let mut parts = if cfg!(target_env = "msvc") {
139141
// Each line looks like:
140142
//
141-
// > $addr: ab cd ef $instr..
142-
// > 00 12 # this line os optional
143-
if instruction.starts_with(" ") {
144-
continue;
145-
}
143+
// > $addr: $instr..
146144
instruction
147-
.split_whitespace()
145+
.split(&[' ', ','])
146+
.filter(|&x| !x.is_empty())
148147
.skip(1)
149-
.skip_while(|s| s.len() == 2 && usize::from_str_radix(s, 16).is_ok())
150-
.map(std::string::ToString::to_string)
148+
.map(str::to_lowercase)
151149
.skip_while(|s| *s == "lock") // skip x86-specific prefix
152150
.collect::<Vec<String>>()
153151
} else {
@@ -165,15 +163,19 @@ fn parse(output: &str) -> HashSet<Function> {
165163

166164
if cfg!(any(target_arch = "aarch64", target_arch = "arm64ec")) {
167165
// Normalize [us]shll.* ..., #0 instructions to the preferred form: [us]xtl.* ...
168-
// as LLVM objdump does not do that.
166+
// as neither LLVM objdump nor dumpbin does that.
169167
// See https://developer.arm.com/documentation/ddi0602/latest/SIMD-FP-Instructions/UXTL--UXTL2--Unsigned-extend-Long--an-alias-of-USHLL--USHLL2-
170168
// and https://developer.arm.com/documentation/ddi0602/latest/SIMD-FP-Instructions/SXTL--SXTL2--Signed-extend-Long--an-alias-of-SSHLL--SSHLL2-
171169
// for details.
170+
fn is_shll(instr: &str) -> bool {
171+
if cfg!(target_env = "msvc") {
172+
instr.starts_with("ushll") || instr.starts_with("sshll")
173+
} else {
174+
instr.starts_with("ushll.") || instr.starts_with("sshll.")
175+
}
176+
}
172177
match (parts.first(), parts.last()) {
173-
(Some(instr), Some(last_arg))
174-
if (instr.starts_with("ushll.") || instr.starts_with("sshll."))
175-
&& last_arg == "#0" =>
176-
{
178+
(Some(instr), Some(last_arg)) if is_shll(&instr) && last_arg == "#0" => {
177179
assert_eq!(parts.len(), 4);
178180
let mut new_parts = Vec::with_capacity(3);
179181
let new_instr = format!("{}{}{}", &instr[..1], "xtl", &instr[5..]);
@@ -182,6 +184,10 @@ fn parse(output: &str) -> HashSet<Function> {
182184
new_parts.push(parts[2][0..parts[2].len() - 1].to_owned()); // strip trailing comma
183185
parts = new_parts;
184186
}
187+
// dumpbin uses "ins" instead of "mov"
188+
(Some(instr), _) if cfg!(target_env = "msvc") && instr == "ins" => {
189+
parts[0] = "mov".to_string()
190+
}
185191
_ => {}
186192
};
187193
}

0 commit comments

Comments
 (0)