commit 728f3bb17b12048abd68be8e8007c27fe6391cfc from: Benjamin Stürz date: Tue Jun 11 01:39:55 2024 UTC implement stub atomics commit - fdc4e5ea5a5c79384231dc931bf6e53499fa23e2 commit + 728f3bb17b12048abd68be8e8007c27fe6391cfc blob - 2727b9249b35510da80a072f48006fc5848db0f9 blob + 4f4a708a8a59aae419e3804e0e2ad6537725d0cb --- examples/test.c +++ examples/test.c @@ -42,5 +42,15 @@ int main (int argc, char *argv[]) { fclose (out); fclose (in); + + in = fopen ("/output.txt", "r"); + if (in == NULL) + err (1, "reopen('output.txt')"); + + while ((ch = fgetc (in)) != EOF) + putchar (ch); + + fclose (in); + return 0; } blob - 57f058885d086e859625805b9891f484dd0b5523 blob + 1097223b6bee26ebd2770d2554da81f7992465a1 --- src/cpu.c +++ src/cpu.c @@ -31,12 +31,16 @@ static i64 extend (i32 x) #define log(fmt, ...) eprintf ("%08"PRIx64": " fmt "\n", pc - 4, __VA_ARGS__) void cpu_exec (u32 instr) { + [[maybe_unused]] const char *sufx; const u8 rd = (instr >> 7) & 0x1f; - const u8 funct3 = (instr >> 12) & 0x7; const u8 rs1 = (instr >> 15) & 0x1f; const u8 rs2 = (instr >> 20) & 0x1f; - const u8 funct7 = instr >> 25; + const bool aq = (instr >> 26) & 1; + const bool rl = (instr >> 25) & 1; + const u8 funct3 = (instr >> 12) & 0x7; + const u8 funct5 = instr >> 27; const u8 funct6 = instr >> 26; + const u8 funct7 = instr >> 25; const u64 imm_i = extend ((i32)instr >> 20); const u64 imm_s = extend (((i32)instr >> 25 << 5) | ((instr >> 7) & 0x1f)); const u64 imm_b = extend (((i32)instr >> 31 << 12) @@ -51,6 +55,13 @@ void cpu_exec (u32 instr) const u16 funct10 = (funct7 << 3) | funct3; const u8 shamt = imm_i & 0x3f; + sufx = (const char *[]){ + "", + ".rl", + ".aq", + ".aqrl", + }[(aq << 1) | rl]; + u64 a, b, c; switch (instr & 0x7f) { case 0b0110111: // lui rd, uimm @@ -61,6 +72,39 @@ void cpu_exec (u32 instr) a = pc + imm_u - 4; log ("auipc x%u, %"PRIu64 " ; %"PRIu64, (uint)rd, imm_u, a); cpu_set (rd, a); + break; + case 0b0101111: // atomics + // TODO: actual atomics, amo* instructions + a = cpu_get (rs1); + b = cpu_get (rs2); + switch ((funct5 << 3) | funct3) { + case 0b00010'010: // lr.w + if (rs2 != 0) + goto ud; + log ("lr.w%s x%u, (x%u) ; *%p", sufx, (uint)rs1, (uint)rs2, (void *)a); + b = read_i32 (a); + cpu_set (rd, b); + break; + case 0b00011'010: // sc.w + log ("sc.w%s x%u, x%u, (x%u) ; *%p = %"PRId64, sufx, (uint)rd, (uint)rs1, (uint)rs2, (void *)a, b); + write_u32 (a, b); + cpu_set (rd, 0); + break; + case 0b00010'011: // lr.d + if (rs2 != 0) + goto ud; + log ("lr.d%s x%u, (x%u) ; *%p", sufx, (uint)rs1, (uint)rs2, (void *)a); + b = read_i64 (a); + cpu_set (rd, b); + break; + case 0b00011'011: // sc.w + log ("sc.d%s x%u, x%u, (x%u) ; *%p = %"PRId64, sufx, (uint)rd, (uint)rs1, (uint)rs2, (void *)a, b); + write_u64 (a, b); + cpu_set (rd, 0); + break; + default: + goto ud; + } break; case 0b1101111: // jal rd, jimm log ("jal x%u, %"PRId64, (uint)rd, imm_j);