报名编号:CICC4035
团队名称:守序善良队
大家好,本篇是我们队伍的第三篇分享,主要内容是对于指令集中back2back情况的简单介绍。水平有限,如有错误,欢迎大家批评指正。
在分析上述问题之前,我们先来想这么一个问题:对于无符号二进制数,两个4位数相乘需要一个几位的寄存器才能保证结果没有溢出呢?答案是我们需要用一个8位的寄存器来存两个4位操作数相乘的结果。但是对于RISC-V架构的CPU来说,它所有的通用寄存器都是32位的,如果我们要进行两个32位操作数的乘法操作,那该如何保存这个操作的结果呢?RISC-V对于乘除法相关的指令设置了一个b2b (back to back) case。在执行Mul/Div指令前,它会首先判断其是否属于back2back fusing类型,如果确实属于下面几种类型就会进行一些判断来保证结果写回的正确性。
(RV32M指令图示)
RV32M具有有符号和无符号整数的除法指令:divide(div)和divide unsigned(divu),它们将商放入目标寄存器。在少数情况下,程序员需要余数而不是商,因此RV32M提供remainder(rem)和 remainder unsigned(remu),它们在目标寄存器写入余数,而不是商。
乘法比除法要更为复杂,是因为积的长度是乘数和被乘数长度的和。将两个 32 位数相乘得到的是 64 位的乘积。为了正确地得到一个有符号或无符号的 64 位积,RISC-V 中带有四个乘法指令。要得到整数 32 位乘积(64 位中的低 32 位)就用 mul 指令。要得到高 32 位,如果操作数都是有符号数,就用 mulh 指令;如果操作数都是无符号数,就用 mulhu 指令;如果一个有符号一个无符号,可以用 mulhsu 指令。在一条指令中完成把 64 位积写入两个 32位寄存器的操作会使硬件设计变得复杂,所以 RV32M 需要两条乘法指令才能得到一个完整的 64 位积。
如果希望得到两个32位整数相乘的完整64位结果,RISC-V架构推荐使用两条连续的乘法指令“MULH[[S]U] rdh, rsl, rs2; MUL rdl, rsl,rs2”, 而对于除法如果希望同时得到两个32位整数相除的商和余数,RISC-V架构推荐使用两条连续的除法和取余指令“DIV[U] rdq, rsl, rs2; REM[U] rdr, rsl, rs2”
(判断标志ifu_muldiv_b2b_nxt数据流通情况)