about summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-11-07 21:07:06 +0000
committerbors <bors@rust-lang.org>2024-11-07 21:07:06 +0000
commitb91a3a05609a46f73d23e0995ae7ebb4a4f429a5 (patch)
tree042c9f3e7be8d29c741e1fac9f28f2ad45b9d228 /compiler/rustc_codegen_llvm
parent57a8a7efdb898966282e3f57528c3b9ea4d9bf49 (diff)
parent241f82ad915b167992ec9d3bb729f095a7829424 (diff)
downloadrust-b91a3a05609a46f73d23e0995ae7ebb4a4f429a5.tar.gz
rust-b91a3a05609a46f73d23e0995ae7ebb4a4f429a5.zip
Auto merge of #132472 - taiki-e:sparc-asm, r=Amanieu
Basic inline assembly support for SPARC and SPARC64

This implements asm_experimental_arch (tracking issue https://github.com/rust-lang/rust/issues/93335) for SPARC and SPARC64.

This PR includes:

- General-purpose registers `r[0-31]` (`reg` register class, LLVM/GCC constraint `r`)
  Supported types: i8, i16, i32, i64 (SPARC64-only)
  Aliases: `g[0-7]` (`r[0-7]`), `o[0-7]` (`r[8-15]`), `l[0-7]` (`r[16-23]`), `i[0-7]` (`r[24-31]`)
- `y` register (clobber-only, needed for clobber_abi)
- preserves_flags: Integer condition codes (`icc`, `xcc`) and floating-point condition codes (`fcc*`)

The following are *not* included:

- 64-bit integer support on SPARC-V8+'s global or out registers (`g[0-7]`, `o[0-7]`): GCC's `h` constraint (it seems that there is no corresponding constraint in LLVM?)
- Floating-point registers (LLVM/GCC constraint `e`/`f`):
  I initially tried to implement this, but postponed it for now because there seemed to be several parts in LLVM that behaved differently than in the LangRef's description.
- clobber_abi: Support for floating-point registers is needed.

Refs:
- LLVM
  - Reserved registers https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp#L52
  - Register definitions https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/Sparc/SparcRegisterInfo.td
  - Supported constraints https://llvm.org/docs/LangRef.html#supported-constraint-code-list
- GCC
  - Reserved registers https://github.com/gcc-mirror/gcc/blob/63b6967b06b5387821c4e5f2c113da6aaeeae2b7/gcc/config/sparc/sparc.h#L633-L658
  - Supported constraints https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
- SPARC ISA/ABI
  - (64-bit ISA) The SPARC Architecture Manual, Version 9
    (32-bit ISA) The SPARC Architecture Manual, Version 8
    (64-bit ABI) System V Application Binary Interface SPARC Version 9 Processor Supplement, Rev 1.35
    (32-bit ABI) System V Application Binary Interface SPARC Processor Supplement, Third Edition
    The above docs can be downloaded from https://sparc.org/technical-documents
  - (32-bit V8+ ABI) The V8+ Technical Specification
    https://temlib.org/pub/SparcStation/Standards/V8plus.pdf

cc `@thejpster` (sparc-unknown-none-elf target maintainer)
(AFAIK, other sparc/sprac64 targets don't have target maintainers)

r? `@Amanieu`

`@rustbot` label +O-SPARC +A-inline-assembly
Diffstat (limited to 'compiler/rustc_codegen_llvm')
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs14
1 files changed, 14 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index a1ccf0d1719..bb74dfe1487 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -268,6 +268,15 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                 InlineAsmArch::S390x => {
                     constraints.push("~{cc}".to_string());
                 }
+                InlineAsmArch::Sparc | InlineAsmArch::Sparc64 => {
+                    // In LLVM, ~{icc} represents icc and xcc in 64-bit code.
+                    // https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/Sparc/SparcRegisterInfo.td#L64
+                    constraints.push("~{icc}".to_string());
+                    constraints.push("~{fcc0}".to_string());
+                    constraints.push("~{fcc1}".to_string());
+                    constraints.push("~{fcc2}".to_string());
+                    constraints.push("~{fcc3}".to_string());
+                }
                 InlineAsmArch::SpirV => {}
                 InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {}
                 InlineAsmArch::Bpf => {}
@@ -672,6 +681,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
             S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => {
                 unreachable!("clobber-only")
             }
+            Sparc(SparcInlineAsmRegClass::reg) => "r",
+            Sparc(SparcInlineAsmRegClass::yreg) => unreachable!("clobber-only"),
             Msp430(Msp430InlineAsmRegClass::reg) => "r",
             M68k(M68kInlineAsmRegClass::reg) => "r",
             M68k(M68kInlineAsmRegClass::reg_addr) => "a",
@@ -765,6 +776,7 @@ fn modifier_to_llvm(
         },
         Avr(_) => None,
         S390x(_) => None,
+        Sparc(_) => None,
         Msp430(_) => None,
         SpirV(SpirVInlineAsmRegClass::reg) => bug!("LLVM backend does not support SPIR-V"),
         M68k(_) => None,
@@ -835,6 +847,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
         S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => {
             unreachable!("clobber-only")
         }
+        Sparc(SparcInlineAsmRegClass::reg) => cx.type_i32(),
+        Sparc(SparcInlineAsmRegClass::yreg) => unreachable!("clobber-only"),
         Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(),
         M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
         M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),