commit - fdc4e5ea5a5c79384231dc931bf6e53499fa23e2
commit + 728f3bb17b12048abd68be8e8007c27fe6391cfc
blob - 2727b9249b35510da80a072f48006fc5848db0f9
blob + 4f4a708a8a59aae419e3804e0e2ad6537725d0cb
--- examples/test.c
+++ examples/test.c
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
#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)
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
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);