-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Basic inline assembly support for SPARC and SPARC64 #132472
Conversation
Some changes occurred in compiler/rustc_codegen_gcc |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Hmm, but when I set needs-llvm-components, I got:
IIUC, it seems difficult to retain this test since there is no builtin target other than xtensa that does not support inline assembly in rust-lang/rust after this PR, and xtensa can probably support inline assembly in LLVM 20 (llvm/llvm-project@dc2d0d5, inline assembly itself is already supported in esp-rs fork). UPDATE: removed this test |
46b0ebc
to
84fdac1
Compare
14f6234
to
3d19a90
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
☔ The latest upstream changes (presumably #129884) made this pull request unmergeable. Please resolve the merge conflicts. |
| SPARC | `r0`/`g0` | This is always zero and cannot be used as inputs or outputs. | | ||
| SPARC | `r1`/`g1` | Used internally by LLVM. | | ||
| SPARC | `r6`/`g6`, `r7`/`g7` | Reserved for system. | | ||
| SPARC | `r31`/`i7` | Return address cannot be used as inputs or outputs. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i6
/o6
also need to be added to the list of stack/frame pointers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And g5 needs to be mentioned as reserved on sparc32.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! I have updated docs to mention them.
) -> &'static [(InlineAsmType, Option<Symbol>)] { | ||
match self { | ||
Self::reg => { | ||
// FIXME: i64 is ok for g*/o* registers on SPARC-V8+ ("h" constraint in GCC) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is better expressed as "v9": I64
in the macro. The feature name can later be changed to v8plus
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That constraint is not yet supported in LLVM, so I have updated the FIXME comment to use the way you mention.
rust/compiler/rustc_target/src/asm/sparc.rs
Lines 44 to 49 in 241f82a
types! { | |
_: I8, I16, I32; | |
// FIXME: i64 is ok for g*/o* registers on SPARC-V8+ ("h" constraint in GCC), | |
// but not yet supported in LLVM. | |
// v8plus: I64; | |
} |
_target: &Target, | ||
_is_clobber: bool, | ||
) -> Result<(), &'static str> { | ||
if is_v7_or_v8(arch, target_features) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition used in LLVM is Subtarget.is64Bit()
, not whether v8plus
is supported. So this should check for InlineAsmArch::Sparc64
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. Section 2.1.5 "Function Registers with Unassigned Roles" of the V8+ Technical Specification says "%g5; no longer reserved for system software" 1, and LLVM does not seem to match it.
I have changed the condition to Sparc64 vs Sparc and left a FIXME comment mentioning the mismatch between LLVM and the specification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(The above change removes the need for the addition of the target feature in this PR. It is still needed for other purposes but will be handled in another PR: #132552)
I would expect all the FIXME to be resolved before stabilization, but this is good enough for nightly. @bors r+ |
@bors rollup=iffy |
☀️ Test successful - checks-actions |
Finished benchmarking commit (b91a3a0): comparison URL. Overall result: ❌ regressions - no action needed@rustbot label: -perf-regression Instruction countThis is the most reliable metric that we have; it was used to determine the overall result at the top of this comment. However, even this metric can sometimes exhibit noise.
Max RSS (memory usage)Results (primary -0.7%, secondary -1.9%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResults (primary 2.3%, secondary 7.5%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 780.698s -> 781.906s (0.15%) |
…rkingjubilee Add v9, v8plus, and leoncasa target feature to sparc and use v8plus in create_object_file This adds the following three unstable target features: - `v9`: SPARC-V9 instructions ([LLVM definition][sparc-v9]) - Relevant to rust-lang#131222 (comment) - Relevant to rust-lang#132472 (comment) - This is also needed to implement taiki-e/atomic-maybe-uninit#31 (depends on inline assembly support) more robustly. - `v8plus`: SPARC-V8+ ABI ([LLVM definition][sparc-v8plus]) - This is added in LLVM 20. In LLVM 19 and older, it is emulated to work the same way as LLVM in each LLVM version. - See rust-lang#132585 (comment) for more. - `leoncasa`: CASA instruction[^1] of LEON3 and LEON4 processors ([LLVM definition][sparc-leoncasa], LLVM feature name: `hasleoncasa`) - This is needed to implement taiki-e/atomic-maybe-uninit#31 (depends on inline assembly support) more robustly. [^1]: Atomic CAS instruction [sparc-v9]: https://github.com/llvm/llvm-project/blob/f5e4ffaa49254706ad6fa209de8aec28e20f0041/llvm/lib/Target/Sparc/Sparc.td#L37-L39 [sparc-v8plus]: https://github.com/llvm/llvm-project/blob/f5e4ffaa49254706ad6fa209de8aec28e20f0041/llvm/lib/Target/Sparc/Sparc.td#L37-L39 [sparc-leoncasa]: https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/Sparc/LeonFeatures.td#L32-L37
Rollup merge of rust-lang#132552 - taiki-e:sparc-target-feature, r=workingjubilee Add v9, v8plus, and leoncasa target feature to sparc and use v8plus in create_object_file This adds the following three unstable target features: - `v9`: SPARC-V9 instructions ([LLVM definition][sparc-v9]) - Relevant to rust-lang#131222 (comment) - Relevant to rust-lang#132472 (comment) - This is also needed to implement taiki-e/atomic-maybe-uninit#31 (depends on inline assembly support) more robustly. - `v8plus`: SPARC-V8+ ABI ([LLVM definition][sparc-v8plus]) - This is added in LLVM 20. In LLVM 19 and older, it is emulated to work the same way as LLVM in each LLVM version. - See rust-lang#132585 (comment) for more. - `leoncasa`: CASA instruction[^1] of LEON3 and LEON4 processors ([LLVM definition][sparc-leoncasa], LLVM feature name: `hasleoncasa`) - This is needed to implement taiki-e/atomic-maybe-uninit#31 (depends on inline assembly support) more robustly. [^1]: Atomic CAS instruction [sparc-v9]: https://github.com/llvm/llvm-project/blob/f5e4ffaa49254706ad6fa209de8aec28e20f0041/llvm/lib/Target/Sparc/Sparc.td#L37-L39 [sparc-v8plus]: https://github.com/llvm/llvm-project/blob/f5e4ffaa49254706ad6fa209de8aec28e20f0041/llvm/lib/Target/Sparc/Sparc.td#L37-L39 [sparc-leoncasa]: https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/Sparc/LeonFeatures.td#L32-L37
…rkingjubilee Add v9, v8plus, and leoncasa target feature to sparc and use v8plus in create_object_file This adds the following three unstable target features: - `v9`: SPARC-V9 instructions ([LLVM definition][sparc-v9]) - Relevant to rust-lang#131222 (comment) - Relevant to rust-lang#132472 (comment) - This is also needed to implement taiki-e/atomic-maybe-uninit#31 (depends on inline assembly support) more robustly. - `v8plus`: SPARC-V8+ ABI ([LLVM definition][sparc-v8plus]) - This is added in LLVM 20. In LLVM 19 and older, it is emulated to work the same way as LLVM in each LLVM version. - See rust-lang#132585 (comment) for more. - `leoncasa`: CASA instruction[^1] of LEON3 and LEON4 processors ([LLVM definition][sparc-leoncasa], LLVM feature name: `hasleoncasa`) - This is needed to implement taiki-e/atomic-maybe-uninit#31 (depends on inline assembly support) more robustly. [^1]: Atomic CAS instruction [sparc-v9]: https://github.com/llvm/llvm-project/blob/f5e4ffaa49254706ad6fa209de8aec28e20f0041/llvm/lib/Target/Sparc/Sparc.td#L37-L39 [sparc-v8plus]: https://github.com/llvm/llvm-project/blob/f5e4ffaa49254706ad6fa209de8aec28e20f0041/llvm/lib/Target/Sparc/Sparc.td#L37-L39 [sparc-leoncasa]: https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/Sparc/LeonFeatures.td#L32-L37
Basic inline assembly support for SPARC and SPARC64 This implements asm_experimental_arch (tracking issue rust-lang#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
This implements asm_experimental_arch (tracking issue #93335) for SPARC and SPARC64.
This PR includes:
r[0-31]
(reg
register class, LLVM/GCC constraintr
)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)icc
,xcc
) and floating-point condition codes (fcc*
)The following are not included:
g[0-7]
,o[0-7]
): GCC'sh
constraint (it seems that there is no corresponding constraint in LLVM?)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.
Refs:
(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
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