Skip to content

Commit bdf8269

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 d595fce commit bdf8269

9 files changed

Lines changed: 1815 additions & 39 deletions

File tree

compiler/rustc_codegen_gcc/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)
@@ -780,6 +782,7 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
780782
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
781783
unreachable!("clobber-only")
782784
}
785+
InlineAsmRegClass::Amdgpu(_) => cx.type_i32(),
783786
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => cx.type_i32(),
784787
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
785788
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => cx.type_f32(),
@@ -983,6 +986,7 @@ fn modifier_to_gcc(
983986
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
984987
unreachable!("clobber-only")
985988
}
989+
InlineAsmRegClass::Amdgpu(_) => None,
986990
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => None,
987991
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
988992
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => None,

compiler/rustc_codegen_llvm/src/asm.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
4343
match *op {
4444
InlineAsmOperandRef::Out { reg, late, place } => {
4545
let is_target_supported = |reg_class: InlineAsmRegClass| {
46-
for &(_, feature) in reg_class.supported_types(asm_arch, true) {
46+
for &(_, feature) in reg_class.supported_types(asm_arch, true).as_ref() {
4747
if let Some(feature) = feature {
4848
if self
4949
.tcx
@@ -229,6 +229,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
229229
InlineAsmArch::AArch64 | InlineAsmArch::Arm64EC | InlineAsmArch::Arm => {
230230
constraints.push("~{cc}".to_string());
231231
}
232+
InlineAsmArch::Amdgpu => {}
232233
InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
233234
constraints.extend_from_slice(&[
234235
"~{dirflag}".to_string(),
@@ -698,6 +699,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
698699
| Arm(ArmInlineAsmRegClass::dreg_low8)
699700
| Arm(ArmInlineAsmRegClass::qreg_low4) => "x",
700701
Arm(ArmInlineAsmRegClass::dreg) | Arm(ArmInlineAsmRegClass::qreg) => "w",
702+
Amdgpu(AmdgpuInlineAsmRegClass::Sgpr(_)) => "s",
703+
Amdgpu(AmdgpuInlineAsmRegClass::Vgpr(_)) => "v",
701704
Hexagon(HexagonInlineAsmRegClass::reg) => "r",
702705
Hexagon(HexagonInlineAsmRegClass::reg_pair) => "r",
703706
Hexagon(HexagonInlineAsmRegClass::preg) => unreachable!("clobber-only"),
@@ -803,6 +806,7 @@ fn modifier_to_llvm(
803806
modifier
804807
}
805808
}
809+
Amdgpu(_) => None,
806810
Hexagon(_) => None,
807811
LoongArch(_) => None,
808812
Mips(_) => None,
@@ -883,6 +887,7 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
883887
Arm(ArmInlineAsmRegClass::qreg)
884888
| Arm(ArmInlineAsmRegClass::qreg_low8)
885889
| Arm(ArmInlineAsmRegClass::qreg_low4) => cx.type_vector(cx.type_i64(), 2),
890+
Amdgpu(_) => cx.type_i32(),
886891
Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(),
887892
Hexagon(HexagonInlineAsmRegClass::reg_pair) => cx.type_i64(),
888893
Hexagon(HexagonInlineAsmRegClass::preg) => unreachable!("clobber-only"),

compiler/rustc_hir_typeck/src/inline_asm.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
465465
if let InlineAsmRegClass::Err = reg_class {
466466
continue;
467467
}
468-
for &(_, feature) in reg_class.supported_types(asm_arch, allow_experimental_reg)
468+
for &(_, feature) in
469+
reg_class.supported_types(asm_arch, allow_experimental_reg).as_ref()
469470
{
470471
match feature {
471472
Some(feature) => {

compiler/rustc_span/src/symbol.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,6 +1840,12 @@ symbols! {
18401840
self_in_typedefs,
18411841
self_struct_ctor,
18421842
semiopaque,
1843+
sgpr32,
1844+
sgpr64,
1845+
sgpr96,
1846+
sgpr128,
1847+
sgpr256,
1848+
sgpr512,
18431849
sha2,
18441850
sha3,
18451851
sha512_sm_x86,
@@ -2248,6 +2254,21 @@ symbols! {
22482254
verbatim,
22492255
version,
22502256
vfp2,
2257+
vgpr16,
2258+
vgpr32,
2259+
vgpr64,
2260+
vgpr96,
2261+
vgpr128,
2262+
vgpr160,
2263+
vgpr192,
2264+
vgpr224,
2265+
vgpr256,
2266+
vgpr288,
2267+
vgpr320,
2268+
vgpr352,
2269+
vgpr384,
2270+
vgpr512,
2271+
vgpr1024,
22512272
view_types,
22522273
vis,
22532274
visible_private_types,

0 commit comments

Comments
 (0)