实验4 RISC-V⽬标代码⽣成

实验4 RISC-V⽬标代码⽣成

本次实验的⽬标是从实验3⽣成的中间表示出发,⽣成 RISC-V 32 的汇编代码,并在 venus 模拟 器上运⾏。 如果你对 RISC-V 汇编不那么熟悉,可以参考 Crash Course。 ⽬标代码⽣成 回顾⼀下,我们已经可以将源代码转换为⼀种⾃定义的中间代码表示,它可以在⼀个⾃定义虚拟 机器上解释执⾏。和实际机器不同,虚拟机允许你使⽤⽆限寄存器,并给你提供了⼀些⽅便的关 于函数调⽤的指令。 ⽽⾯对⼀个实际的机器,如在本实验使⽤的 RISC-V 32 指令集下,这些假设 都不再成⽴。为了⽣成最终⽬标代码,有以下三个问题需要你解决: 指令选择 ⾸先我们注意到中间代码和汇编代码格式是不⼀样的,我们要对每⼀种中间代码找到⼀个特定的 模式,翻译成对应的⽬标代码,这个过程就是指令选择。 考虑到在本实验中实现的中间表示是 线性的,最直接的⽅式就是将每⼀条中间代码翻译成⼀条或多条⽬标代码。 下表是部分中间代 码与 RISC-V 32 指令对应的⼀个示例,⼤部分的逻辑都是显然的:
优化的可能 这样直截了当的对应的确能够满⾜我们的需求,但我们可能会⽣成很多冗余的指令,会影响程序 的运⾏效率。例如,我们可能会⽣成下⾯这样的代码: 但这条指令可以被下⾯这条指令替代: 这个例⼦启示我们,直接翻译得到的代码很有可能是低效的,我们需要⼀些⽅法来优化⽣成的代 码。⽐如你可以采⽤滑动窗⼝的⽅法,来检查是否有可以合并的指令序列。例如上述的寻址模拟 即可简化代码。 除此之外,你可能已经发现了,我们在⽬标代码中对于某⼀个中间代码中的变量 a 使⽤的是 reg(a) ,意为储存该变量的寄存器。那么我们怎么知道⽤哪个寄存器储存变量呢?这也就引出 了下⼀个问题:寄存器分配。 寄存器分配 对于中间代码中的全局变量,我们可以直接映射到⽬标代码的上,这是⽐较简单的。 但是除此 之外,我们还使⽤了数⽬不受限的变量和临时变量,但处理器所拥有的寄存器数量是有限的。因 此我们需要将中间代码中的变量映射到寄存器上,这个过程就是寄存器分配。 朴素的寄存器分配 最朴素的寄存器分配⽅法当然是把⼏乎所有临时变量都存储在内存中,也就是栈上。 每翻译⼀ 条中间代码之前我们把要⽤到的变量先加载到寄存器中,得到计算结果后⼜将结果写回内存。这 种⽅法的确能将中间代码翻译成可以正常运⾏的⽬标代码,⽽且实现和调试都特别容易。 基于图染⾊的寄存器分配 朴素的寄存器分配⽅法虽然简单,但是⽣成的代码效率很低。我们可以考虑使⽤⼀些更加⾼级的 寄存器分配算法来优化⽣成的代码。 同学们已经在课程中学习过了基于图染⾊的寄存器分配⽅ 法,在对程序进⾏活跃变量分析之后,我们可以根据活跃变量的信息构造⼀个冲突图,然后使⽤ 图染⾊算法来进⾏寄存器分配。 这⾥不再赘述。 栈的管理 完成了指令选择和寄存器分配,代码⽣成还剩最后⼀个问题需要解决。同学们肯定注意到了中间 代码中的函数调⽤返回和参数的传递与使⽤被抽象为 CALL, RETURN, ARG, PARAM 等特殊的指 li a1, 0 ecall addi a0 t1 8 lw a0 0(a0) lw a0 8(t1) 令。这(或许)让同学们在中间代码⽣成的时候少了不少麻烦,但在⽬标代码中,我们必须使⽤ 寄存器和栈来完成这⼀点。 所以我们最后要解决的就是有关函数调⽤的细节,包括函数调⽤时 参数的传递,寄存器的保存,函数调⽤时栈的管理,函数返回时寄存器的恢复等。 那么我们具体该怎么做呢?对于 ARG 和 PARAM 这两个指令,我们可以简单的根据 RISCV 的调 ⽤规范,将实参传递到 a0-a7 这⼏个寄存器中,读取参数的时候再从这⼏个寄存器中取出即可, 注意这可能会影响到寄存器分配的结果。 当函数的参数个数超过调⽤规范中规定的个数时,我 们则需要将多余的参数保存到栈上, 对于 CALL 和 RETURN 这两个指令,我们则需要正确的管 理整个活动记录(activation record)。同学们在课堂上也已经学过了相关的内容。 ⽽在本实验 中,我们其实只需要最简单的管理栈指针⽅式,即在函数调⽤时将栈指针减去相应栈帧的⼤⼩, 函数返回时再将栈指针恢复即可。栈帧的⼤⼩则来⾃于函数的局部变量⼤⼩加上函数调⽤时要保 存到栈上的值的⼤⼩(如 ra),具体取决于你的栈帧设计。 具体细节和实现⽅式留给同学们⾃⼰探 索。 Venus模拟器 我们的实验评测会在 venus,⼀个 RISCV 模拟器上进⾏。 Venus ⽀持 RV32M 指令集,即在基础 的 RV32I 指令集加上乘法,除法和取模指令。对于中间代码中的这些运算,你不需要⾃⼰实现。 Venus ⽀持⼀些基础的环境调⽤,我们可以⽅便进⾏输⼊输出交互。如果我们想要调⽤⼀个环境 调⽤,将 ID 加载到寄存器 a0 中,将所需要的参数加载到 a1-a7 中,然后执⾏ ecall 指令即 可。 返回值都同样存储在这些寄存器中。Venus ⽀持下列环境调⽤:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值