Skip to content

Commit

Permalink
Rollup merge of #126555 - beetrees:f16-inline-asm-arm, r=Amanieu
Browse files Browse the repository at this point in the history
Add `f16` inline ASM support for 32-bit ARM

Adds `f16` inline ASM support for 32-bit ARM. SIMD vector types are taken from [here](https://developer.arm.com/architectures/instruction-sets/intrinsics/#f:`@navigationhierarchiesreturnbasetype=[float]&f:@navigationhierarchieselementbitsize=[16]&f:@navigationhierarchiesarchitectures=[A32]).`

Relevant issue: #125398
Tracking issue: #116909

`@rustbot` label +F-f16_and_f128
  • Loading branch information
GuillaumeGomez authored Jun 22, 2024
2 parents f1b0d54 + 753fb07 commit 07e8b3a
Show file tree
Hide file tree
Showing 3 changed files with 365 additions and 183 deletions.
39 changes: 39 additions & 0 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1037,6 +1037,19 @@ fn llvm_fixup_input<'ll, 'tcx>(
value
}
}
(
InlineAsmRegClass::Arm(
ArmInlineAsmRegClass::dreg
| ArmInlineAsmRegClass::dreg_low8
| ArmInlineAsmRegClass::dreg_low16
| ArmInlineAsmRegClass::qreg
| ArmInlineAsmRegClass::qreg_low4
| ArmInlineAsmRegClass::qreg_low8,
),
Abi::Vector { element, count: count @ (4 | 8) },
) if element.primitive() == Primitive::Float(Float::F16) => {
bx.bitcast(value, bx.type_vector(bx.type_i16(), count))
}
(InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
match s.primitive() {
// MIPS only supports register-length arithmetics.
Expand Down Expand Up @@ -1158,6 +1171,19 @@ fn llvm_fixup_output<'ll, 'tcx>(
value
}
}
(
InlineAsmRegClass::Arm(
ArmInlineAsmRegClass::dreg
| ArmInlineAsmRegClass::dreg_low8
| ArmInlineAsmRegClass::dreg_low16
| ArmInlineAsmRegClass::qreg
| ArmInlineAsmRegClass::qreg_low4
| ArmInlineAsmRegClass::qreg_low8,
),
Abi::Vector { element, count: count @ (4 | 8) },
) if element.primitive() == Primitive::Float(Float::F16) => {
bx.bitcast(value, bx.type_vector(bx.type_f16(), count))
}
(InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
match s.primitive() {
// MIPS only supports register-length arithmetics.
Expand Down Expand Up @@ -1270,6 +1296,19 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
layout.llvm_type(cx)
}
}
(
InlineAsmRegClass::Arm(
ArmInlineAsmRegClass::dreg
| ArmInlineAsmRegClass::dreg_low8
| ArmInlineAsmRegClass::dreg_low16
| ArmInlineAsmRegClass::qreg
| ArmInlineAsmRegClass::qreg_low4
| ArmInlineAsmRegClass::qreg_low8,
),
Abi::Vector { element, count: count @ (4 | 8) },
) if element.primitive() == Primitive::Float(Float::F16) => {
cx.type_vector(cx.type_i16(), count)
}
(InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
match s.primitive() {
// MIPS only supports register-length arithmetics.
Expand Down
12 changes: 7 additions & 5 deletions compiler/rustc_target/src/asm/arm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,18 @@ impl ArmInlineAsmRegClass {
_arch: InlineAsmArch,
) -> &'static [(InlineAsmType, Option<Symbol>)] {
match self {
Self::reg => types! { _: I8, I16, I32, F32; },
Self::sreg | Self::sreg_low16 => types! { vfp2: I32, F32; },
Self::reg => types! { _: I8, I16, I32, F16, F32; },
Self::sreg | Self::sreg_low16 => types! { vfp2: I32, F16, F32; },
Self::dreg_low16 | Self::dreg_low8 => types! {
vfp2: I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2);
vfp2: I64, F64;
neon: VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF16(4), VecF32(2);
},
Self::dreg => types! {
d32: I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2);
d32: I64, F64;
neon: VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF16(4), VecF32(2);
},
Self::qreg | Self::qreg_low8 | Self::qreg_low4 => types! {
neon: VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4);
neon: VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4);
},
}
}
Expand Down
Loading

0 comments on commit 07e8b3a

Please sign in to comment.