有没有什么好方法可以将TAC转换为x86-64程序集?

时间:2017-05-20 09:43:31

标签: assembly compiler-construction x86-64

例如,我想将TAC add c a b(意为c := a + b)转换为x86程序集。为简单起见,假设a, b, c是所有寄存器。但x86只有ADD a b,表示a += b

我的想法是先将0移至c,然后移至ADD c aADD c b。但是,我将一个TAC转换为三个汇编语句,而在MIPS中,我只需要一行add c a b

有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

是的,先前在TAC修复它。

我知道有两种主要技术,第一种是简单地重写这样的一切:

xor c a b

进入这个:

copy c a
xor c c b

这基本上就像你描述的那样:

  

我的想法是先将0移至c,然后执行ADD c a和ADD c b

但是在TAC级别,并且复制而不是零/添加,零/添加很奇怪。

现在,如果运行寄存器分配器,则会自动满足所有2操作数约束。当然,任何自我复制都以零指令结束,并且您可以通过尝试合并副本的虚拟寄存器来使寄存器分配器更喜欢安排它。大部分副本都将被避免。

另一种技术基本上是做同样的事情,但是在第一次运行寄存器分配器时未能合并之后懒惰地插入副本。根据寄存器分配器的工作原理,这需要权衡一点。它可以防止TAC大小几乎翻倍(然后依靠指令选择来忽略大多数副本),但运行寄存器分配器两次。是否更慢或更快取决于寄存器分配器的工作方式。

你可以通过尝试合并具有2操作数约束的操作的源和dest,如果失败则接受它,然后让指令选择器具有不同的情况,如果约束是否满足,则可以隐式地执行它。这基本上将复杂性推入指令选择器,这已经足够糟糕,所以我不喜欢这样做。

我已将操作更改为xor,因为add在x86上有一个3操作数版本,lea - 除非您需要标记,在这种情况下您当然可以做复制/优先合并的事情。