首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >LLVM/CLANG CPU体系结构的选择

LLVM/CLANG CPU体系结构的选择
EN

Stack Overflow用户
提问于 2011-09-20 11:38:16
回答 5查看 6.8K关注 0票数 15

我正在设计TTL系列计算机,我正在努力选择更适合LLVM编译器后端的体系结构(我希望能够在那里运行任何C++软件)。没有MMU,没有乘法/除法,没有硬件栈,没有中断。

我有两个主要选择:

1) 8位存储器、8位ALU、8位寄存器(~12-16).内存地址宽度24位。因此,我需要使用3个寄存器作为IP和3个寄存器的任何内存位置。

不用说,在编译器中实现任何地址计算都是很痛苦的。

2) 24位存储器、24位ALU、24位寄存器(~6-8).记性平平,不错。缺点是,由于设计的串行性质,每次操作将花费3倍的时钟,即使我们是在一些布尔人上操作。24位内存数据宽度是昂贵的。而且在硬件上更难实现。

问题是:您认为在这种8位、无堆栈的硬件上实现所有c++功能是可能的,还是我需要更复杂的硬件来生成质量和速度合理的代码?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-09-26 04:08:42

我赞成使用LCC的建议。我在这个自制的16位RISC项目中使用了它:http://fpgacpu.org/xsoc/cc.html

我认为无论是构建8位变体并使用3加载项增加IP,还是使用24位变体并在硬件上完成全部工作,都不应该有太大的区别。您可以在汇编程序中隐藏差异。

如果您看我上面的文章,或者这里的一个更简单的CPU:http://fpgacpu.org/papers/soc-gr0040-paper.pdf,您将看到您真的不需要那么多操作符/指令来覆盖整数C重复线。实际上,有一个lcc实用程序(ops)来打印给定机器的min操作符集。

有关更多信息,请参阅我关于将lcc移植到新机器的文章:http://www.fpgacpu.org/usenet/lcc.html

一旦我移植了lcc,我就编写了一个汇编程序,它从基本的汇编程序中合成了一个更大的指令累进。例如,我的机器有加载字节无符号但没有加载字节签名,所以我发出了以下序列:

代码语言:javascript
运行
复制
lbs rd,imm(rs) ->
  lbu rd,imm(rs)
  lea r1,0x80
  xor rd,r1
  sub rd,r1

所以我认为你可以通过这个最小的行动:

代码语言:javascript
运行
复制
  registers
  load register with constant
  load rd = *rs
  store *rs1 = rs2
  + - (w/ w/o carry)    // actually can to + with - and ^
  >> 1                  // << 1 is just +
  & ^                   // (synthesize ~ from ^, | from & and ^)
  jump-and-link rd,rs   // rd = pc, pc = rs
  skip-z/nz/n/nn rs     // skip next insn on rs==0, !=0, <0, >=0

更简单的做法是没有寄存器(或者与内存等效的模糊寄存器--所有寄存器都有一个内存地址)。

为SP预留一个寄存器,并在编译器中编写prolog/epilog处理程序,您就不必担心堆栈指令了。只有代码来存储每个被调用的保存寄存器,根据帧大小调整SP,等等。

中断(以及从中断返回)非常简单。您所需要做的就是强制跳转和链接指令到指令寄存器.如果您选择了类似于0的位模式,并将正确的地址放入源寄存器rs (特别是如果是r0),则可以使用触发器复位输入或额外的力到-0和门来完成。我在上面的第二篇论文中使用了类似的技巧。

有趣的项目。我看到一场TTL / 7400竞赛正在进行中,我在想,一台机器有多简单,你能逃过一劫吗?在机器上添加32 KB或128 KB异步SRAM来保存代码和数据是作弊的。

不管怎么说,黑客很开心!

附注:

1)你会想要决定每种积分类型有多大。当然,如果您愿意,可以使char、short、int、long、long等大小相同,一个24b字,尽管它在min表示范围内不兼容。

2)虽然我在这里关注的是lcc,但您询问的是C++。我建议先说服C。一旦你弄清楚了C的东西,包括*,/,软件中的%操作符等等,那么无论是在LLVM还是在GCC,都应该更容易使用完全成熟的C++。C和C++之间的区别是“仅”处理虚拟函数调用、成员取消引用指针、动态转换、静态构造函数、异常处理等所需的额外vtable和RTTI表和代码序列(完全建立在原始C整数运算符同步器上)。

票数 17
EN

Stack Overflow用户

发布于 2011-09-25 03:03:12

IMHO,c编译器是可能的。不过,我不太确定c++的情况。

对于8位计算机来说,LLVM/CLang是很难选择的,

相反,首先尝试lcc,然后再尝试llvm/etc,HTH。

比尔·布兹比成功地为他的魔术-1(被称为自制啤酒)重新获得lcc编译器。

虽然Magic-1的硬件设计和构建通常得到最广泛的关注,但是项目的最大部分(到目前为止)已经开发/移植了该软件。为此,我必须从头开始编写汇编程序和链接器,重定向C编译器,编写和移植标准C库,编写简化的操作系统,然后移植更复杂的操作系统。这是个挑战,但很有趣。我想我有点扭曲,但我碰巧喜欢调试困难的问题。而且,当您试图跟踪的bug可能涉及一个或多个:硬件设计缺陷、松线或断线、松散或坏的TTL芯片、汇编程序错误、链接程序错误、编译器错误、C运行时库错误,或者是程序中的一个bug,都有很多好玩的机会。哦,我也不想把虫子怪在其他人身上。

我一直很惊讶这该死的东西居然跑得那么好,更不用说跑得那么好了。

票数 3
EN

Stack Overflow用户

发布于 2011-09-22 17:15:19

在我看来,无堆栈硬件已经不适合C和C++代码。如果您有嵌套函数调用,您将需要在软件中模拟堆栈,这当然要慢得多。

在使用无堆栈路径时,您可能会将大部分变量分配为“静态”,并且没有可重入的函数。在这种情况下,6502风格的寻址模式是有效的.例如,您可以使用以下寻址模式:

  1. 即时地址(24位)作为操作码的一部分
  2. 即时地址(24位)加索引寄存器(8位)
  3. 间接访问:内存的直接24位地址,其中包含实际地址
  4. 间接访问: 24位地址到内存,8位索引寄存器从内存中添加值。

上面概述的地址模式将允许有效地访问以固定地址(静态分配)分配的数组、结构和对象。对于动态和堆栈分配的对象,它们的效率较低(但仍然可用)。

你也会从你的串行设计中得到一些好处:通常24位+8位加法不需要24个周期,但是你可以在进位为0时缩短加法。

与直接将IP映射为寄存器不同,您可以只允许使用与上面相同的地址模式,通过goto/分支指令对其进行更改。跳转到动态计算的地址是非常罕见的,所以在操作码中直接给出整个24位地址是更有意义的。

我认为,如果您仔细设计CPU,您可以非常有效地使用许多C++功能。但是,不要期望任何随机的C++代码都会在如此有限的CPU上快速运行。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7484466

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档