more instructions, dummy gettimeofday, improve read syscall
This commit is contained in:
145
riscv64.c
145
riscv64.c
@@ -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");
|
||||
exit(1);
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user