Commit Diff


commit - 461d14981023044f01a4a27fe87ddaa313bc5e39
commit + 166c6b70ce597414f40e5a3e2ba33f1572c0b8a4
blob - ebe99ece4176b423afb04d660bc2f31790770808
blob + b88ff85a5f3c5a6be87cde2b332b0bfcdf00d464
--- Makefile
+++ Makefile
@@ -6,8 +6,8 @@ SUDO	= doas
 PREFIX	= /usr/local
 
 CROSS	= riscv64-unknown-linux-musl
-CFLAGS	= -fPIC -O3
-LDFLAGS	= -s -pie -static -lpthread$ -lutil
+CFLAGS	= -std=c2x -fPIC -O3
+LDFLAGS	= -s -pie -static -lpthread
 OBJ	= rvemu.o ecall.o cpu.o exec.o
 PROGS	= test.elf hello.elf
 
blob - f12b40ff570310c03a64afafdf2dcb151c7f4878
blob + a8e4ca5cef165745638682cdc3cd92323f4b09ea
--- cpu.c
+++ cpu.c
@@ -46,6 +46,7 @@ void cpu_exec (u32 instr)
 		| (((instr >> 21) & 0x3ff) << 1)
 		| (((instr >> 20) & 1) << 11)
 		| (((instr >> 12) & 0xff) << 12));
+	const u16 funct10 = (funct7 << 3) | funct3;
 	const u8 shamt = imm_i & 0x3f;
 
 	u64 a, b, c;
@@ -64,11 +65,15 @@ void cpu_exec (u32 instr)
 		pc += imm_j - 4;
 		break;
 	case 0b1100111: // jalr rd, rs1, iimm
-		if (funct3 != 0b000)
+		switch (funct3) {
+		case 0b000:
+			eprintf ("jalr x%u, x%u, %d\n", (uint)rd, (uint)rs1, (int)imm_i);
+			cpu_set (rd, pc);
+			pc = cpu_get (rs1);
+			break;
+		default:
 			goto ud;
-		eprintf ("jalr x%u, x%u, %d\n", (uint)rd, (uint)rs1, (int)imm_i);
-		cpu_set (rd, pc);
-		pc = cpu_get (rs1);
+		}
 		break;
 	case 0b1100011: // bcc rs1, rs2, bimm
 		a = cpu_get (rs1);
@@ -175,6 +180,8 @@ void cpu_exec (u32 instr)
 			c = a + b;
 			break;
 		case 0b001: // slli
+			if (funct7 != 0)
+				goto ud;
 			name = "slli";
 			c = a << shamt;
 			break;
@@ -191,12 +198,17 @@ void cpu_exec (u32 instr)
 			c = a ^ b;
 			break;
 		case 0b101: // srli/srai
-			if ((instr >> 30) & 1) {
-				name = "srai";
-				c = (i64)a >> shamt;
-			} else {
+			switch (funct7) {
+			case 0b0000000:
 				name = "srli";
 				c = a >> shamt;
+				break;
+			case 0b0100000:
+				name = "srai";
+				c = (i64)a >> shamt;
+				break;
+			default:
+				goto ud;
 			}
 			break;
 		case 0b110: // ori
@@ -231,12 +243,16 @@ void cpu_exec (u32 instr)
 		case 0b101: // srliw/sraiw
 			if (shamt >> 5)
 				goto ud;
-			if (c) {
-				name = "srai";
-				c = (i64)a >> shamt;
-			} else {
-				name = "srli";
-				c = a >> shamt;
+			switch (funct7) {
+			case 0b0000000:
+				name = "srliw";
+				c = (u32)a >> shamt;
+				break;
+			case 0b0100000:
+				name = "sraiw";
+				c = (i32)a >> shamt;
+			default:
+				goto ud;
 			}
 			break;
 		default:
@@ -301,30 +317,27 @@ void cpu_exec (u32 instr)
 	case 0b0111011: // aluw
 		a = cpu_get (rs1);
 		b = cpu_get (rs2);
-		c = (instr >> 30) & 1;
-		switch (funct3) {
-		case 0b000: // addw/subw
-			if (c) {
-				name = "subw";
-				c = a - b;
-			} else {
-				name = "addw";
-				c = a + b;
-			}
+		switch (funct10) {
+		case 0b0000000'000: // addw
+			name = "addw";
+			c = a + b;
 			break;
-		case 0b001: // sllw
+		case 0b0100000'000: // subw
+			name = "addw";
+			c = a - b;
+			break;
+		case 0b0000000'001: // sllw
 			name = "sllw";
 			c = a << (b & 0x1f);
 			break;
-		case 0b101: // srlw/sraiw
-			if (c) {
-				name = "sraw";
-				c = (i64)a >> (b & 0x1f);
-			} else {
-				name = "srlw";
-				c = a >> (b & 0x1f);
-			}
+		case 0b0000000'101: // srlw
+			name = "srlw";
+			c = a >> (b & 0x1f);
 			break;
+		case 0b0100000'101: // sraw
+			name = "sraw";
+			c = (i64)a >> (b & 0x1f);
+			break;
 		default:
 			goto ud;
 		}