mirror of https://github.com/rust-lang/rust.git
185 lines
4.1 KiB
Rust
185 lines
4.1 KiB
Rust
//@ add-core-stubs
|
|
//@ revisions: x86_64 i686
|
|
//@ assembly-output: emit-asm
|
|
//@ compile-flags: -Copt-level=3 -C panic=abort
|
|
//@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
|
|
//@[x86_64] needs-llvm-components: x86
|
|
//@[i686] compile-flags: --target i686-unknown-linux-gnu
|
|
//@[i686] needs-llvm-components: x86
|
|
//@ compile-flags: -C llvm-args=--x86-asm-syntax=intel
|
|
//@ compile-flags: -C target-feature=+avx512bw
|
|
//@ compile-flags: -Zmerge-functions=disabled
|
|
|
|
#![feature(no_core)]
|
|
#![crate_type = "rlib"]
|
|
#![no_core]
|
|
#![allow(asm_sub_register)]
|
|
|
|
extern crate minicore;
|
|
use minicore::*;
|
|
|
|
macro_rules! check {
|
|
($func:ident $modifier:literal $reg:ident $mov:literal) => {
|
|
// -Copt-level=3 and extern "C" guarantee that the selected register is always ax/xmm0
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn $func() -> i32 {
|
|
let y;
|
|
asm!(concat!($mov, " {0:", $modifier, "}, {0:", $modifier, "}"), out($reg) y);
|
|
y
|
|
}
|
|
};
|
|
}
|
|
|
|
// CHECK-LABEL: reg:
|
|
// CHECK: #APP
|
|
// x86_64: mov rax, rax
|
|
// i686: mov eax, eax
|
|
// CHECK: #NO_APP
|
|
check!(reg "" reg "mov");
|
|
|
|
// x86_64-LABEL: reg_l:
|
|
// x86_64: #APP
|
|
// x86_64: mov al, al
|
|
// x86_64: #NO_APP
|
|
#[cfg(x86_64)]
|
|
check!(reg_l "l" reg "mov");
|
|
|
|
// CHECK-LABEL: reg_x:
|
|
// CHECK: #APP
|
|
// CHECK: mov ax, ax
|
|
// CHECK: #NO_APP
|
|
check!(reg_x "x" reg "mov");
|
|
|
|
// CHECK-LABEL: reg_e:
|
|
// CHECK: #APP
|
|
// CHECK: mov eax, eax
|
|
// CHECK: #NO_APP
|
|
check!(reg_e "e" reg "mov");
|
|
|
|
// x86_64-LABEL: reg_r:
|
|
// x86_64: #APP
|
|
// x86_64: mov rax, rax
|
|
// x86_64: #NO_APP
|
|
#[cfg(x86_64)]
|
|
check!(reg_r "r" reg "mov");
|
|
|
|
// CHECK-LABEL: reg_abcd:
|
|
// CHECK: #APP
|
|
// x86_64: mov rax, rax
|
|
// i686: mov eax, eax
|
|
// CHECK: #NO_APP
|
|
check!(reg_abcd "" reg_abcd "mov");
|
|
|
|
// CHECK-LABEL: reg_abcd_l:
|
|
// CHECK: #APP
|
|
// CHECK: mov al, al
|
|
// CHECK: #NO_APP
|
|
check!(reg_abcd_l "l" reg_abcd "mov");
|
|
|
|
// CHECK-LABEL: reg_abcd_h:
|
|
// CHECK: #APP
|
|
// CHECK: mov ah, ah
|
|
// CHECK: #NO_APP
|
|
check!(reg_abcd_h "h" reg_abcd "mov");
|
|
|
|
// CHECK-LABEL: reg_abcd_x:
|
|
// CHECK: #APP
|
|
// CHECK: mov ax, ax
|
|
// CHECK: #NO_APP
|
|
check!(reg_abcd_x "x" reg_abcd "mov");
|
|
|
|
// CHECK-LABEL: reg_abcd_e:
|
|
// CHECK: #APP
|
|
// CHECK: mov eax, eax
|
|
// CHECK: #NO_APP
|
|
check!(reg_abcd_e "e" reg_abcd "mov");
|
|
|
|
// x86_64-LABEL: reg_abcd_r:
|
|
// x86_64: #APP
|
|
// x86_64: mov rax, rax
|
|
// x86_64: #NO_APP
|
|
#[cfg(x86_64)]
|
|
check!(reg_abcd_r "r" reg_abcd "mov");
|
|
|
|
// CHECK-LABEL: xmm_reg
|
|
// CHECK: #APP
|
|
// CHECK: movaps xmm0, xmm0
|
|
// CHECK: #NO_APP
|
|
check!(xmm_reg "" xmm_reg "movaps");
|
|
|
|
// CHECK-LABEL: xmm_reg_x
|
|
// CHECK: #APP
|
|
// CHECK: movaps xmm0, xmm0
|
|
// CHECK: #NO_APP
|
|
check!(xmm_reg_x "x" xmm_reg "movaps");
|
|
|
|
// CHECK-LABEL: xmm_reg_y
|
|
// CHECK: #APP
|
|
// CHECK: vmovaps ymm0, ymm0
|
|
// CHECK: #NO_APP
|
|
check!(xmm_reg_y "y" xmm_reg "vmovaps");
|
|
|
|
// CHECK-LABEL: xmm_reg_z
|
|
// CHECK: #APP
|
|
// CHECK: vmovaps zmm0, zmm0
|
|
// CHECK: #NO_APP
|
|
check!(xmm_reg_z "z" xmm_reg "vmovaps");
|
|
|
|
// CHECK-LABEL: ymm_reg
|
|
// CHECK: #APP
|
|
// CHECK: movaps ymm0, ymm0
|
|
// CHECK: #NO_APP
|
|
check!(ymm_reg "" ymm_reg "vmovaps");
|
|
|
|
// CHECK-LABEL: ymm_reg_x
|
|
// CHECK: #APP
|
|
// CHECK: movaps xmm0, xmm0
|
|
// CHECK: #NO_APP
|
|
check!(ymm_reg_x "x" ymm_reg "movaps");
|
|
|
|
// CHECK-LABEL: ymm_reg_y
|
|
// CHECK: #APP
|
|
// CHECK: vmovaps ymm0, ymm0
|
|
// CHECK: #NO_APP
|
|
check!(ymm_reg_y "y" ymm_reg "vmovaps");
|
|
|
|
// CHECK-LABEL: ymm_reg_z
|
|
// CHECK: #APP
|
|
// CHECK: vmovaps zmm0, zmm0
|
|
// CHECK: #NO_APP
|
|
check!(ymm_reg_z "z" ymm_reg "vmovaps");
|
|
|
|
// CHECK-LABEL: zmm_reg
|
|
// CHECK: #APP
|
|
// CHECK: movaps zmm0, zmm0
|
|
// CHECK: #NO_APP
|
|
check!(zmm_reg "" zmm_reg "vmovaps");
|
|
|
|
// CHECK-LABEL: zmm_reg_x
|
|
// CHECK: #APP
|
|
// CHECK: movaps xmm0, xmm0
|
|
// CHECK: #NO_APP
|
|
check!(zmm_reg_x "x" zmm_reg "movaps");
|
|
|
|
// CHECK-LABEL: zmm_reg_y
|
|
// CHECK: #APP
|
|
// CHECK: vmovaps ymm0, ymm0
|
|
// CHECK: #NO_APP
|
|
check!(zmm_reg_y "y" zmm_reg "vmovaps");
|
|
|
|
// CHECK-LABEL: zmm_reg_z
|
|
// CHECK: #APP
|
|
// CHECK: vmovaps zmm0, zmm0
|
|
// CHECK: #NO_APP
|
|
check!(zmm_reg_z "z" zmm_reg "vmovaps");
|
|
|
|
// Note: we don't have any way of ensuring that k1 is actually the register
|
|
// chosen by the register allocator, so this check may fail if a different
|
|
// register is chosen.
|
|
|
|
// CHECK-LABEL: kreg:
|
|
// CHECK: #APP
|
|
// CHECK: kmovb k1, k1
|
|
// CHECK: #NO_APP
|
|
check!(kreg "" kreg "kmovb");
|