已使用的操作码:
| opcode | opcode.hex | op | fmt | desc |
|---|---|---|---|---|
| b0000010 | h02 | op32i | I | 32位立即数操作 |
| b0010010 | h12 | op32 | R | 32位操作 |
| b1000010 | h42 | load | I | 加载指令 |
| b1000110 | h46 | loadu | I | 无符号加载指令 |
| b1010010 | h52 | store | S | 存储指令 |
| b1100010 | h62 | lui | U | 加载高位立即数 |
| b1100110 | h66 | auipc | U | 加载PC相对高位立即数 |
| b1110010 | h72 | jal | J | 跳转并链接 |
| b1110110 | h76 | jalr&branch | JALR&B | 跳转并链接寄存器&分支指令 |
MA32I 的指令:
opcode = b0000010
fmt = I
| funct3 | imm[11] | inst | desc | exec |
|---|---|---|---|---|
| b000 | b0 | addi.w | 立即数加法 | x[rd] = x[rs1] + sext(imm); |
| b001 | b0 | slli.w | 立即数左移 | x[rd] = x[rs1] << zext(imm[4:0]); |
| b010 | b0 | slti.w | 立即数小于 | x[rd] = x[rs1] < sext(imm) ? 1 : 0; |
| b011 | b0 | sltui.w | 立即数无符号小于 | x[rd] = x[rs1] <_u sext(imm) ? 1 : 0; |
| b100 | b0 | xori.w | 立即数异或 | x[rd] = x[rs1] ^ sext(imm); |
| b101 | b0 | srli.w | 立即数右移 | x[rd] = x[rs1] >> zext(imm[4:0]); |
| b101 | b1 | srai.w | 立即数算数右移 | x[rd] = x[rs1] >>> zext(imm[4:0]); |
| b110 | b0 | ori.w | 立即数或 | x[rd] = x[rs1] | sext(imm); |
| b111 | b0 | andi.w | 立即数与 | x[rd] = x[rs1] & sext(imm); |
opcode = b0010010
fmt = R
| funct7 | funct3 | inst | desc | exec |
|---|---|---|---|---|
| b0000000 | b000 | add.w | 加法 | x[rd] = x[rs1] + x[rs2]; |
| b0000000 | b001 | sll.w | 左移 | x[rd] = x[rs1] << x[rs2][4:0]; |
| b0000000 | b010 | slt.w | 小于 | x[rd] = x[rs1] < x[rs2] ? 1 : 0; |
| b0000000 | b011 | sltu.w | 无符号小于 | x[rd] = x[rs1] <_u x[rs2] ? 1 : 0; |
| b0000000 | b100 | xor.w | 异或 | x[rd] = x[rs1] ^ x[rs2]; |
| b0000000 | b101 | srl.w | 右移 | x[rd] = x[rs1] >> x[rs2][4:0]; |
| b0000000 | b110 | or.w | 或 | x[rd] = x[rs1] | x[rs2]; |
| b0000000 | b111 | and.w | 与 | x[rd] = x[rs1] & x[rs2]; |
| b1000000 | b000 | sub.w | 减法 | x[rd] = x[rs1] - x[rs2]; |
| b1000000 | b101 | sra.w | 算数右移 | x[rd] = x[rs1] >>> x[rs2][4:0]; |
| opcode | funct3 | inst | fmt | desc | exec |
|---|---|---|---|---|---|
| b1000010 | b000 | lb | I | 加载字节 | x[rd] = sext(mem[x[rs1] + sext(imm)][7:0]); |
| b1000010 | b001 | lh | I | 加载半字 | x[rd] = sext(mem[x[rs1] + sext(imm)][15:0]); |
| b1000010 | b010 | lw | I | 加载字 | x[rd] = sext(mem[x[rs1] + sext(imm)][31:0]); |
| b1000110 | b000 | lbu | I | 无符号加载字节 | x[rd] = zext(mem[x[rs1] + sext(imm)][7:0]); |
| b1000110 | b001 | lhu | I | 无符号加载半字 | x[rd] = zext(mem[x[rs1] + sext(imm)][15:0]); |
| b1010010 | b000 | sb | S | 存储字节 | mem[x[rs1] + sext(imm)][7:0] = x[rs2]; |
| b1010010 | b001 | sh | S | 存储半字 | mem[x[rs1] + sext(imm)][15:0] = x[rs2]; |
| b1010010 | b010 | sw | S | 存储字 | mem[x[rs1] + sext(imm)][31:0] = x[rs2]; |
| opcode | inst | fmt | desc | exec |
|---|---|---|---|---|
| b1100010 | lui | U | 加载高位立即数 | x[rd] = sext(imm); |
| b1100110 | auipc | U | 加载PC相对高位立即数 | x[rd] = pc + sext(imm); |
| b1110010 | jal | J | 跳转并链接 | pc = pc + sext(imm); |
opcode = b1110110
| funct3 | inst | fmt | desc | exec |
|---|---|---|---|---|
| b000 | jalr | JALR | 跳转并链接寄存器 | pc = x[rs1] + sext(imm); |
| b010 | beq | B | 等于时跳转 | if(x[rs1] == x[rs2]) pc = pc + sext(imm); |
| b011 | bne | B | 不等于时跳转 | if(x[rs1] != x[rs2]) pc = pc + sext(imm); |
| b100 | blt | B | 小于时跳转 | if(x[rs1] < x[rs2]) pc = pc + sext(imm); |
| b101 | bge | B | 大于等于时跳转 | if(x[rs1] >= x[rs2]) pc = pc + sext(imm); |
| b110 | bltu | B | 无符号小于时跳转 | if(x[rs1] <_u x[rs2]) pc = pc + sext(imm); |
| b111 | bgeu | B | 无符号大于等于时跳转 | if(x[rs1] >=_u x[rs2]) pc = pc + sext(imm); |
MA32I 共计 37 条指令,使用了 9 个操作码,预留空间为 93.0%()。
关于指令格式,请参考本人写的第一篇文章。