diff --git a/library/stdarch/.github/workflows/main.yml b/library/stdarch/.github/workflows/main.yml index cadfc383000d..3f9744e19285 100644 --- a/library/stdarch/.github/workflows/main.yml +++ b/library/stdarch/.github/workflows/main.yml @@ -96,10 +96,11 @@ jobs: # Windows targets - x86_64-pc-windows-msvc + - i686-pc-windows-msvc # FIXME: Disassembly not implemented for the # following targets: # - x86_64-pc-windows-gnu: # - i686-pc-windows-gnu: - # - i686-pc-windows-msvc: + # - aarch64-pc-windows-msvc: include: - target: i686-unknown-linux-gnu @@ -137,6 +138,8 @@ jobs: os: macos-latest - target: x86_64-pc-windows-msvc os: windows-latest + - target: i686-pc-windows-msvc + os: windows-latest - target: i586-unknown-linux-gnu os: ubuntu-latest - target: x86_64-linux-android diff --git a/library/stdarch/ci/run.sh b/library/stdarch/ci/run.sh index 2b7e51be3d0b..4f4eaa1cfcd9 100755 --- a/library/stdarch/ci/run.sh +++ b/library/stdarch/ci/run.sh @@ -13,6 +13,8 @@ set -ex RUSTFLAGS="$RUSTFLAGS -D warnings " case ${TARGET} in + *-pc-windows-msvc) + ;; # On 32-bit use a static relocation model which avoids some extra # instructions when dealing with static data, notably allowing some # instruction assertion checks to pass below the 20 instruction limit. If diff --git a/library/stdarch/crates/core_arch/src/x86/sse.rs b/library/stdarch/crates/core_arch/src/x86/sse.rs index ba3efae3c9e8..a18964f3ff9e 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse.rs @@ -957,9 +957,15 @@ pub unsafe fn _mm_set_ps(a: f32, b: f32, c: f32, d: f32) -> __m128 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setr_ps) #[inline] #[target_feature(enable = "sse")] -#[cfg_attr(all(test, target_arch = "x86_64"), assert_instr(unpcklps))] -// On a 32-bit architecture it just copies the operands from the stack. -#[cfg_attr(all(test, target_arch = "x86"), assert_instr(movaps))] +#[cfg_attr( + all(test, any(target_os = "windows", target_arch = "x86_64")), + assert_instr(unpcklps) +)] +// On a 32-bit architecture on non-Windows it just copies the operands from the stack. +#[cfg_attr( + all(test, all(not(target_os = "windows"), target_arch = "x86")), + assert_instr(movaps) +)] #[stable(feature = "simd_x86", since = "1.27.0")] pub unsafe fn _mm_setr_ps(a: f32, b: f32, c: f32, d: f32) -> __m128 { __m128(a, b, c, d) diff --git a/library/stdarch/crates/core_arch/src/x86/sse2.rs b/library/stdarch/crates/core_arch/src/x86/sse2.rs index b6c19cdef4fc..947b196f26e5 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse2.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse2.rs @@ -2812,8 +2812,14 @@ pub unsafe fn _mm_loadu_pd(mem_addr: *const f64) -> __m128d { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_pd) #[inline] #[target_feature(enable = "sse2")] -#[cfg_attr(all(test, not(target_os = "windows")), assert_instr(shufps, imm8 = 1))] -#[cfg_attr(all(test, target_os = "windows"), assert_instr(shufpd, imm8 = 1))] +#[cfg_attr( + all(test, any(not(target_os = "windows"), target_arch = "x86")), + assert_instr(shufps, imm8 = 1) +)] +#[cfg_attr( + all(test, all(target_os = "windows", target_arch = "x86_64")), + assert_instr(shufpd, imm8 = 1) +)] #[rustc_args_required_const(2)] #[stable(feature = "simd_x86", since = "1.27.0")] pub unsafe fn _mm_shuffle_pd(a: __m128d, b: __m128d, imm8: i32) -> __m128d { @@ -2832,8 +2838,14 @@ pub unsafe fn _mm_shuffle_pd(a: __m128d, b: __m128d, imm8: i32) -> __m128d { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_move_sd) #[inline] #[target_feature(enable = "sse2")] -#[cfg_attr(all(test, not(target_os = "windows")), assert_instr(movsd))] -#[cfg_attr(all(test, target_os = "windows"), assert_instr(movlps))] +#[cfg_attr( + all(test, any(not(target_os = "windows"), target_arch = "x86")), + assert_instr(movsd) +)] +#[cfg_attr( + all(test, all(target_os = "windows", target_arch = "x86_64")), + assert_instr(movlps) +)] #[stable(feature = "simd_x86", since = "1.27.0")] pub unsafe fn _mm_move_sd(a: __m128d, b: __m128d) -> __m128d { _mm_setr_pd(simd_extract(b, 0), simd_extract(a, 1)) diff --git a/library/stdarch/crates/stdarch-test/src/disassembly.rs b/library/stdarch/crates/stdarch-test/src/disassembly.rs index d82b07d0a8cb..d82ec4c48fd5 100644 --- a/library/stdarch/crates/stdarch-test/src/disassembly.rs +++ b/library/stdarch/crates/stdarch-test/src/disassembly.rs @@ -32,62 +32,71 @@ fn normalize(mut symbol: &str) -> String { while symbol.starts_with('_') { symbol.remove(0); } + // Windows/x86 has a suffix such as @@4. + if let Some(idx) = symbol.find("@@") { + symbol = (&symbol[..idx]).to_string(); + } symbol } pub(crate) fn disassemble_myself() -> HashSet { let me = env::current_exe().expect("failed to get current exe"); - let disassembly = - if cfg!(target_arch = "x86_64") && cfg!(target_os = "windows") && cfg!(target_env = "msvc") - { - let mut cmd = cc::windows_registry::find("x86_64-pc-windows-msvc", "dumpbin.exe") - .expect("failed to find `dumpbin` tool"); - let output = cmd - .arg("/DISASM") - .arg(&me) - .output() - .expect("failed to execute dumpbin"); - println!( - "{}\n{}", - output.status, - String::from_utf8_lossy(&output.stderr) - ); - assert!(output.status.success()); - // Windows does not return valid UTF-8 output: - String::from_utf8_lossy(Vec::leak(output.stdout)) - } else if cfg!(target_os = "windows") { - panic!("disassembly unimplemented") - } else if cfg!(target_os = "macos") { - let output = Command::new("otool") - .arg("-vt") - .arg(&me) - .output() - .expect("failed to execute otool"); - println!( - "{}\n{}", - output.status, - String::from_utf8_lossy(&output.stderr) - ); - assert!(output.status.success()); - - String::from_utf8_lossy(Vec::leak(output.stdout)) + let disassembly = if cfg!(target_os = "windows") && cfg!(target_env = "msvc") { + let target = if cfg!(target_arch = "x86_64") { + "x86_64-pc-windows-msvc" + } else if cfg!(target_arch = "x86") { + "i686-pc-windows-msvc" } else { - let objdump = env::var("OBJDUMP").unwrap_or_else(|_| "objdump".to_string()); - let output = Command::new(objdump.clone()) - .arg("--disassemble") - .arg(&me) - .output() - .unwrap_or_else(|_| panic!("failed to execute objdump. OBJDUMP={}", objdump)); - println!( - "{}\n{}", - output.status, - String::from_utf8_lossy(&output.stderr) - ); - assert!(output.status.success()); - - String::from_utf8_lossy(Vec::leak(output.stdout)) + panic!("disassembly unimplemented") }; + let mut cmd = cc::windows_registry::find(target, "dumpbin.exe") + .expect("failed to find `dumpbin` tool"); + let output = cmd + .arg("/DISASM") + .arg(&me) + .output() + .expect("failed to execute dumpbin"); + println!( + "{}\n{}", + output.status, + String::from_utf8_lossy(&output.stderr) + ); + assert!(output.status.success()); + // Windows does not return valid UTF-8 output: + String::from_utf8_lossy(Vec::leak(output.stdout)) + } else if cfg!(target_os = "windows") { + panic!("disassembly unimplemented") + } else if cfg!(target_os = "macos") { + let output = Command::new("otool") + .arg("-vt") + .arg(&me) + .output() + .expect("failed to execute otool"); + println!( + "{}\n{}", + output.status, + String::from_utf8_lossy(&output.stderr) + ); + assert!(output.status.success()); + + String::from_utf8_lossy(Vec::leak(output.stdout)) + } else { + let objdump = env::var("OBJDUMP").unwrap_or_else(|_| "objdump".to_string()); + let output = Command::new(objdump.clone()) + .arg("--disassemble") + .arg(&me) + .output() + .unwrap_or_else(|_| panic!("failed to execute objdump. OBJDUMP={}", objdump)); + println!( + "{}\n{}", + output.status, + String::from_utf8_lossy(&output.stderr) + ); + assert!(output.status.success()); + + String::from_utf8_lossy(Vec::leak(output.stdout)) + }; parse(&disassembly) }