more instructions, dummy gettimeofday, improve read syscall

This commit is contained in:
2026-02-28 20:31:30 +01:00
parent b7f27abaf4
commit a8573689d3

143
riscv64.c
View File

@@ -132,7 +132,11 @@ void riscv64_disassemble_one(const RISCV64 *r) {
case 0b1100011: {
PARSE_B_INS(ins);
if (funct3 == 0b100) {
if (funct3 == 0b000) {
printf("beq %s, %s, %d\n", REGS[rs1], REGS[rs2], imm);
} else if (funct3 == 0b001) {
printf("bne %s, %s, %d\n", REGS[rs1], REGS[rs2], imm);
} else if (funct3 == 0b100) {
printf("blt %s, %s, %d\n", REGS[rs1], REGS[rs2], imm);
} else if (funct3 == 0b101) {
printf("bge %s, %s, %d\n", REGS[rs1], REGS[rs2], imm);
@@ -147,6 +151,8 @@ void riscv64_disassemble_one(const RISCV64 *r) {
if (funct3 == 0b000) {
printf("addi %s, %s, %d\n", REGS[rd], REGS[rs1], imm);
} else if (funct3 == 0b001) {
printf("slli %s, %s, %d\n", REGS[rd], REGS[rs1], imm);
} else {
fprintf(stderr, "I-type 1: unrecognized funct3: %03b\n", funct3);
exit(1);
@@ -157,6 +163,8 @@ void riscv64_disassemble_one(const RISCV64 *r) {
if (funct3 == 0b000) {
printf("lb %s, %d(%s)\n", REGS[rd], imm, REGS[rs1]);
} else if (funct3 == 0b011) {
printf("ld %s, %d(%s)\n", REGS[rd], imm, REGS[rs1]);
} else {
fprintf(stderr, "I-type 2: unrecognized funct3: %03b\n", funct3);
exit(1);
@@ -189,8 +197,12 @@ void riscv64_disassemble_one(const RISCV64 *r) {
case 0b0110011: {
PARSE_R_INS(ins);
if (funct3 == 0b000) {
if (funct7 == 0) {
if (funct7 == 0b0000000) {
printf("add %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
} else if (funct7 == 0b0100000) {
printf("sub %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
} else if (funct7 == 0b0000001) {
printf("mul %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
} else {
fprintf(stderr, "R-type 1: funct3=0b000: unrecognized funct7: %b\n",
funct7);
@@ -204,23 +216,49 @@ void riscv64_disassemble_one(const RISCV64 *r) {
case 0b0101111:
fprintf(stderr, "R-type 2: unimplemented\n");
exit(1);
case 0b0111011:
fprintf(stderr, "R-type 3: unimplemented\n");
case 0b0111011: {
PARSE_R_INS(ins);
if (funct3 == 0b101) {
if (funct7 == 0b0000001) {
printf("divuw %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
} else {
fprintf(stderr, "R-type 3: funct3=101: unrecognized funct7: %b\n",
funct7);
exit(1);
}
} else if (funct3 == 0b111) {
printf("remuw %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
} else {
fprintf(stderr, "R-type 3: unrecognized funct3: %03b\n", funct3);
exit(1);
}
}; break;
case 0b0011011: {
uint8_t funct3 = (ins >> 12) & 0b111;
if (funct3 == 0b000) {
PARSE_I_INS(ins);
printf("addiw %s, %s, %d\n", REGS[rd], REGS[rs1], imm);
} else {
fprintf(stderr, "R-type 4: unrecognized funct3: %03b\n", funct3);
exit(1);
}
}; break;
case 0b0100011: {
PARSE_S_INS(ins);
if (funct3 == 0b000) {
printf("sb %s, %d(%s)\n", REGS[rs2], imm, REGS[rs1]);
} else if (funct3 == 0b011) {
printf("sd %s, %d(%s)\n", REGS[rs2], imm, REGS[rs1]);
} else {
fprintf(stderr, "S-type: unrecognized funct3: %03b\n", funct3);
exit(1);
}
}; break;
case 0b0110111:
fprintf(stderr, "U-type 1: unimplemented\n");
exit(1);
break;
case 0b0110111: {
PARSE_U_INS(ins);
printf("lui %s, %d\n", REGS[rd], imm);
}; break;
case 0b0010111: {
PARSE_U_INS(ins);
printf("auipc %s, %d\n", REGS[rd], imm);
@@ -249,7 +287,17 @@ void riscv64_execute(RISCV64 *r) {
case 0b1100011: {
PARSE_B_INS(ins);
if (funct3 == 0b101) { // bge
if (funct3 == 0b000) { // beq
if (r->regs[rs1] == r->regs[rs2]) {
r->pc += imm;
continue;
}
} else if (funct3 == 0b001) { // bne
if (r->regs[rs1] != r->regs[rs2]) {
r->pc += imm;
continue;
}
} else if (funct3 == 0b101) { // bge
if (r->regs[rs1] >= r->regs[rs2]) {
r->pc += imm;
continue;
@@ -269,6 +317,8 @@ void riscv64_execute(RISCV64 *r) {
if (funct3 == 0b000) { // addi
r->regs[rd] = r->regs[rs1] + imm;
} else if (funct3 == 0b001) { // slli
r->regs[rd] = r->regs[rs1] << (imm & 0b111111);
} else {
fprintf(stderr, "I-type 1: unrecognized funct3: %03b\n", funct3);
exit(1);
@@ -279,6 +329,8 @@ void riscv64_execute(RISCV64 *r) {
if (funct3 == 0b000) { // lb
r->regs[rd] = r->memory[r->regs[rs1] + imm];
} else if (funct3 == 0b011) { // ld
r->regs[rd] = *(uint64_t *)&r->memory[r->regs[rs1] + imm];
} else {
fprintf(stderr, "I-type 2: unrecognized funct3: %03b\n", funct3);
exit(1);
@@ -314,6 +366,8 @@ void riscv64_execute(RISCV64 *r) {
break;
r->memory[start + i] = (uint8_t)c;
bytes_read++;
if (c == '\n')
break;
}
r->regs[10] = bytes_read;
@@ -335,6 +389,23 @@ void riscv64_execute(RISCV64 *r) {
printf("Program exited with code %lu.\n", r->regs[10]);
return;
}; break;
case 169: { // gettimeofday
// TODO: actually return the time
int64_t tv_addr = r->regs[10];
int64_t tz_addr = r->regs[11];
uint8_t tv_buf[16] = {
0xD2, 0x02, 0x96, 0x49,
0x00, 0x00, 0x00, 0x00, // tv_sec = 1234567890
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // tv_usec = 0
};
memcpy(&r->memory[tv_addr], tv_buf, 16);
memset(&r->memory[tz_addr], 0, 8);
r->regs[10] = 0;
}; break;
default:
fprintf(stderr, "Unimplemented syscall: %lu\n", r->regs[17]);
exit(1);
@@ -359,9 +430,15 @@ void riscv64_execute(RISCV64 *r) {
case 0b0110011: {
PARSE_R_INS(ins);
if (funct3 == 0b000) {
if (funct7 == 0) { // add
if (funct7 == 0b0000000) { // add
r->regs[rd] = r->regs[rs1] + r->regs[rs2];
break;
} else if (funct7 == 0b0100000) { // sub
r->regs[rd] = r->regs[rs1] - r->regs[rs2];
break;
} else if (funct7 == 0b0000001) { // mul
r->regs[rd] = r->regs[rs1] * r->regs[rs2];
break;
} else {
fprintf(stderr, "R-type 1: funct3=0b000: unrecognized funct7: %b\n",
funct7);
@@ -372,20 +449,64 @@ void riscv64_execute(RISCV64 *r) {
exit(1);
}
}; break;
case 0b0111011: {
PARSE_R_INS(ins);
if (funct3 == 0b101) {
if (funct7 == 0b0000001) {
if (r->regs[rs2] == 0) {
r->regs[rd] = -1LL;
} else {
r->regs[rd] = (int32_t)(r->regs[rs1] / r->regs[rs2]);
}
} else {
fprintf(stderr, "R-type 3: funct3=101: unrecognized funct7: %b\n",
funct7);
exit(1);
}
} else if (funct3 == 0b111) {
if (r->regs[rs2] == 0) {
r->regs[rd] = (int32_t)r->regs[rs1];
} else {
r->regs[rd] = (int32_t)(r->regs[rs1] % r->regs[rs2]);
}
} else {
fprintf(stderr, "R-type 3: unrecognized funct3: %03b\n", funct3);
exit(1);
}
}; break;
case 0b0011011: {
uint8_t funct3 = (ins >> 12) & 0b111;
if (funct3 == 0b000) {
PARSE_I_INS(ins);
int32_t result = r->regs[rs1] + imm;
r->regs[rd] = result;
} else {
fprintf(stderr, "R-type 4: unrecognized funct3: %03b\n", funct3);
exit(1);
}
}; break;
case 0b0100011: {
PARSE_S_INS(ins);
if (funct3 == 0b000) { // sb
size_t addr = r->regs[rs1] + imm;
r->memory[addr] = r->regs[rs2];
} else if (funct3 == 0b011) { // sd
size_t addr = r->regs[rs1] + imm;
// take this rust
*(uint64_t *)(&r->memory[addr]) = r->regs[rs2];
} else {
fprintf(stderr, "S-type: unrecognized funct3: %03b\n", funct3);
exit(1);
}
}; break;
case 0b0110111: { // lui
PARSE_U_INS(ins);
r->regs[rd] = imm << 12;
}; break;
case 0b0010111: { // auipc
PARSE_U_INS(ins);
r->regs[rd] = r->pc + (imm >> 12);
r->regs[rd] = r->pc + (imm << 12);
}; break;
default:
fprintf(stderr, "Unrecognized opcode: %07b\n", opcode);