Skip to content

Commit 09c0b82

Browse files
Rollup merge of rust-lang#149793 - Flakebi:inline-asm, r=Amanieu
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. Tracking issue: rust-lang#135024
2 parents b5e0530 + e699f5a commit 09c0b82

9 files changed

Lines changed: 1817 additions & 41 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)
@@ -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,

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(),
@@ -699,6 +700,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
699700
| Arm(ArmInlineAsmRegClass::dreg_low8)
700701
| Arm(ArmInlineAsmRegClass::qreg_low4) => "x",
701702
Arm(ArmInlineAsmRegClass::dreg) | Arm(ArmInlineAsmRegClass::qreg) => "w",
703+
Amdgpu(AmdgpuInlineAsmRegClass::Sgpr(_)) => "s",
704+
Amdgpu(AmdgpuInlineAsmRegClass::Vgpr(_)) => "v",
702705
Hexagon(HexagonInlineAsmRegClass::reg) => "r",
703706
Hexagon(HexagonInlineAsmRegClass::reg_pair) => "r",
704707
Hexagon(HexagonInlineAsmRegClass::preg) => unreachable!("clobber-only"),
@@ -809,6 +812,7 @@ fn modifier_to_llvm(
809812
modifier
810813
}
811814
}
815+
Amdgpu(_) => None,
812816
Hexagon(_) => None,
813817
LoongArch(_) => None,
814818
Mips(_) => None,
@@ -890,6 +894,7 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
890894
Arm(ArmInlineAsmRegClass::qreg)
891895
| Arm(ArmInlineAsmRegClass::qreg_low8)
892896
| Arm(ArmInlineAsmRegClass::qreg_low4) => cx.type_vector(cx.type_i64(), 2),
897+
Amdgpu(_) => cx.type_i32(),
893898
Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(),
894899
Hexagon(HexagonInlineAsmRegClass::reg_pair) => cx.type_i64(),
895900
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
@@ -1860,6 +1860,12 @@ symbols! {
18601860
self_in_typedefs,
18611861
self_struct_ctor,
18621862
semiopaque,
1863+
sgpr32,
1864+
sgpr64,
1865+
sgpr96,
1866+
sgpr128,
1867+
sgpr256,
1868+
sgpr512,
18631869
sha2,
18641870
sha3,
18651871
sha512_sm_x86,
@@ -2272,6 +2278,21 @@ symbols! {
22722278
verbatim,
22732279
version,
22742280
vfp2,
2281+
vgpr16,
2282+
vgpr32,
2283+
vgpr64,
2284+
vgpr96,
2285+
vgpr128,
2286+
vgpr160,
2287+
vgpr192,
2288+
vgpr224,
2289+
vgpr256,
2290+
vgpr288,
2291+
vgpr320,
2292+
vgpr352,
2293+
vgpr384,
2294+
vgpr512,
2295+
vgpr1024,
22752296
view_types,
22762297
vis,
22772298
visible_private_types,

0 commit comments

Comments
 (0)