mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-31 04:57:19 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			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");
 | 
