minorum/llvm-nds32

GitHub: minorum/llvm-nds32

LLVM 22 分支,为 Andes NDS32 架构添加了代码生成后端,支持在该平台上编译 Rust no_std 固件。

Stars: 0 | Forks: 0

# 带有 Andes NDS32 后端的 LLVM 这是 [llvm/llvm-project](https://github.com/llvm/llvm-project) 的一个分支,基于 `llvmorg-22.1.0` 版本,添加了**用于 Andes NDS32 (AndeStar) 架构的代码生成器**,包含大端序。上游 LLVM 没有 NDS32 目标;该分支 存在的目的是为 NDS32 协处理器编译 Rust `no_std` 固件。 - **后端位于 [`llvm/lib/Target/NDS32/`](llvm/lib/Target/NDS32)。** - **`nds32` 是包含该后端的分支**,也是默认分支。`main` 是 未经修改的上游 LLVM,完全不包含 NDS32 目标。 - 该分支追踪一条长期的开发线,而不是每个 LLVM 版本对应一个分支, 因此其名称和 URL 保持稳定。它当前所基于的上游版本通过标签标记: `nds32-v-`,例如 `nds32-v22.1.0-1`。上游代码会被合并进来, 从不进行 rebase —— 重写该分支会破坏所有指向它的子模块 gitlink。 - 选择 LLVM 22 是为了匹配 rustc-nightly 捆绑的 LLVM,因此 rustc 的 IR 可以直接 解析和降低。 ## 在 AI 辅助下开发 此后端在很大程度上是在 AI(Anthropic 的 Claude)的辅助下编写的,并在 人工指导和审查下进行。明确说明这一点是因为这会影响你阅读代码的方式: 将其视为任何陌生贡献者的作品,并依赖检查机制而非作者身份来判断。 关于“你如何信任它?”这个项目给出的回答是,这里没有任何内容是 仅凭看起来合理就被接受的: - 指令编码是**与 Andes `nds32be-elf` binutils 进行逐字节的差分测试**,而 非人工推导。系统寄存器表是通过探测工具链生成的,而不是直接抄录(266 种 拼写,包含两种助记符,以及一次反汇编往返测试)。 - 编译后的代码**在 Andes nds32 ISS 上执行**,这捕获了严格匹配输出的 FileCheck 在结构上无法发现的静默错误编译。 - 行为变更伴随着针对性的 CodeGen 或 MC 测试一同提交。 当本 README 中的声明没有得到上述任一支持时,它仅仅是关于意图的声明,而非证据。 ## 已实现的功能 完整的 ABI、帧指针 + alloca、varargs、寄存器偏移和后自增 寻址、PIC/TLS、单精度硬浮点、16 位压缩、系统 寄存器,以及完整的 MC 层(TableGen 驱动的编码器、反汇编器、 AsmParser)。Rust `core` 和 `compiler_builtins` 可以编译为有效的 NDS32 对象 文件,并在 Andes nds32 ISS 上正确执行。 处理器:`v2`(= `generic`)、`v3`、`v3f`、`v3f-hard`。主要 triple: `nds32be-unknown-none-elf`。 ### 核心配置特性 除了 ISA 级别之外,还有两个 subtarget 特性用于描述特定核心是 如何*构建*的。两者在真实的硅片上都很重要,而且过去它们都会静默失败: | 特性 | 含义 | |---|---| | `+reduced-regs` | 仅存在 Andes 缩减寄存器集(r0–r10, r15, r28–r31)。在此类核心上分配 r11–r14 或 r16–r27 会产生**错误**。 | | `+no-16bit` | 永不生成 16 位(压缩)形式。 | 与此相关,`bitci` 仅限 V3 基准 —— V2 核心在执行时会陷入异常 —— 因此 `(and reg, imm)` → `bitci` 模式受 `HasV3Ops` 限制,而 V2 会将 相同的表达式降级为 `movi`+`and`。 ## 构建 ``` cmake -S llvm -B build -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DLLVM_TARGETS_TO_BUILD=X86 \ -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=NDS32 \ -DLLVM_ENABLE_ASSERTIONS=ON \ -DLLVM_INCLUDE_TESTS=ON ninja -C build llc llvm-mc llvm-objdump FileCheck not count ``` NDS32 是一个*实验性*目标,因此需要指定 `LLVM_EXPERIMENTAL_TARGETS_TO_BUILD`。 如果你打算将宿主 rustc 链接到此构建版本,请将你的宿主架构(上例中的 `X86`)保留在 `LLVM_TARGETS_TO_BUILD` 中。 ## 测试 使用 `-DLLVM_INCLUDE_TESTS=ON` 进行配置(如上所述),测试套件将在 真实的 `llvm-lit` 下运行。所需的一切都包含在此代码库中: ``` # CodeGen + MC,exact-output FileCheck —— 标准 LLVM 工作流 ./build/bin/llvm-lit -sv llvm/test/CodeGen/NDS32 llvm/test/MC/NDS32 # 每个 sysreg 拼写与 GNU assembler 进行 byte-compared python3 llvm/utils/NDS32/verify-sysregs.py # 编译后的代码实际在 Andes nds32 ISS 上运行 bash llvm/utils/NDS32/build-nds32-sim.sh # once bash llvm/utils/NDS32/run-exec-test.sh ``` 不要满足于“测试能够编译”。在 ISS 上运行代码已经捕获了静默 错误编译 —— 数据字节序、PIC 跳转表、1 位分支修复掩码 —— 这些是 基于汇编的 FileCheck 在结构上无法发现的。 `llvm/lib/Target/NDS32/NDS32SysRegs.td` 是**生成**的 —— 请勿手动编辑。 使用 `llvm/utils/NDS32/gen-sysregs.py` 重新生成,它通过探测 GNU 工具链来推导整个表: 规范名称是 `nds32be-elf-objdump` 为每个架构上不同的 SRIDX 打印的内容,别名是 `nds32be-elf-as` 接受的数字 `$crN`/`$irN`/`$drN`/… 拼写形式。 ## 许可 此分支采用 **Apache-2.0 WITH LLVM-exception**,与上游相同。`LICENSE.TXT` 未被 修改,每个 NDS32 源文件均带有标准的 LLVM 头文件。 **不存在任何 GPL 代码或派生自 GPL 的数据。** 这一点值得明确说明,因为用于 验证此后端的工具链 —— GNU binutils 和提供 ISS 的 Andes `gdb` 分支 —— 是 GPL 许可的。该界限在两个方向上都保持清晰: - 生成的系统寄存器表**仅基于工具输出构建**(字节 输入,字节输出)。早期版本曾从 binutils 的 `nds32-asm.c` 中解析 `keyword_sr` 表,这引发了一个可以避免的许可问题;该 依赖项已被移除,并且它生成的规范寄存器集在字节层面上 完全相同(136 个寄存器,相同的 SRIDX 值)。 - binutils 和 ISS **作为外部程序调用**,从未被链接、 引入或复制。`build-nds32-sim.sh` 在构建时将 Andes gdb 分支克隆 到你的机器上;这里不再分发其中的任何内容。 - 对你的输入运行 GPL 工具不会使其输出受到限制,因此由 此后端生成并针对这些工具进行验证的对象文件不承担任何 GPL 义务。 如果你重新分发此分支,你是在 Apache-2.0 WITH LLVM-exception 许可下重新分发 LLVM,仅此而已。 ## 状态与支持 **工作正常,并已投入实战使用** —— 此后端为以下 消费者项目编译固件,该项目在真实的 MT6785 硬件上运行。它不是一个 研究玩具。但它**也**不是上游 LLVM 目标,而且永远也不会是: NDS32 是遗留物(Andes 已转向 RISC-V),因此此分支是永久的最终状态, 而非中转站。 坦诚的期望,以免大家失望: - 这是一个**由单人维护的个人项目**,尽力而为,没有 SLA。欢迎提交 Issue 和补丁;回复可能缓慢或缺失,我可能 会拒绝我无法测试的功能范围。 - 我仅在 **Linux/x86-64 宿主机上测试大端序 `nds32be-unknown-none-elf`**。 小端序 NDS32 和非 Linux 宿主机未经测试 —— 可能差距 不大,但绝对未经核实。 - 当我需要更新的 rustc 时才会变基到更新的 LLVM,而不是按计划进行。 ### 已验证和未验证的内容 | 领域 | 状态 | |---|---| | i32 ALU、移位、比较、分支、select | 已实现,lit + ISS 执行 | | i64(寄存器对,ABI2 偶数对规则) | 已实现,lit + ISS 执行 | | i8/i16 窄位加载/存储,符号/零扩展 | 已实现,lit + ISS 执行 | | 调用、被调用者保存、varargs、alloca、帧指针 | 已实现,lit + ISS 执行 | | 全局地址、常量池、跳转表 | 已实现,lit + ISS 执行 | | PIC(通过 `$gp` 的 GOT/GOTOFF)和 TLS-LE | 已实现,ISS 执行 | | 单精度硬浮点(`v3f`、`v3f-hard`) | 已实现,ISS 执行 | | 16 位压缩 + 分支松弛 | 已实现,ISS 执行 | | 系统寄存器(`mfsr`/`mtsr`) | 已实现,与 binutils 进行差分测试 | | `+reduced-regs`、`+no-16bit` | 已实现,lit 测试 | | ELF 对象、重定位、反汇编器往返测试 | 与 GNU `objdump`/`readelf` 进行交叉检查 | | **双精度硬浮点** | **未实现** | | **链接器松弛** | **未实现** | | **硬浮点 ABI 中的被调用者保存 FPR** | **未实现** | | **小端序 NDS32** | **未测试** | | 执行测试广度 | 有限的;覆盖率良好,但并非详尽无遗 | 构建 ISS 执行循环发现了**八次静默错误编译**,这是 FileCheck 套件无法看到的。这是信任上述各行的主要原因 —— 也是最后一行被表述为剩余风险而非保证的原因。 ## 相关代码库 - [minorum/nds32-llvm](https://github.com/minorum/nds32-llvm) —— 包装器:Rust 目标规格(包括 `nds32be-conn-mcu.json`)、构建和验证 脚本,以及作为子模块的此分支。 - [minorum/mt6785-connsys-firmware](https://github.com/minorum/mt6785-connsys-firmware) —— 消费者:联发科 MT6785 连接 协处理器固件的 Rust 重构版。其 `docs/07-environment-setup.md` 记录了整个 工具链以及如何从零开始重新构建它。 以下是上游 LLVM 的 README。 # LLVM 编译器基础架构 [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/llvm/llvm-project/badge)](https://securityscorecards.dev/viewer/?uri=github.com/llvm/llvm-project) [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/8273/badge)](https://www.bestpractices.dev/projects/8273) [![libc++](https://static.pigsec.cn/wp-content/uploads/repos/cas/49/4924128b2827fad5e9d957cc6eeb1fd1f6e5b73e74ca6e5df2dce43ba82e65e2.svg)](https://github.com/llvm/llvm-project/actions/workflows/libcxx-build-and-test.yaml?query=event%3Aschedule) 欢迎来到 LLVM 项目! 此代码库包含 LLVM 的源代码,这是一个用于 构建高度优化的编译器、优化器和运行时环境的工具包。 LLVM 项目包含多个组件。该项目的核心 本身被称为“LLVM”。它包含处理中间表示并将其转换为 目标文件所需的所有工具、库和头 文件。工具包括汇编器、反汇编器、bitcode 分析器和 bitcode 优化器。 类 C 语言使用 [Clang](https://clang.llvm.org/) 前端。该 组件将 C、C++、Objective-C 和 Objective-C++ 代码编译为 LLVM bitcode —— 然后使用 LLVM 从那里将其转换为目标文件。 其他组件包括: [libc++ C++ 标准库](https://libcxx.llvm.org)、 [LLD 链接器](https://lld.llvm.org) 等。 ## 获取源代码并构建 LLVM 请查阅 [LLVM 入门](https://llvm.org/docs/GettingStarted.html#getting-the-source-code-and-building-llvm) 页面以获取有关构建和运行 LLVM 的信息。 有关如何为 LLVM 项目做贡献的信息,请查看 [为 LLVM 做贡献](https://llvm.org/docs/Contributing.html)指南。 ## 联系我们 加入 [LLVM Discourse 论坛](https://discourse.llvm.org/)、[Discord 聊天](https://discord.gg/xS7Z362)、 [LLVM 办公时间](https://llvm.org/docs/GettingInvolved.html#office-hours) 或 [定期同步会议](https://llvm.org/docs/GettingInvolved.html#online-sync-ups)。 LLVM 项目已为项目内所有沟通方式的参与者采用了 [行为准则](https://llvm.org/docs/CodeOfConduct.html)。
标签:Bash脚本, LLVM, NDS32, 代码生成器, 可视化界面, 嵌入式开发, 指令集架构, 编译器, 逆向工具