Skip to content

Commit

Permalink
实现了RV-M 指令集扩展,支持了乘除法
Browse files Browse the repository at this point in the history
  • Loading branch information
ponyma committed Mar 27, 2023
1 parent ad6fa7b commit b5cbfc8
Show file tree
Hide file tree
Showing 9 changed files with 223 additions and 24 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Java实现的RSIC-V教学虚拟机。采用RV32I指令集
Java实现的RSIC-V教学虚拟机。采用RV32IM指令集

ponyvm-rv32i 构建打包

Expand All @@ -14,4 +14,4 @@ java -jar PonyVM-0.0.1.jar -f pi.bin

C样例编译 采用了ESP32C3的工具链 riscv32-esp-elf-gcc

riscv32-esp-elf-gcc -march=rv32i loop.s -o loop.bin
riscv32-esp-elf-gcc -march=rv32im loop.s -o loop.bin
83 changes: 66 additions & 17 deletions src/main/java/com/ponyvm/soc/core/CPU.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ public boolean executeInstruction() {
Instruction inst = InstructionDecode(pc);
String instAddr = Integer.toUnsignedString(pc, 16);
// 打印指令操作码
// System.out.println(Integer.toUnsignedString(pc, 16) + ":" + inst.assemblyString);
// System.out.println(Integer.toUnsignedString(pc, 16) + ":" + inst.toAssemblyString());
switch (inst.opcode) {
// R-type instructions
case 0b0110011: // ADD / SUB / SLL / SLT / SLTU / XOR / SRL / SRA / OR / AND
// R-type instructions 包含 RVI RVM
case 0b0110011: // ADD / SUB / SLL / SLT / SLTU / XOR / SRL / SRA / OR / AND /MUL /MULH /MULHSU /MULHU /DIV /DIVU /REM /REMU
rType(inst);
break;

Expand Down Expand Up @@ -101,45 +101,94 @@ public boolean executeInstruction() {
*/
private void rType(Instruction inst) {
switch (inst.funct3) {
case 0b000: // ADD / SUB
case 0b000: // ADD / SUB /MUL
switch (inst.funct7) {
case 0b0000000: // ADD
reg[inst.rd] = reg[inst.rs1] + reg[inst.rs2];
break;
case 0b0100000: // SUB
reg[inst.rd] = reg[inst.rs1] - reg[inst.rs2];
break;
case 0b0000001: // MUL 有符号*有符号 低32位
reg[inst.rd] = reg[inst.rs1] * reg[inst.rs2];
break;
}
break;
case 0b001: // SLL
reg[inst.rd] = reg[inst.rs1] << reg[inst.rs2];
case 0b001: // SLL /MULH
switch (inst.funct7) {
case 0b0000000: // SLL
reg[inst.rd] = reg[inst.rs1] << reg[inst.rs2];
break;
case 0b0000001: // MULH 有符号*有符号 高32位
reg[inst.rd] = (int) (((long) reg[inst.rs1]) * reg[inst.rs2] >> 32);
break;
}
break;
case 0b010: // SLT
if (reg[inst.rs1] < reg[inst.rs2]) reg[inst.rd] = 1;
else reg[inst.rd] = 0;
case 0b010://SLT MULHSU
switch (inst.funct7) {
case 0b0000000: // SLT
if (reg[inst.rs1] < reg[inst.rs2]) reg[inst.rd] = 1;
else reg[inst.rd] = 0;
break;
case 0b0000001: // MULHSU 有符号*无符号 高32位
reg[inst.rd] = (int) ((reg[inst.rs1] * Integer.toUnsignedLong(reg[inst.rs2])) >> 32);
break;
}
break;
case 0b011: // SLTU
if (Integer.toUnsignedLong(reg[inst.rs1]) < Integer.toUnsignedLong(reg[inst.rs2])) reg[inst.rd] = 1;
else reg[inst.rd] = 0;
switch (inst.funct7) {
case 0b0000000: //SLTU
if (Integer.toUnsignedLong(reg[inst.rs1]) < Integer.toUnsignedLong(reg[inst.rs2]))
reg[inst.rd] = 1;
else reg[inst.rd] = 0;
break;
case 0b0000001: // MULHU 无符号*无符号 高32位
reg[inst.rd] = (int) ((Integer.toUnsignedLong(reg[inst.rs1]) * Integer.toUnsignedLong(reg[inst.rs2])) >> 32);
break;
}
break;
case 0b100: // XOR
reg[inst.rd] = reg[inst.rs1] ^ reg[inst.rs2];
case 0b100: // XOR /DIV
switch (inst.funct7) {
case 0b0000000: //XOR
reg[inst.rd] = reg[inst.rs1] ^ reg[inst.rs2];
break;
case 0b0000001: // DIV
reg[inst.rd] = reg[inst.rs1] / reg[inst.rs2];
break;
}
break;
case 0b101: // SRL / SRA
case 0b101: // SRL / SRA /DIV
switch (inst.funct7) {
case 0b0000000: // SRL
reg[inst.rd] = reg[inst.rs1] >>> reg[inst.rs2];
break;
case 0b0100000: // SRA
reg[inst.rd] = reg[inst.rs1] >> reg[inst.rs2];
break;
case 0b0000001: // DIVU
reg[inst.rd] = (int) ((Integer.toUnsignedLong(reg[inst.rs1]) / Integer.toUnsignedLong(reg[inst.rs2])));
break;
}
break;
case 0b110: // OR
reg[inst.rd] = reg[inst.rs1] | reg[inst.rs2];
switch (inst.funct7) {
case 0b0000000: // OR
reg[inst.rd] = reg[inst.rs1] | reg[inst.rs2];
break;
case 0b0000001: // REM
reg[inst.rd] = reg[inst.rs1] % reg[inst.rs2];
break;
}
break;
case 0b111: // AND
reg[inst.rd] = reg[inst.rs1] & reg[inst.rs2];
case 0b111: // AND /REMU
switch (inst.funct7) {
case 0b0000000: // AND
reg[inst.rd] = reg[inst.rs1] & reg[inst.rs2];
break;
case 0b0000001: // REMU
reg[inst.rd] = (int) ((Integer.toUnsignedLong(reg[inst.rs1]) % Integer.toUnsignedLong(reg[inst.rs2])));
break;
}
break;
}
pc += 4;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/ponyvm/soc/core/Instruction.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ private int getImmJ(int instruction) {
return (b20 << 20 | b12to19 << 12 | b11 << 11 | b1to10 << 1);
}

private String toAssemblyString() {
public String toAssemblyString() {
String instr = "", arg1 = "", arg2 = "", arg3 = "";
switch (opcode) {
// R-type instructions
Expand Down
7 changes: 3 additions & 4 deletions src/main/java/com/ponyvm/soc/internal/ram/Memory.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@

import com.ponyvm.soc.internal.sysbus.Addressable;

/**
* 数据以小端进行保存
*/
public class Memory implements Addressable {
private byte[] memory;

/**
* Constructor for Memory
* Initializes as a byte array of size given by argument
*/
public Memory(int capacity) {
memory = new byte[capacity];
}
Expand Down
Binary file modified src/test/resources/pi.bin
Binary file not shown.
117 changes: 117 additions & 0 deletions src/test/resources/pi.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
.file "pi.c"
.option nopic
.attribute arch, "rv32i2p1_m2p0"
.attribute unaligned_access, 0
.attribute stack_align, 16
.text
.globl __muldf3
.globl __floatsidf
.globl __divdf3
.globl __adddf3
.globl __fixdfsi
.align 2
.globl main
.type main, @function
main:
addi sp,sp,-32
sw ra,28(sp)
sw s0,24(sp)
sw s2,20(sp)
sw s3,16(sp)
addi s0,sp,32
sw zero,-32(s0)
sw zero,-28(s0)
sw zero,-20(s0)
j .L2
.L5:
lw a5,-20(s0)
andi a5,a5,1
beq a5,zero,.L3
lui a5,%hi(.LC0)
lw a4,%lo(.LC0)(a5)
lw a5,%lo(.LC0+4)(a5)
j .L4
.L3:
lui a5,%hi(.LC1)
lw a4,%lo(.LC1)(a5)
lw a5,%lo(.LC1+4)(a5)
.L4:
lui a3,%hi(.LC2)
lw a2,%lo(.LC2)(a3)
lw a3,%lo(.LC2+4)(a3)
mv a0,a4
mv a1,a5
call __muldf3
mv a4,a0
mv a5,a1
mv s2,a4
mv s3,a5
lw a5,-20(s0)
slli a5,a5,1
addi a5,a5,1
mv a0,a5
call __floatsidf
mv a4,a0
mv a5,a1
mv a2,a4
mv a3,a5
mv a0,s2
mv a1,s3
call __divdf3
mv a4,a0
mv a5,a1
mv a2,a4
mv a3,a5
lw a0,-32(s0)
lw a1,-28(s0)
call __adddf3
mv a4,a0
mv a5,a1
sw a4,-32(s0)
sw a5,-28(s0)
lw a5,-20(s0)
addi a5,a5,1
sw a5,-20(s0)
.L2:
lw a4,-20(s0)
li a5,8192
addi a5,a5,1807
ble a4,a5,.L5
lui a5,%hi(.LC3)
lw a2,%lo(.LC3)(a5)
lw a3,%lo(.LC3+4)(a5)
lw a0,-32(s0)
lw a1,-28(s0)
call __muldf3
mv a4,a0
mv a5,a1
mv a0,a4
mv a1,a5
call __fixdfsi
mv a5,a0
mv a0,a5
lw ra,28(sp)
lw s0,24(sp)
lw s2,20(sp)
lw s3,16(sp)
addi sp,sp,32
jr ra
.size main, .-main
.section .rodata
.align 3
.LC0:
.word 0
.word -1074790400
.align 3
.LC1:
.word 0
.word 1072693248
.align 3
.LC2:
.word 0
.word 1074790400
.align 3
.LC3:
.word 0
.word 1093567616
.ident "GCC: (xPack GNU RISC-V Embedded GCC x86_64) 12.2.0"
Binary file added src/test/resources/short.bin
Binary file not shown.
8 changes: 8 additions & 0 deletions src/test/resources/short.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//short _sum[4096] = {32765,-32688,2688,5656,45656,4535,4556,56356};
//short i = 13414;
//short j = 32123;
int main(void)
{
int div1 = 32765;
return div1/2;
}
26 changes: 26 additions & 0 deletions src/test/resources/short.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.file "short.c"
.option nopic
.attribute arch, "rv32i2p1_m2p0"
.attribute unaligned_access, 0
.attribute stack_align, 16
.text
.align 2
.globl main
.type main, @function
main:
addi sp,sp,-32
sw s0,28(sp)
addi s0,sp,32
li a5,32768
addi a5,a5,-3
sw a5,-20(s0)
lw a5,-20(s0)
srli a4,a5,31
add a5,a4,a5
srai a5,a5,1
mv a0,a5
lw s0,28(sp)
addi sp,sp,32
jr ra
.size main, .-main
.ident "GCC: (xPack GNU RISC-V Embedded GCC x86_64) 12.2.0"

0 comments on commit b5cbfc8

Please sign in to comment.