diff options
Diffstat (limited to 'tests/codegen/asm')
| -rw-r--r-- | tests/codegen/asm/arm64ec-clobbers.rs | 36 | ||||
| -rw-r--r-- | tests/codegen/asm/foo.s | 3 | ||||
| -rw-r--r-- | tests/codegen/asm/global_asm.rs | 28 | ||||
| -rw-r--r-- | tests/codegen/asm/global_asm_include.rs | 21 | ||||
| -rw-r--r-- | tests/codegen/asm/global_asm_x2.rs | 47 | ||||
| -rw-r--r-- | tests/codegen/asm/goto.rs | 51 | ||||
| -rw-r--r-- | tests/codegen/asm/may_unwind.rs | 39 | ||||
| -rw-r--r-- | tests/codegen/asm/maybe-uninit.rs | 27 | ||||
| -rw-r--r-- | tests/codegen/asm/msp430-clobbers.rs | 36 | ||||
| -rw-r--r-- | tests/codegen/asm/multiple-options.rs | 54 | ||||
| -rw-r--r-- | tests/codegen/asm/options.rs | 104 | ||||
| -rw-r--r-- | tests/codegen/asm/powerpc-clobbers.rs | 47 | ||||
| -rw-r--r-- | tests/codegen/asm/s390x-clobbers.rs | 50 | ||||
| -rw-r--r-- | tests/codegen/asm/sanitize-llvm.rs | 30 | ||||
| -rw-r--r-- | tests/codegen/asm/x86-clobber_abi.rs | 36 | ||||
| -rw-r--r-- | tests/codegen/asm/x86-clobbers.rs | 20 | ||||
| -rw-r--r-- | tests/codegen/asm/x86-target-clobbers.rs | 29 |
17 files changed, 658 insertions, 0 deletions
diff --git a/tests/codegen/asm/arm64ec-clobbers.rs b/tests/codegen/asm/arm64ec-clobbers.rs new file mode 100644 index 00000000000..2ec61907947 --- /dev/null +++ b/tests/codegen/asm/arm64ec-clobbers.rs @@ -0,0 +1,36 @@ +//@ assembly-output: emit-asm +//@ compile-flags: --target arm64ec-pc-windows-msvc +//@ needs-llvm-components: aarch64 + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +// CHECK-LABEL: @cc_clobber +// CHECK: call void asm sideeffect "", "~{cc}"() +#[no_mangle] +pub unsafe fn cc_clobber() { + asm!("", options(nostack, nomem)); +} + +// CHECK-LABEL: @no_clobber +// CHECK: call void asm sideeffect "", ""() +#[no_mangle] +pub unsafe fn no_clobber() { + asm!("", options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @clobber_abi +// CHECK: asm sideeffect "", "={w0},={w1},={w2},={w3},={w4},={w5},={w6},={w7},={w8},={w9},={w10},={w11},={w12},={w15},={w16},={w17},={w30},={q0},={q1},={q2},={q3},={q4},={q5},={q6},={q7},={q8},={q9},={q10},={q11},={q12},={q13},={q14},={q15}"() +#[no_mangle] +pub unsafe fn clobber_abi() { + asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); +} diff --git a/tests/codegen/asm/foo.s b/tests/codegen/asm/foo.s new file mode 100644 index 00000000000..304d82aa0c6 --- /dev/null +++ b/tests/codegen/asm/foo.s @@ -0,0 +1,3 @@ +.global foo +foo: + jmp baz diff --git a/tests/codegen/asm/global_asm.rs b/tests/codegen/asm/global_asm.rs new file mode 100644 index 00000000000..32075daa3cf --- /dev/null +++ b/tests/codegen/asm/global_asm.rs @@ -0,0 +1,28 @@ +//@ revisions: x32 x64 +//@[x32] only-x86 +//@[x64] only-x86_64 +//@ compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] + +use std::arch::global_asm; + +// CHECK-LABEL: foo +// CHECK: module asm +// this regex will capture the correct unconditional branch inst. +// CHECK: module asm "{{[[:space:]]+}}jmp baz" +global_asm!( + r#" + .global foo +foo: + jmp baz +"# +); + +extern "C" { + fn foo(); +} + +// CHECK-LABEL: @baz +#[no_mangle] +pub unsafe extern "C" fn baz() {} diff --git a/tests/codegen/asm/global_asm_include.rs b/tests/codegen/asm/global_asm_include.rs new file mode 100644 index 00000000000..98be9c3e333 --- /dev/null +++ b/tests/codegen/asm/global_asm_include.rs @@ -0,0 +1,21 @@ +//@ revisions: x32 x64 +//@[x32] only-x86 +//@[x64] only-x86_64 +//@ compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] + +use std::arch::global_asm; + +// CHECK-LABEL: foo +// CHECK: module asm +// CHECK: module asm "{{[[:space:]]+}}jmp baz" +global_asm!(include_str!("foo.s")); + +extern "C" { + fn foo(); +} + +// CHECK-LABEL: @baz +#[no_mangle] +pub unsafe extern "C" fn baz() {} diff --git a/tests/codegen/asm/global_asm_x2.rs b/tests/codegen/asm/global_asm_x2.rs new file mode 100644 index 00000000000..9e3a00f0680 --- /dev/null +++ b/tests/codegen/asm/global_asm_x2.rs @@ -0,0 +1,47 @@ +//@ revisions: x32 x64 +//@[x32] only-x86 +//@[x64] only-x86_64 +//@ compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] +#![no_std] + +use core::arch::global_asm; + +// CHECK-LABEL: foo +// CHECK: module asm +// CHECK: module asm "{{[[:space:]]+}}jmp baz" +// any other global_asm will be appended to this first block, so: +// CHECK-LABEL: bar +// CHECK: module asm "{{[[:space:]]+}}jmp quux" +global_asm!( + r#" + .global foo +foo: + jmp baz +"# +); + +extern "C" { + fn foo(); +} + +// CHECK-LABEL: @baz +#[no_mangle] +pub unsafe extern "C" fn baz() {} + +// no checks here; this has been appended to the first occurrence +global_asm!( + r#" + .global bar +bar: + jmp quux +"# +); + +extern "C" { + fn bar(); +} + +#[no_mangle] +pub unsafe extern "C" fn quux() {} diff --git a/tests/codegen/asm/goto.rs b/tests/codegen/asm/goto.rs new file mode 100644 index 00000000000..e522d0da5b4 --- /dev/null +++ b/tests/codegen/asm/goto.rs @@ -0,0 +1,51 @@ +//@ compile-flags: -O +//@ only-x86_64 + +#![crate_type = "rlib"] +#![feature(asm_goto)] + +use std::arch::asm; + +#[no_mangle] +pub extern "C" fn panicky() {} + +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) { + println!(); + } +} + +// CHECK-LABEL: @asm_goto +#[no_mangle] +pub unsafe fn asm_goto() { + // CHECK: callbr void asm sideeffect alignstack inteldialect " + // CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]] + asm!("jmp {}", label {}); +} + +// CHECK-LABEL: @asm_goto_with_outputs +#[no_mangle] +pub unsafe fn asm_goto_with_outputs() -> u64 { + let out: u64; + // CHECK: [[RES:%[0-9]+]] = callbr i64 asm sideeffect alignstack inteldialect " + // CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]] + asm!("{} /* {} */", out(reg) out, label { return 1; }); + // CHECK: [[JUMPBB]]: + // CHECK-NEXT: [[RET:%.+]] = phi i64 [ [[RES]], %[[FALLTHROUGHBB]] ], [ 1, %start ] + // CHECK-NEXT: ret i64 [[RET]] + out +} + +// CHECK-LABEL: @asm_goto_noreturn +#[no_mangle] +pub unsafe fn asm_goto_noreturn() -> u64 { + let out: u64; + // CHECK: callbr void asm sideeffect alignstack inteldialect " + // CHECK-NEXT: to label %unreachable [label %[[JUMPBB:[a-b0-9]+]]] + asm!("jmp {}", label { return 1; }, options(noreturn)); + // CHECK: [[JUMPBB]]: + // CHECK-NEXT: ret i64 1 + out +} diff --git a/tests/codegen/asm/may_unwind.rs b/tests/codegen/asm/may_unwind.rs new file mode 100644 index 00000000000..be66b3975ff --- /dev/null +++ b/tests/codegen/asm/may_unwind.rs @@ -0,0 +1,39 @@ +//@ compile-flags: -O +//@ only-x86_64 + +#![crate_type = "rlib"] +#![feature(asm_unwind)] + +use std::arch::asm; + +#[no_mangle] +pub extern "C" fn panicky() {} + +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) { + println!(); + } +} + +// CHECK-LABEL: @asm_may_unwind +#[no_mangle] +pub unsafe fn asm_may_unwind() { + let _m = Foo; + // CHECK: invoke void asm sideeffect alignstack inteldialect unwind "" + asm!("", options(may_unwind)); +} + +// CHECK-LABEL: @asm_with_result_may_unwind +#[no_mangle] +pub unsafe fn asm_with_result_may_unwind() -> u64 { + let _m = Foo; + let res: u64; + // CHECK: [[RES:%[0-9]+]] = invoke i64 asm sideeffect alignstack inteldialect unwind + // CHECK-NEXT: to label %[[NORMALBB:[a-b0-9]+]] + asm!("mov {}, 1", out(reg) res, options(may_unwind)); + // CHECK: [[NORMALBB]]: + // CHECK: ret i64 [[RES:%[0-9]+]] + res +} diff --git a/tests/codegen/asm/maybe-uninit.rs b/tests/codegen/asm/maybe-uninit.rs new file mode 100644 index 00000000000..55813c35a46 --- /dev/null +++ b/tests/codegen/asm/maybe-uninit.rs @@ -0,0 +1,27 @@ +//@ compile-flags: -O +//@ only-x86_64 + +#![crate_type = "rlib"] +#![allow(asm_sub_register)] + +use std::arch::asm; +use std::mem::MaybeUninit; + +// CHECK-LABEL: @int +#[no_mangle] +pub unsafe fn int(x: MaybeUninit<i32>) -> MaybeUninit<i32> { + let y: MaybeUninit<i32>; + asm!("/*{}{}*/", in(reg) x, out(reg) y); + y +} + +// CHECK-LABEL: @inout +#[no_mangle] +pub unsafe fn inout(mut x: i32) -> MaybeUninit<u32> { + let mut y: MaybeUninit<u32>; + asm!("/*{}*/", inout(reg) x => y); + asm!("/*{}*/", inout(reg) y => x); + asm!("/*{}*/", inlateout(reg) x => y); + asm!("/*{}*/", inlateout(reg) y => x); + y +} diff --git a/tests/codegen/asm/msp430-clobbers.rs b/tests/codegen/asm/msp430-clobbers.rs new file mode 100644 index 00000000000..c00c04f3088 --- /dev/null +++ b/tests/codegen/asm/msp430-clobbers.rs @@ -0,0 +1,36 @@ +//@ assembly-output: emit-asm +//@ compile-flags: --target msp430-none-elf +//@ needs-llvm-components: msp430 + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +// CHECK-LABEL: @sr_clobber +// CHECK: call void asm sideeffect "", "~{sr}"() +#[no_mangle] +pub unsafe fn sr_clobber() { + asm!("", options(nostack, nomem)); +} + +// CHECK-LABEL: @no_clobber +// CHECK: call void asm sideeffect "", ""() +#[no_mangle] +pub unsafe fn no_clobber() { + asm!("", options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @clobber_abi +// CHECK: asm sideeffect "", "={r11},={r12},={r13},={r14},={r15}"() +#[no_mangle] +pub unsafe fn clobber_abi() { + asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); +} diff --git a/tests/codegen/asm/multiple-options.rs b/tests/codegen/asm/multiple-options.rs new file mode 100644 index 00000000000..1ee295e32c9 --- /dev/null +++ b/tests/codegen/asm/multiple-options.rs @@ -0,0 +1,54 @@ +//@ compile-flags: -O +//@ only-x86_64 + +#![crate_type = "rlib"] + +use std::arch::asm; + +// CHECK-LABEL: @pure +// CHECK-NOT: asm +// CHECK: ret void +#[no_mangle] +pub unsafe fn pure(x: i32) { + let y: i32; + asm!("", out("ax") y, in("cx") x, options(pure), options(nomem)); +} + +pub static mut VAR: i32 = 0; +pub static mut DUMMY_OUTPUT: i32 = 0; + +// CHECK-LABEL: @readonly +// CHECK: call i32 asm +// CHECK: ret i32 1 +#[no_mangle] +pub unsafe fn readonly() -> i32 { + VAR = 1; + asm!("", out("ax") DUMMY_OUTPUT, options(pure), options(readonly)); + VAR +} + +// CHECK-LABEL: @nomem +// CHECK-NOT: store +// CHECK: call i32 asm +// CHECK: store +// CHECK: ret i32 2 +#[no_mangle] +pub unsafe fn nomem() -> i32 { + VAR = 1; + asm!("", out("ax") DUMMY_OUTPUT, options(pure), options(nomem)); + VAR = 2; + VAR +} + +// CHECK-LABEL: @not_nomem +// CHECK: store +// CHECK: call i32 asm +// CHECK: store +// CHECK: ret i32 2 +#[no_mangle] +pub unsafe fn not_nomem() -> i32 { + VAR = 1; + asm!("", out("ax") DUMMY_OUTPUT, options(pure), options(readonly)); + VAR = 2; + VAR +} diff --git a/tests/codegen/asm/options.rs b/tests/codegen/asm/options.rs new file mode 100644 index 00000000000..96a72c2f5ae --- /dev/null +++ b/tests/codegen/asm/options.rs @@ -0,0 +1,104 @@ +//@ compile-flags: -O +//@ only-x86_64 + +#![crate_type = "rlib"] + +use std::arch::asm; + +// CHECK-LABEL: @pure +// CHECK-NOT: asm +// CHECK: ret void +#[no_mangle] +pub unsafe fn pure(x: i32) { + let y: i32; + asm!("", out("ax") y, in("cx") x, options(pure, nomem)); +} + +// CHECK-LABEL: @noreturn +// CHECK: call void asm +// CHECK-NEXT: unreachable +#[no_mangle] +pub unsafe fn noreturn() { + asm!("", options(noreturn)); +} + +pub static mut VAR: i32 = 0; +pub static mut DUMMY_OUTPUT: i32 = 0; + +// CHECK-LABEL: @readonly +// CHECK: call i32 asm +// CHECK: ret i32 1 +#[no_mangle] +pub unsafe fn readonly() -> i32 { + VAR = 1; + asm!("", out("ax") DUMMY_OUTPUT, options(pure, readonly)); + VAR +} + +// CHECK-LABEL: @not_readonly +// CHECK: call i32 asm +// CHECK: ret i32 % +#[no_mangle] +pub unsafe fn not_readonly() -> i32 { + VAR = 1; + asm!("", out("ax") DUMMY_OUTPUT, options()); + VAR +} + +// CHECK-LABEL: @nomem +// CHECK-NOT: store +// CHECK: call i32 asm +// CHECK: store +// CHECK: ret i32 2 +#[no_mangle] +pub unsafe fn nomem() -> i32 { + VAR = 1; + asm!("", out("ax") DUMMY_OUTPUT, options(pure, nomem)); + VAR = 2; + VAR +} + +// CHECK-LABEL: @nomem_nopure +// CHECK-NOT: store +// CHECK: call i32 asm +// CHECK: store +// CHECK: ret i32 2 +#[no_mangle] +pub unsafe fn nomem_nopure() -> i32 { + VAR = 1; + asm!("", out("ax") DUMMY_OUTPUT, options(nomem)); + VAR = 2; + VAR +} + +// CHECK-LABEL: @not_nomem +// CHECK: store +// CHECK: call i32 asm +// CHECK: store +// CHECK: ret i32 2 +#[no_mangle] +pub unsafe fn not_nomem() -> i32 { + VAR = 1; + asm!("", out("ax") DUMMY_OUTPUT, options(pure, readonly)); + VAR = 2; + VAR +} + +// CHECK-LABEL: @dont_remove_nonpure +// CHECK: call void asm +// CHECK: call void asm +// CHECK: call void asm +// CHECK: ret void +#[no_mangle] +pub unsafe fn dont_remove_nonpure() { + asm!("", options()); + asm!("", options(nomem)); + asm!("", options(readonly)); +} + +// CHECK-LABEL: @raw +// CHECK: call void asm sideeffect inteldialect "{} {}", ""() +#[no_mangle] +pub unsafe fn raw() { + asm!("{} {}", options(nostack, nomem, preserves_flags, raw)); +} diff --git a/tests/codegen/asm/powerpc-clobbers.rs b/tests/codegen/asm/powerpc-clobbers.rs new file mode 100644 index 00000000000..0be1b66bd99 --- /dev/null +++ b/tests/codegen/asm/powerpc-clobbers.rs @@ -0,0 +1,47 @@ +//@ revisions: powerpc powerpc64 powerpc64le +//@[powerpc] compile-flags: --target powerpc-unknown-linux-gnu +//@[powerpc] needs-llvm-components: powerpc +//@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu +//@[powerpc64] needs-llvm-components: powerpc +//@[powerpc64le] compile-flags: --target powerpc64le-unknown-linux-gnu +//@[powerpc64le] needs-llvm-components: powerpc + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +// CHECK-LABEL: @cr_clobber +// CHECK: call void asm sideeffect "", "~{cr}"() +#[no_mangle] +pub unsafe fn cr_clobber() { + asm!("", out("cr") _, options(nostack, nomem)); +} + +// CHECK-LABEL: @cr0_clobber +// CHECK: call void asm sideeffect "", "~{cr0}"() +#[no_mangle] +pub unsafe fn cr0_clobber() { + asm!("", out("cr0") _, options(nostack, nomem)); +} + +// CHECK-LABEL: @cr5_clobber +// CHECK: call void asm sideeffect "", "~{cr5}"() +#[no_mangle] +pub unsafe fn cr5_clobber() { + asm!("", out("cr5") _, options(nostack, nomem)); +} + +// CHECK-LABEL: @xer_clobber +// CHECK: call void asm sideeffect "", "~{xer}"() +#[no_mangle] +pub unsafe fn xer_clobber() { + asm!("", out("xer") _, options(nostack, nomem)); +} diff --git a/tests/codegen/asm/s390x-clobbers.rs b/tests/codegen/asm/s390x-clobbers.rs new file mode 100644 index 00000000000..45f72206bdf --- /dev/null +++ b/tests/codegen/asm/s390x-clobbers.rs @@ -0,0 +1,50 @@ +//@ revisions: s390x +//@[s390x] compile-flags: --target s390x-unknown-linux-gnu +//@[s390x] needs-llvm-components: systemz + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +// CHECK-LABEL: @cc_clobber +// CHECK: call void asm sideeffect "", "~{cc}"() +#[no_mangle] +pub unsafe fn cc_clobber() { + asm!("", options(nostack, nomem)); +} + +// CHECK-LABEL: @no_clobber +// CHECK: call void asm sideeffect "", ""() +#[no_mangle] +pub unsafe fn no_clobber() { + asm!("", options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @a2_clobber +// CHECK: call void asm sideeffect "", "~{a2}"() +#[no_mangle] +pub unsafe fn a2_clobber() { + asm!("", out("a2") _, options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @v0_clobber +// CHECK: call void asm sideeffect "", "~{v0}"() +#[no_mangle] +pub unsafe fn v0_clobber() { + asm!("", out("v0") _, options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @clobber_abi +// CHECK: asm sideeffect "", "={r0},={r1},={r2},={r3},={r4},={r5},={r14},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31},~{a2},~{a3},~{a4},~{a5},~{a6},~{a7},~{a8},~{a9},~{a10},~{a11},~{a12},~{a13},~{a14},~{a15}"() +#[no_mangle] +pub unsafe fn clobber_abi() { + asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); +} diff --git a/tests/codegen/asm/sanitize-llvm.rs b/tests/codegen/asm/sanitize-llvm.rs new file mode 100644 index 00000000000..fb332f9a0f3 --- /dev/null +++ b/tests/codegen/asm/sanitize-llvm.rs @@ -0,0 +1,30 @@ +// FIXME(nagisa): remove the flags below once all targets support `asm!`. +//@ compile-flags: --target x86_64-unknown-linux-gnu -Copt-level=0 +//@ needs-llvm-components: x86 + +// Verify we sanitize the special tokens for the LLVM inline-assembly, ensuring people won't +// inadvertently rely on the LLVM-specific syntax and features. +#![no_core] +#![feature(no_core, lang_items, rustc_attrs)] +#![crate_type = "rlib"] +#![allow(named_asm_labels)] + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} + +pub unsafe fn we_escape_dollar_signs() { + // CHECK: call void asm sideeffect alignstack inteldialect "banana$$:" + asm!(r"banana$:",) +} + +pub unsafe fn we_escape_escapes_too() { + // CHECK: call void asm sideeffect alignstack inteldialect "banana\{{(\\|5C)}}36:" + asm!(r"banana\36:",) +} diff --git a/tests/codegen/asm/x86-clobber_abi.rs b/tests/codegen/asm/x86-clobber_abi.rs new file mode 100644 index 00000000000..cc563474bf8 --- /dev/null +++ b/tests/codegen/asm/x86-clobber_abi.rs @@ -0,0 +1,36 @@ +//@ compile-flags: -O +//@ only-x86_64 + +#![crate_type = "rlib"] + +use std::arch::asm; + +// CHECK-LABEL: @clobber_sysv64 +// CHECK: ={ax},={cx},={dx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{tmm0},~{tmm1},~{tmm2},~{tmm3},~{tmm4},~{tmm5},~{tmm6},~{tmm7},~{dirflag},~{fpsr},~{flags},~{memory} +#[no_mangle] +pub unsafe fn clobber_sysv64() { + asm!("", clobber_abi("sysv64")); +} + +// CHECK-LABEL: @clobber_win64 +// CHECK: ={ax},={cx},={dx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{tmm0},~{tmm1},~{tmm2},~{tmm3},~{tmm4},~{tmm5},~{tmm6},~{tmm7},~{dirflag},~{fpsr},~{flags},~{memory} +#[no_mangle] +pub unsafe fn clobber_win64() { + asm!("", clobber_abi("win64")); +} + +// CHECK-LABEL: @clobber_sysv64 +// CHECK: =&{dx},={ax},={cx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{tmm0},~{tmm1},~{tmm2},~{tmm3},~{tmm4},~{tmm5},~{tmm6},~{tmm7},~{dirflag},~{fpsr},~{flags},~{memory} +#[no_mangle] +pub unsafe fn clobber_sysv64_edx() { + let foo: i32; + asm!("", out("edx") foo, clobber_abi("sysv64")); +} + +// CHECK-LABEL: @clobber_win64 +// CHECK: =&{dx},={ax},={cx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{tmm0},~{tmm1},~{tmm2},~{tmm3},~{tmm4},~{tmm5},~{tmm6},~{tmm7},~{dirflag},~{fpsr},~{flags},~{memory} +#[no_mangle] +pub unsafe fn clobber_win64_edx() { + let foo: i32; + asm!("", out("edx") foo, clobber_abi("win64")); +} diff --git a/tests/codegen/asm/x86-clobbers.rs b/tests/codegen/asm/x86-clobbers.rs new file mode 100644 index 00000000000..4094db74134 --- /dev/null +++ b/tests/codegen/asm/x86-clobbers.rs @@ -0,0 +1,20 @@ +//@ compile-flags: -O +//@ only-x86_64 + +#![crate_type = "rlib"] + +use std::arch::asm; + +// CHECK-LABEL: @x87_clobber +// CHECK: ~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)} +#[no_mangle] +pub unsafe fn x87_clobber() { + asm!("foo", out("st") _); +} + +// CHECK-LABEL: @mmx_clobber +// CHECK: ~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)} +#[no_mangle] +pub unsafe fn mmx_clobber() { + asm!("bar", out("mm0") _, out("mm1") _); +} diff --git a/tests/codegen/asm/x86-target-clobbers.rs b/tests/codegen/asm/x86-target-clobbers.rs new file mode 100644 index 00000000000..119372491ff --- /dev/null +++ b/tests/codegen/asm/x86-target-clobbers.rs @@ -0,0 +1,29 @@ +//@ only-x86_64 +//@ revisions: base avx512 +//@ [avx512]compile-flags: -C target-feature=+avx512f + +#![crate_type = "rlib"] + +use std::arch::asm; + +// CHECK-LABEL: @amx_clobber +// base: call void asm sideeffect inteldialect "", "~{tmm0}"() +#[no_mangle] +pub unsafe fn amx_clobber() { + asm!("", out("tmm0") _, options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @avx512_clobber +// base: call void asm sideeffect inteldialect "", "~{xmm31}"() +// avx512: call float asm sideeffect inteldialect "", "=&{xmm31}"() +#[no_mangle] +pub unsafe fn avx512_clobber() { + asm!("", out("zmm31") _, options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @eax_clobber +// CHECK: call i32 asm sideeffect inteldialect "", "=&{ax}"() +#[no_mangle] +pub unsafe fn eax_clobber() { + asm!("", out("eax") _, options(nostack, nomem, preserves_flags)); +} |
