ports/unix: Add LoongArch64 architecture support.#19292
Open
agatti wants to merge 7 commits into
Open
Conversation
This commit adds native NLR support for the LoongArch64 platform. Even though the setjmp/longjmp NLR implementation works, an implementation tailored to MicroPython's needs is provided. It should be slightly faster and use less memory since it only saves the subset of registers that are mentioned in the ABI as callee-saved, in addition to a register that is simply marked as "reserved" in the same document. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit provides optimised function implementations for the GC helper function to collect register values. Both a generic C version and a pure assembler version are provided by these changes, collecting the subset of callee-save registers mentioned in the LoongArch64 ABI document (S0-S9). As for the other platforms, it is preferable to use the assembler version whenever possible, although both were found to be working. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit lets the Unix port use an optimised implementation of the helper function that gathers CPU registers' values. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit lets the `platform` module correctly report whether an interpreter was built targeting the LoongArch64 architecture. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit adds the necessary commands to the CI script to set up, build, and run tests for the Unix port using LoongArch64 as a CPU target. Following the rest of the Unix port targets, `ci_unix_qemu_loong64_setup`, `ci_unix_qemu_loong64_build`, and `ci_unix_qemu_loong64_run_tests` commands are now available. Even though the architecture has been supported by GCC, Linux, QEMU, LibFFI and other support libraries for quite some time now, some workarounds had to be put in place to make things work. The CI image's Ubuntu version comes with two versions of the GCC compiler and no installable meta-package. Moreover, the compiler binaries are tagged via a suffix, so the usual approach of setting the `CROSS` variable when invoking make cannot be used. This means having to symlink the gcc and g++ binaries into something that can work with that scheme. On the execution side, the LoongArch64 binary format isn't in the binfmt database. That was worked around by creating a runner script that invokes the interpreter via the appropriate QEMU binary. This is enough to let the test runner work with the current setup. Both workarounds need to be revisited if things change when a new OS image is used for running CI tasks. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit adds a new LoongArch64 variant to the Unix port's targets list, using the same template as the rest of the targets already put under test. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit updates the Unix port's supported targets list in the README file, adding both RISC-V and LoongArch to said list. Now that the LoongArch64 target is fully implemented as far as the Unix port is concerned, is supported by LibFFI, and it is buildable both by hand using `make` and by the CI script, it can safely be added to the supported targets list. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #19292 +/- ##
=======================================
Coverage 98.47% 98.47%
=======================================
Files 176 176
Lines 22845 22845
=======================================
Hits 22497 22497
Misses 348 348 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Code size report: |
|
Thank you for your contributions to the Loongson ecosystem. From China |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR introduces support for the LoongArch64 architecture to the Unix port.
Inspired by #18564 and #18604, and with roughly a hour of free time, LoongArch64 could now be added to the list of supported architectures. This is essentially a rehash of the RV64 code with the unsupported
__attribute__((naked))workaround introduced inpy/nlrmips.c, saving and restoring a subset of the RV64 registers, and having to look up the new opcodes syntax. The assembly code could have probably been machine-translated given how similar it is.LoongArch64 support, if merged, will stay at the same level as MIPS64 unless there are users asking for more. Which in this case would only mean natmod support, and only if there's strong demand (some of the relocation types mentioned in the ABI documents make AArch64 look simplistic...).
Like MIPS 64 and RISC-V 64, LoongArch64 is fully supported by Linux, GCC, and LibFFI. It is an officially supported platform by the Alpine and Debian Linux distributions, so there might be some interest in getting MicroPython to work a tiny bit better on this architecture.
It's not a big deal if this PR is found to be out of scope w.r.t. the current MicroPython direction, it was an interesting exercise and it took more time to come up with appropriate git commit descriptions than figuring out how to make this work.
Some pointers:
ELF ABI: https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html
Assembler opcodes: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.pdf
Toolchain preprocessor definitions: https://loongson.github.io/LoongArch-Documentation/LoongArch-toolchain-conventions-EN.pdf
Testing
This should be already tested by the updated CI workflow present in this PR.
tests/thread/stress_aes.pyis still flaky, but that's the case with all other QEMU-based runners. When the job is executed during off-peak hours (eg. 4AM or 5AM) the test completes in the allotted amount of time.Trade-offs and Alternatives
Although a new architecture usually means non-trivial amount of maintenance at the beginning, this should require the same amount of maintenance as the Unix port's RV64 variant. It's basically the same execution model but with different assembler syntax, after all.
Generative AI
I did not use generative AI tools when creating this PR.