为LLVM/CLANG选择CPU架构

Bar*_*ter 15 hardware cpu llvm clang

我正在设计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 ++功能是可能的,还是我需要更复杂的硬件来生成合理质量和速度的代码?

Jan*_*ray 18

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

我认为你是否应该构建8位变体并使用3个add-with-carry来增加IP,或24位变量并在硬件中完成整个过程,这并不是很重要.您可以隐藏汇编程序中的差异.

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

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

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

lbs rd,imm(rs) ->
  lbu rd,imm(rs)
  lea r1,0x80
  xor rd,r1
  sub rd,r1
Run Code Online (Sandbox Code Playgroud)

所以我认为你可以通过这个最小的操作覆盖:

  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
Run Code Online (Sandbox Code Playgroud)

更简单的是没有寄存器(或等效地模糊寄存器与存储器 - 所有寄存器都有一个存储器地址).

为SP指定寄存器,并在编译器中编写函数prolog/epilog处理程序,您不必担心堆栈指令.只有代码存储每个被调用者保存寄存器,按帧大小调整SP,等等.

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

有趣的项目.我看到一场TTL/7400比赛正在进行中,我正在考虑一台机器如何简单易用,并且在机器上添加一个32 KB或128 KB的异步SRAM来保存代码和数据是不应该的.

无论如何,快乐的黑客!

PS

1)您将需要决定每个整数类型的大小.如果你愿意,你当然可以使char,short,int,long,long long等具有相同的大小,一个24b字,尽管它不符合最小表示范围.

2)虽然我在这里专注于lcc,但你问的是C++.我建议首先考虑C.一旦你找到C的东西,包括软件中的*,/,%运算符等,无论是在LLVM还是GCC中,转向完全成熟的C++都应该更容易处理.C和C++之间的区别是"仅"处理虚函数调用所需的额外vtable和RTTI表和代码序列(完全由原始C整数运算符repetoire构建),指向成员解引用的指针,动态转换,静态构造函数,异常处理等

  • ps我在想.您应该优先构建24b变体,而不是8b变体.这不是因为更广泛的数据操作每个都需要多个指令,而是因为您确实需要一个用于指令和数据的线性24b地址空间的概念.虽然您可以从3个8b负载中合成24b负载,但您需要24b地址(以及24b地址增量)来处理硬件中的指令获取,程序计数器和PC增量.如果您只有8b地址,则不清楚如何处理大于256条指令的程序. (2认同)