学习目标

  • 实现 R 型和 I 型指令
  • 理解算术运算
  • 掌握逻辑运算

7.1 思考:最简单的指令是什么?

你觉得哪条指令最简单?

答案可能是 add

add x1, x2, x3  # x1 = x2 + x3

就是简单的加法!但实现起来有细节。

7.2 R 型指令格式

add  rd, rs1, rs2  # rd = rs1 + rs2
sub  rd, rs1, rs2  # rd = rs1 - rs2
and  rd, rs1, rs2  # rd = rs1 & rs2

问题:add 和 sub 的 opcode 一样吗?

是的!都是 0x33。那怎么区分?

答案:看 funct7funct3

add: funct7=0x00, funct3=0x0
sub: funct7=0x20, funct3=0x0

7.3 实现 R 型指令

void exec_R_type(Decode d) {
    uint32_t src1 = reg_read(d.rs1);
    uint32_t src2 = reg_read(d.rs2);
    uint32_t result;

    switch (d.funct3) {
        case 0x0:  // ADD/SUB
            if (d.funct7 == 0x00) {
                result = src1 + src2;  // ADD
            } else {
                result = src1 - src2;  // SUB
            }
            break;
        case 0x7:  // AND
            result = src1 & src2;
            break;
        // ...
    }

    reg_write(d.rd, result);
}

问题:为什么不用 int 而用 uint32_t?

因为 RISC-V 寄存器是 32 位无符号数!

7.4 I 型指令

addi x1, x2, 10  # x1 = x2 + 10

问题:addi 和 add 有什么区别?

一个用立即数,一个用寄存器!

void exec_I_type(Decode d) {
    uint32_t src1 = reg_read(d.rs1);
    uint32_t result = src1 + d.imm;
    reg_write(d.rd, result);
}

7.5 移位指令的陷阱

slli x1, x2, 5  # x1 = x2 << 5

问题:移位 5 位,立即数是 5 吗?

是的!但只用低 5 位(因为最多移 31 位)。

case 0x1:  // SLLI
    result = src1 << (d.imm & 0x1F);
    break;

下一步

第 8 章:访存指令

更新时间: