为了与操作系统以及编译器更好的适配,我们的指令系统在One-page CPU的基础上进行了改动。
指令按格式可以分为R型指令、I型指令、J型指令三种,格式分别如下所示:
R型指令
31-26 | 25-21 | 20-16 | 15-11 | 10-0 |
---|---|---|---|---|
opcode | rx | ry | rz | reserved |
I型指令
31-26 | 25-21 | 20-16 | 15-0 |
---|---|---|---|
opcode | rx | ry | imm |
J型指令
31-26 | 25-0 |
---|---|
opcode | offset |
R型指令
汇编代码 | opcode | 含义 | 注释 |
---|---|---|---|
add $rx, $ry, $rz |
0 | $rx = $ry + $rz; |
|
sub $rx, $ry, $rz |
1 | $rx = $ry - $rz; |
|
mul $rx, $ry, $rz |
2 | $rx = $ry * $rz; |
只取低32位 |
and $rx, $ry, $rz |
4 | $rx = $ry & $rz; |
按位取与 |
or $rx, $ry, $rz |
5 | `$rx = $ry | $rz;` |
xor $rx, $ry, $rz |
6 | $rx = $ry ^ $rz; |
按位取异或 |
shr $rx, $ry, $rz |
9 | $rx = $ry shr $rz; |
逻辑右移,高位补零 |
shl $rx, $ry, $rz |
10 | $rx = $ry shl $rz; |
I型指令
汇编代码 | opcode | 含义 | 注释 |
---|---|---|---|
loa $rx, imm($ry) |
7 | $rx = mem<int32>[$ry + sign-extend(imm)]; |
如果是访问RAM,地址必须是4对齐的 |
sto $rx, imm($ry) |
8 | mem<int32>[$ry + sign-extend(imm)] = $rx; |
同上 |
beq $rx, $ry, imm |
11 | if $rx == $ry then $pc += sign-extend(imm); |
|
blt $rx, $ry, imm |
12 | if $rx u< $ry then $pc += sign-extend(imm); |
无符号比较 |
addiu $rx, $ry, imm |
13 | $rx = $ry + sign-extend(imm); |
|
lui $rx, imm |
14 | $rx = imm << 16, clearing the lower 16 bits; |
|
ori $rx, $ry, imm |
16 | $rx = $ry O zero-extend(imm); |
按位与 |
bne $rx, $ry, imm |
19 | if $rx != $ry then $pc += sign-extend(imm); |
|
jr $rx |
20 | $pc = $rx; |
|
jalr $rx |
21 | $lr = $pc+4; $pc = $rx; |
J型指令
汇编代码 | opcode | 含义 | 注释 |
---|---|---|---|
jsub offset |
22 | $lr = $pc+4; $pc += sign-extend(offset)+4 |
硬件上共支持32个寄存器,编号从0~31,使用约定如下:(有些没有被编译器使用的寄存器在硬件上也存在,所以都列为通用寄存器)
编号 | 名称 | 用途 |
---|---|---|
0 | pc | 保存当前的指令地址 |
1 | sp | 栈指针 |
2 | fp | 栈帧指针, 当前没有使用 |
3 | zr | 0寄存器,其值永远是0 |
4 | fr | 标志位寄存器,保存中断相关信息 |
5 | wr | 字长寄存器,其值永远是4 |
6 | at | 通用寄存器 |
7 | lr | 链接寄存器,储存函数的返回地址 |
8~17 | 通用寄存器 | |
18 | epc | 中断发生地址寄存器 |
19~31 | 通用寄存器 |
这里,fr是一个特殊的寄存器,它保存了一些与中断相关的信息,具体而言:
fr 位 | 含义 |
---|---|
0 | 如果某条指令将这一位置为 1, 则 CPU 停止执行. |
1 | 全局中断使能. |
2 | 如果某条指令将这一位置为 1, 则 CPU 执行 "从异常返回" 指令 (x86 的 iret, mips 的 eret) |
3 | 时钟中断使能 |
4 | 时钟中断, 发生时钟中断时硬件将此位置为 1, 软件必须将其置回为 0 |
5 | 串口可写中断使能, 是否使能因串口变为可写状态而造成的中断 |
6 | 串口可写中断, 发生串口可写中断时硬件将此位置为 1, 软件必须将其置回为 0 |
7 | 串口可读中断使能, 同上 |
8 | 串口可读中断, 发生中断时由硬件置为 1, 软件必须将其置回为 0 |
9 | 串口可写, 为 1 表示串口可写. 软件希望写串口, 则需要写完将此位设为 0. |
10 | 串口可读, 同上. 硬件设为 1, 软件设为 0. |
11 | 当前特权级, 1 为 user, 0 为 kernel |
12 | 缺页异常位, 发生缺页异常时该位被硬件置为 1 |