diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index 2e8cd934eb298..20d91b80e8c52 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -592,7 +592,7 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg0) => unimplemented!(), InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => unimplemented!(), InlineAsmRegClass::X86( - X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg, + X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg | X86InlineAsmRegClass::tmm_reg, ) => unreachable!("clobber-only"), InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("GCC backend does not support SPIR-V") @@ -656,6 +656,7 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg) => unimplemented!(), InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => cx.type_i16(), InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg0) => cx.type_i16(), + InlineAsmRegClass::X86(X86InlineAsmRegClass::tmm_reg) => unimplemented!(), InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(), InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") @@ -787,7 +788,7 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option }, InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => None, InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg0) => None, - InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg) => { + InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg | X86InlineAsmRegClass::tmm_reg) => { unreachable!("clobber-only") } InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => unimplemented!(), diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index e994001f96fd9..a53946995ee1c 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -604,7 +604,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> InlineAsmRegClass::X86( X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg - | X86InlineAsmRegClass::kreg0, + | X86InlineAsmRegClass::kreg0 + | X86InlineAsmRegClass::tmm_reg, ) => unreachable!("clobber-only"), InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r", InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r", @@ -692,7 +693,8 @@ fn modifier_to_llvm( InlineAsmRegClass::X86( X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg - | X86InlineAsmRegClass::kreg0, + | X86InlineAsmRegClass::kreg0 + | X86InlineAsmRegClass::tmm_reg, ) => { unreachable!("clobber-only") } @@ -766,7 +768,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &' InlineAsmRegClass::X86( X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg - | X86InlineAsmRegClass::kreg0, + | X86InlineAsmRegClass::kreg0 + | X86InlineAsmRegClass::tmm_reg, ) => { unreachable!("clobber-only") } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 2cc6eb0358567..5c9c16350e469 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1408,6 +1408,7 @@ symbols! { thread_local_macro, thumb2, thumb_mode: "thumb-mode", + tmm_reg, todo_macro, tool_attributes, tool_lints, diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 6bc807c7c4421..df8ccc42a77a3 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -912,6 +912,7 @@ impl InlineAsmClobberAbi { mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, st0, st1, st2, st3, st4, st5, st6, st7, + tmm0, tmm1, tmm2, tmm3, tmm4, tmm5, tmm6, tmm7, } }, InlineAsmClobberAbi::X86_64Win => clobbered_regs! { @@ -931,6 +932,7 @@ impl InlineAsmClobberAbi { mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, st0, st1, st2, st3, st4, st5, st6, st7, + tmm0, tmm1, tmm2, tmm3, tmm4, tmm5, tmm6, tmm7, } }, InlineAsmClobberAbi::AArch64 => clobbered_regs! { diff --git a/compiler/rustc_target/src/asm/x86.rs b/compiler/rustc_target/src/asm/x86.rs index 854674c7f2fa7..e35035fd25af6 100644 --- a/compiler/rustc_target/src/asm/x86.rs +++ b/compiler/rustc_target/src/asm/x86.rs @@ -17,6 +17,7 @@ def_reg_class! { kreg0, mmx_reg, x87_reg, + tmm_reg, } } @@ -41,6 +42,7 @@ impl X86InlineAsmRegClass { Self::xmm_reg | Self::ymm_reg | Self::zmm_reg => &['x', 'y', 'z'], Self::kreg | Self::kreg0 => &[], Self::mmx_reg | Self::x87_reg => &[], + Self::tmm_reg => &[], } } @@ -80,6 +82,7 @@ impl X86InlineAsmRegClass { }, Self::kreg | Self::kreg0 => None, Self::mmx_reg | Self::x87_reg => None, + Self::tmm_reg => None, } } @@ -98,6 +101,7 @@ impl X86InlineAsmRegClass { Self::zmm_reg => Some(('z', "zmm0")), Self::kreg | Self::kreg0 => None, Self::mmx_reg | Self::x87_reg => None, + Self::tmm_reg => None, } } @@ -135,6 +139,7 @@ impl X86InlineAsmRegClass { }, Self::kreg0 => &[], Self::mmx_reg | Self::x87_reg => &[], + Self::tmm_reg => &[], } } } @@ -320,6 +325,14 @@ def_regs! { st5: x87_reg = ["st(5)"], st6: x87_reg = ["st(6)"], st7: x87_reg = ["st(7)"], + tmm0: tmm_reg = ["tmm0"] % x86_64_only, + tmm1: tmm_reg = ["tmm1"] % x86_64_only, + tmm2: tmm_reg = ["tmm2"] % x86_64_only, + tmm3: tmm_reg = ["tmm3"] % x86_64_only, + tmm4: tmm_reg = ["tmm4"] % x86_64_only, + tmm5: tmm_reg = ["tmm5"] % x86_64_only, + tmm6: tmm_reg = ["tmm6"] % x86_64_only, + tmm7: tmm_reg = ["tmm7"] % x86_64_only, #error = ["bp", "bpl", "ebp", "rbp"] => "the frame pointer cannot be used as an operand for inline asm", #error = ["sp", "spl", "esp", "rsp"] => diff --git a/src/test/codegen/asm-clobber_abi.rs b/src/test/codegen/asm-clobber_abi.rs index a87152e0321b9..f70caea2fb9e2 100644 --- a/src/test/codegen/asm-clobber_abi.rs +++ b/src/test/codegen/asm-clobber_abi.rs @@ -6,21 +6,21 @@ 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)},~{dirflag},~{fpsr},~{flags},~{memory} +// 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)},~{dirflag},~{fpsr},~{flags},~{memory} +// 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)},~{dirflag},~{fpsr},~{flags},~{memory} +// 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; @@ -28,7 +28,7 @@ pub unsafe fn clobber_sysv64_edx() { } // 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)},~{dirflag},~{fpsr},~{flags},~{memory} +// 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; diff --git a/src/test/codegen/asm-target-clobbers.rs b/src/test/codegen/asm-target-clobbers.rs index 8845cfbe76792..ac30e18ec5234 100644 --- a/src/test/codegen/asm-target-clobbers.rs +++ b/src/test/codegen/asm-target-clobbers.rs @@ -6,6 +6,13 @@ 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}"()