如何为自定义 CPU 创建 C 编译器?

Posted

技术标签:

【中文标题】如何为自定义 CPU 创建 C 编译器?【英文标题】:How to create a C compiler for custom CPU? 【发布时间】:2012-01-31 13:06:16 【问题描述】:

为自定义 CPU 创建 C 编译器的最简单方法是什么,当然假设我已经有一个汇编器?

既然 C 编译器会生成汇编,有没有办法为各种 C 习惯定义标准的汇编代码片段,重建编译器,从而获得目标硬件的交叉编译器?

编译器本身最好用 C 语言编写,并构建为适用于 Linux 或 Windows 的本机可执行文件。

请注意:不是询问如何编写编译器本身。我确实在大学里学过那门课,我知道一般的编译器,等等。在这种情况下,如果可能的话,我只想配置一些现有的框架。我不想修改语言,我只想能够针对任意架构。如果答案是“它不是那样工作的”,信息将对我自己和任何可能做出类似假设的人有用。

【问题讨论】:

编译器生成汇编程序没有基本要求:这只是一种常见且方便的做法。 @dmckee - 让我们假设在这种情况下这是一个要求。我知道这个社区中有些人会对此有答案。请注意,我要问的答案是不是“去参加编译器写作课程”。 PS:假设你有这个全新的定制 CPU,你甚至没有编译器。 OS 会从哪里来???你是什​​么意思“本机可执行文件”? WHAT?!? 原生 @JustJeff:您要问的是“如何为 GCC 编写我自己的后端?” (如果合适,用“clang”等代替“GCC”)。这仍然很重要,可能最好的起点是相关文档(例如llvm.org/releases/2.3/docs/WritingAnLLVMBackend.html)。 (我会很高兴地承认,在这一点上我已经超出了我的能力范围!) @paulsm4 - 是的,假设它是新的。假设没有操作系统。 “本机可执行文件”用于表示“在 cpu 上执行的二进制文件” 【参考方案1】:

vbcc(位于 www.compilers.de)是一个用 C 编写的优秀且简单的可重定向 C 编译器。它比 GCC/LLVM 简单得多。它是如此简单,我能够在几周的工作中将编译器重新定位到我自己的 CPU,而无需任何编译器的先验知识。

【讨论】:

有趣的选项。通常人们甚至不会想到 gcc/clang/llvm 系列之外的免费编译器。您能否为 OP 详细说明重定向过程是如何完成的? (例如,是否有一个明确定义的中间“通用机器代码”阶段,您只需将或多或少的直接翻译器写入真正的 CPU 指令集?) 是的,VBCC 编译器前端输出各种通用机器代码。它正在调用后端函数(您必须编写的函数)将这些指令翻译成您的目标汇编指令。编译器相当强大并且提供了很好的优化。让一个正常运行(虽然不是很优化)的后端运行起来只需要很少的时间。如果你的目标是尽可能实现最好的代码,那就有点难了。【参考方案2】:

您可以修改现有的开源编译器,例如 GCC 或 Clang。其他答案为您提供了有关在何处了解更多信息的链接。但这些编译器并非旨在轻松重新定位;与为特定目标连接的其他编译器相比,它们比编译器“更容易”重新定位。

但是,如果您想要一个相对容易重定向的编译器,您需要一个可以明确指定机器架构的编译器,并且某些工具会生成编译器的其余部分(GCC 会做一些;我不'认为 Clang/LLVM 做的不多,但我在这里可能是错的)。

文献中有很多这样的,谷歌“compiler-compiler”。

但对于 C 的具体解决方案,您应该查看 ACE,这是一家为客户按需生成编译器的编译器供应商。不是免费的,但我听说他们很快就能产生非常好的编译器。我认为它会生成标准样式的二进制文件(ELF?),因此它会跳过汇编程序阶段。 (我与 ACE 没有任何经验或关系。)

如果您不关心代码质量,您可能会使用 C AST 编写 C 到汇编程序的语法导向翻译。您可以从 GCC、Clang、ANTLR 以及我们的 DMS Software Reengineering Toolkit 获取 C AST。

【讨论】:

【参考方案3】:

简短的回答是它不能那样工作。

更长的答案是,为新的 CPU 类型编写编译器确实需要一些努力。但是,您不需要从头开始创建编译器。大多数编译器都是通过多次传递来构建的;这是一个典型的架构(可能有很多变化):

    句法分析(词法分析器和解析器),以及用于 C 预处理,生成抽象句法树。 类型检查,生成带注释的抽象语法树。 中间代码生成,导致独立于体系结构的中间代码。在这个阶段进行了一些优化。 机器代码生成,导致汇编或直接生成机器代码。在此阶段执行更多优化。

在这个描述中,只有第 4 步是机器相关的。所以你可以在第4步明确分离的地方使用一个编译器,然后插入你自己的第4步。这样做需要对CPU有深入的了解,并对编译器内部有一定的了解,但你不必担心之前发生了什么。

几乎所有不是非常小、非常稀有或非常旧的 CPU 都有一个GCC 的后端(第 4 步)。编写 GCC 后端的主要文档是 GCC internals manual,尤其是关于 machine descriptions 和 target descriptions 的章节。 GCC 是免费软件,因此使用它不需要任何许可费用。

【讨论】:

【参考方案4】:

Quick overview/tutorial on writing a LLVM backend.

本文档描述了为 LLVM 编写后端的技术,这些技术将 LLVM 表示形式转换为机器汇编代码或其他语言。

[ . . . ]

要创建静态编译器(发出文本程序集的编译器),您需要实现以下内容:

描述寄存器集。 描述指令集。 描述目标机器。 为架构实现组装打印机。 为架构实现指令选择器。

【讨论】:

LLVM 非常复杂并且完全没有文档记录。甚至不要碰它。它浪费了我 1 个月的生命。 我就是留下上一条评论的那个人。我已经在 LLVM 上工作了一年半。我可以开发自己的后端并进行组装。是的,掌握 LLVM 基础架构需要一年的时间,但我认为这是值得的。 @Ehsan 你认为你可以写一些文档吗? :-D @wizzwizz4 我可能会在我完成博士论文后去做。【参考方案5】:

1) 简答:

“不。没有“编译器框架”之类的东西,您可以在其中添加水(插入您自己的组装集),搅拌,然后就完成了。”

2) 更长的答案:这当然是可能的。但具有挑战性。而且可能很贵。

如果你想自己做,我会从 Gnu CC 开始。它已经可用于多种 CPU 和平台。

3)查看此链接以获得更多想法(包括“仅构建函数和宏库”的想法),这是我的第一个建议:

http://www.instructables.com/answers/Custom-C-Compiler-for-homemade-instruction-set/

【讨论】:

【参考方案6】:

有一个交叉编译器的概念,即在一种架构上运行,但针对不同的架构。您可以查看 GCC 是如何做到的(例如)并向集合中添加一个新架构,如果那是您想要扩展的编译器。

编辑:几年前我刚刚在 GCC 邮件列表上发现了一个关于如何添加新目标的问题,有人指出 this

【讨论】:

是的。如何添加新架构。请详细说明? 用链接编辑了答案。这是一个有点大的文件,但我想这是要走的路...... 您有没有查看 GCC 源代码,看看它是如何工作的? PS:看gcc源码,看LLVM。我想你会发现两者都提供了丰富的信息...... @paulsm4 - 你知道,这个评论比你实际给出的答案更好。

以上是关于如何为自定义 CPU 创建 C 编译器?的主要内容,如果未能解决你的问题,请参考以下文章

如何为自定义控件创建事件

如何为 iPhone 创建自定义 Interface Builder 插件?

如何为自定义帖子类型创建档案

如何为 QtCreator 创建自定义主题

如何为 AVD 管理器创建自定义 Android 设备配置文件?

如何为 Cloudwatch 创建自定义文本格式化程序?