Skip to content

Commit 9202952

Browse files
committed
Add inline asm support for amdgpu
Add support for inline assembly for the amdgpu backend (the amdgcn-amd-amdhsa target). Add register classes for `vgpr` (vector general purpose register) and `sgpr` (scalar general purpose register). The LLVM backend supports two more classes, `reg`, which is either VGPR or SGPR, up to the compiler to decide. As instructions often rely on a register being either a VGPR or SGPR for the assembly to be valid, reg doesn’t seem that useful (I struggled to write correct tests for it), so I didn’t end up adding it. The fourth register class is AGPRs, which only exist on some hardware versions (not the consumer ones) and they have restricted ways to write and read from them, which makes it hard to write a Rust variable into them. They could be used inside assembly blocks, but I didn’t add them as Rust register class. There are a few change affecting general inline assembly code, that is `InlineAsmReg::name()` now returns a `Cow` instead of a `&'static str`. Because amdgpu has many registers, 256 VGPRs plus combinations of 2 or 4 VGPRs, and I didn’t want to list hundreds of static strings, the amdgpu reg stores the register number(s) and a non-static String is generated at runtime for the register name. Similar for register classes and supported_types. Vectors of 64-bit types are supported by the LLVM backend, but omitted here to make the code simpler. There is currently no systematic support in LLVM of which vectors of 64-bit types are supported. Also, they are likely seldomly unused, vectors of 16- and 32-bit types are important.
1 parent a20ecda commit 9202952

1 file changed

Lines changed: 4 additions & 0 deletions

File tree

src/asm.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,8 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str {
677677
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
678678
unreachable!("clobber-only")
679679
}
680+
InlineAsmRegClass::Amdgpu(AmdgpuInlineAsmRegClass::Sgpr(_)) => "Sg",
681+
InlineAsmRegClass::Amdgpu(AmdgpuInlineAsmRegClass::Vgpr(_)) => "v",
680682
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => "r",
681683
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
682684
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16)
@@ -785,6 +787,7 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
785787
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
786788
unreachable!("clobber-only")
787789
}
790+
InlineAsmRegClass::Amdgpu(_) => cx.type_i32(),
788791
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => cx.type_i32(),
789792
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
790793
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => cx.type_f32(),
@@ -993,6 +996,7 @@ fn modifier_to_gcc(
993996
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
994997
unreachable!("clobber-only")
995998
}
999+
InlineAsmRegClass::Amdgpu(_) => None,
9961000
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => None,
9971001
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
9981002
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => None,

0 commit comments

Comments
 (0)