Support predicate registers (clobber-only) in Hexagon inline assembly
This commit is contained in:
parent
1278dad1e9
commit
59f01cdbf4
5 changed files with 53 additions and 0 deletions
|
@ -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(),
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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"] =>
|
||||
|
|
|
@ -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` |
|
||||
|
|
37
tests/codegen/asm/hexagon-clobbers.rs
Normal file
37
tests/codegen/asm/hexagon-clobbers.rs
Normal file
|
@ -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));
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue