commit 0ed5ecb832e32efc6b14ca4073ee2fb0a6f3018a from: Benjamin Stürz date: Mon Jun 10 23:51:06 2024 UTC implement M extension commit - cc17802d9c1b8d811f2045b6e047326d85dc3444 commit + 0ed5ecb832e32efc6b14ca4073ee2fb0a6f3018a blob - 1e8765501eefc02cf51b9f751f1b7208f15ce810 blob + 05d839119a65abac506979add72e7529eddb1714 --- src/cpu.c +++ src/cpu.c @@ -282,10 +282,6 @@ void cpu_exec (u32 instr) case 0b0000000'000: // add c = a + b; alu ("add"); - break; - case 0b0000001'000: // mul - c = a * b; - alu ("mul"); break; case 0b0100000'000: // sub c = a - b; @@ -306,19 +302,11 @@ void cpu_exec (u32 instr) case 0b0000000'100: // xor c = a ^ b; alu ("xor"); - break; - case 0b0000001'100: // div - c = b != 0 ? (i64)a / (i64)b : -1; - alu ("div"); break; case 0b0000000'101: // srl c = a >> (b & 0x3f); alu ("srl"); break; - case 0b0000001'101: // divu - c = b != 0 ? a / b : -1; - alu ("divu"); - break; case 0b0100000'101: // sra c = (i64)a >> (b & 0x3f); alu ("sra"); @@ -327,16 +315,40 @@ void cpu_exec (u32 instr) c = a | b; alu ("or"); break; - case 0b0000001'110: // rem - c = b != 0 ? (i64)a % (i64)b : -1; - alu ("rem"); - break; case 0b0000000'111: // and c = a & b; alu ("and"); + break; + case 0b0000001'000: // mul + c = a * b; + alu ("mul"); + break; + case 0b0000001'001: // mulh + c = ((i128)a * (i128)b) >> 64; + alu ("mulh"); + break; + case 0b0000001'010: // mulhsu + c = ((u128)a * (i128)b) >> 64; + alu ("mulhsu"); + break; + case 0b0000001'011: // mulhu + c = ((u128)a * (u128)b) >> 64; + alu ("mulhu"); + break; + case 0b0000001'100: // div + c = b != 0 ? (i64)a / (i64)b : -1; + alu ("div"); break; + case 0b0000001'101: // divu + c = b != 0 ? a / b : -1; + alu ("divu"); + break; + case 0b0000001'110: // rem + c = b != 0 ? (i64)a % (i64)b : a; + alu ("rem"); + break; case 0b0000001'111: // remu - c = b != 0 ? a % b : -1; + c = b != 0 ? a % b : 1; alu ("remu"); break; } @@ -366,6 +378,26 @@ void cpu_exec (u32 instr) c = extend ((i64)a >> (b & 0x1f)); alu ("sraw"); break; + case 0b000001'000: // mulw + c = extend (a * b); + alu ("mulw"); + break; + case 0b000001'001: // divw + c = extend (b != 0 ? (i32)a / (i32)b : -1); + alu ("divw"); + break; + case 0b000001'010: // divuw + c = extend (b != 0 ? (u32)a / (u32)b : -1); + alu ("divuw"); + break; + case 0b000001'011: // remw + c = extend (b != 0 ? (i32)a % (i32)b : (i32)a); + alu ("divw"); + break; + case 0b000001'100: // remuw + c = extend (b != 0 ? (u32)a % (u32)b : (u32)b); + alu ("divuw"); + break; default: goto ud; } blob - f1fa870f78600a53528abcc226d280124e392286 blob + 733bc6a143bc3c452314d63bcd9212448a2861ba --- src/linurv.h +++ src/linurv.h @@ -51,11 +51,13 @@ typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; +typedef __uint128_t u128; typedef int8_t i8; typedef int16_t i16; typedef int32_t i32; typedef int64_t i64; +typedef __int128_t i128; typedef unsigned int uint;