diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2024-11-28 12:06:02 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-28 12:06:02 +0100 |
| commit | 470c4f94e819b408bac9de0e67f6c4a5d0fa0b0a (patch) | |
| tree | ce22fdbf92515ec0f3e9d92d0e7a674a0052a401 | |
| parent | 89ae19ee0dba8966f21153794358da8c5ac05a51 (diff) | |
| parent | 59f01cdbf48795ab8d6752b8a4bbe0e4540c30a5 (diff) | |
| download | rust-470c4f94e819b408bac9de0e67f6c4a5d0fa0b0a.tar.gz rust-470c4f94e819b408bac9de0e67f6c4a5d0fa0b0a.zip | |
Rollup merge of #133452 - taiki-e:hexagon-asm-pred, r=Amanieu
Support predicate registers (clobber-only) in Hexagon inline assembly
The result of the Hexagon instructions such as comparison, store conditional, etc. is stored in predicate registers (`p[0-3]`), but currently there is no way to mark it as clobbered in `asm!`.
This is also needed for `clobber_abi` (although implementing `clobber_abi` will require the addition of support for [several more register classes](https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp#L71-L90). see also https://github.com/rust-lang/rust/issues/93335#issuecomment-2395210055).
Refs:
- [Section 6 "Conditional Execution" in Qualcomm Hexagon V73 Programmer’s Reference Manual](https://docs.qualcomm.com/bundle/publicresource/80-N2040-53_REV_AB_Qualcomm_Hexagon_V73_Programmers_Reference_Manual.pdf#page=90)
- [Register definition in LLVM](https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td#L155)
cc `@androm3da` (target maintainer of hexagon-unknown-{[none-elf](https://doc.rust-lang.org/nightly/rustc/platform-support/hexagon-unknown-none-elf.html#target-maintainers),[linux-musl](https://doc.rust-lang.org/nightly/rustc/platform-support/hexagon-unknown-linux-musl.html#target-maintainers)})
r? `@Amanieu`
`@rustbot` label +A-inline-assembly
(Currently there is no O-hexagon label...)
| -rw-r--r-- | compiler/rustc_codegen_gcc/src/asm.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/asm.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/hexagon.rs | 6 | ||||
| -rw-r--r-- | src/doc/unstable-book/src/language-features/asm-experimental-arch.md | 2 | ||||
| -rw-r--r-- | tests/codegen/asm/hexagon-clobbers.rs | 37 |
5 files changed, 53 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index ab4fdb78bb0..341d1b9c179 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -634,6 +634,9 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r", InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w", InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::preg) => { + unreachable!("clobber-only") + } InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r", InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f", InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r", @@ -720,6 +723,9 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl cx.type_vector(cx.type_i64(), 2) } InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::preg) => { + unreachable!("clobber-only") + } InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(), InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(), diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 6ee80c08d4a..9aa01bd1b95 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -645,6 +645,7 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> | Arm(ArmInlineAsmRegClass::qreg_low4) => "x", Arm(ArmInlineAsmRegClass::dreg) | Arm(ArmInlineAsmRegClass::qreg) => "w", Hexagon(HexagonInlineAsmRegClass::reg) => "r", + Hexagon(HexagonInlineAsmRegClass::preg) => unreachable!("clobber-only"), LoongArch(LoongArchInlineAsmRegClass::reg) => "r", LoongArch(LoongArchInlineAsmRegClass::freg) => "f", Mips(MipsInlineAsmRegClass::reg) => "r", @@ -813,6 +814,7 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &' | Arm(ArmInlineAsmRegClass::qreg_low8) | Arm(ArmInlineAsmRegClass::qreg_low4) => cx.type_vector(cx.type_i64(), 2), Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(), + Hexagon(HexagonInlineAsmRegClass::preg) => unreachable!("clobber-only"), LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(), LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(), Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(), diff --git a/compiler/rustc_target/src/asm/hexagon.rs b/compiler/rustc_target/src/asm/hexagon.rs index f7e726c3376..aa14ca3f337 100644 --- a/compiler/rustc_target/src/asm/hexagon.rs +++ b/compiler/rustc_target/src/asm/hexagon.rs @@ -7,6 +7,7 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; def_reg_class! { Hexagon HexagonInlineAsmRegClass { reg, + preg, } } @@ -37,6 +38,7 @@ impl HexagonInlineAsmRegClass { ) -> &'static [(InlineAsmType, Option<Symbol>)] { match self { Self::reg => types! { _: I8, I16, I32, F32; }, + Self::preg => &[], } } } @@ -71,6 +73,10 @@ def_regs! { r26: reg = ["r26"], r27: reg = ["r27"], r28: reg = ["r28"], + p0: preg = ["p0"], + p1: preg = ["p1"], + p2: preg = ["p2"], + p3: preg = ["p3"], #error = ["r19"] => "r19 is used internally by LLVM and cannot be used as an operand for inline asm", #error = ["r29", "sp"] => diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md index 01de12bb90e..12a73f0508b 100644 --- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md +++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md @@ -30,6 +30,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | NVPTX | `reg32` | None\* | `r` | | NVPTX | `reg64` | None\* | `l` | | Hexagon | `reg` | `r[0-28]` | `r` | +| Hexagon | `preg` | `p[0-3]` | Only clobbers | | PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-28]` | `r` | | PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-28]` | `b` | | PowerPC | `freg` | `f[0-31]` | `f` | @@ -70,6 +71,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | NVPTX | `reg32` | None | `i8`, `i16`, `i32`, `f32` | | NVPTX | `reg64` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | | Hexagon | `reg` | None | `i8`, `i16`, `i32`, `f32` | +| Hexagon | `preg` | N/A | Only clobbers | | PowerPC | `reg` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) | | PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) | | PowerPC | `freg` | None | `f32`, `f64` | diff --git a/tests/codegen/asm/hexagon-clobbers.rs b/tests/codegen/asm/hexagon-clobbers.rs new file mode 100644 index 00000000000..6bb662ead99 --- /dev/null +++ b/tests/codegen/asm/hexagon-clobbers.rs @@ -0,0 +1,37 @@ +//@ revisions: hexagon +//@[hexagon] compile-flags: --target hexagon-unknown-linux-musl +//@[hexagon] needs-llvm-components: hexagon +//@ compile-flags: -Zmerge-functions=disabled + +#![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: @flags_clobber +// CHECK: call void asm sideeffect "", ""() +#[no_mangle] +pub unsafe fn flags_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: @p0_clobber +// CHECK: call void asm sideeffect "", "~{p0}"() +#[no_mangle] +pub unsafe fn p0_clobber() { + asm!("", out("p0") _, options(nostack, nomem, preserves_flags)); +} |
