mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-11-03 22:49:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			206 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			206 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
// revisions: x86_64 i686
 | 
						|
// assembly-output: emit-asm
 | 
						|
// compile-flags: -O
 | 
						|
//[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
 | 
						|
 | 
						|
#![feature(no_core, lang_items, rustc_attrs)]
 | 
						|
#![crate_type = "rlib"]
 | 
						|
#![no_core]
 | 
						|
#![allow(asm_sub_register)]
 | 
						|
 | 
						|
#[rustc_builtin_macro]
 | 
						|
macro_rules! asm {
 | 
						|
    () => {};
 | 
						|
}
 | 
						|
#[rustc_builtin_macro]
 | 
						|
macro_rules! concat {
 | 
						|
    () => {};
 | 
						|
}
 | 
						|
#[rustc_builtin_macro]
 | 
						|
macro_rules! stringify {
 | 
						|
    () => {};
 | 
						|
}
 | 
						|
 | 
						|
#[lang = "sized"]
 | 
						|
trait Sized {}
 | 
						|
#[lang = "copy"]
 | 
						|
trait Copy {}
 | 
						|
 | 
						|
impl Copy for i32 {}
 | 
						|
 | 
						|
macro_rules! check {
 | 
						|
    ($func:ident $modifier:literal $reg:ident $mov:literal) => {
 | 
						|
        // -O and extern "C" guarantee that the selected register is always ax/xmm0
 | 
						|
        #[no_mangle]
 | 
						|
        pub unsafe extern "C" fn $func() -> i32 {
 | 
						|
            // Hack to avoid function merging
 | 
						|
            extern "Rust" {
 | 
						|
                fn dont_merge(s: &str);
 | 
						|
            }
 | 
						|
            dont_merge(stringify!($func));
 | 
						|
 | 
						|
            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");
 |