even more instructions
This commit is contained in:
8
build.sh
8
build.sh
@@ -1,15 +1,15 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
WARNINGS="-Wall -Wextra -Wpedantic -Wno-unused-variable -Wno-gnu-binary-literal"
|
COMMON="-g -Wall -Wextra -Wpedantic -Wno-unused-variable -Wno-gnu-binary-literal"
|
||||||
|
|
||||||
echo "building mos6502..."
|
echo "building mos6502..."
|
||||||
cc $WARNINGS -std=c99 -o mos6502 mos6502.c
|
cc $COMMON -std=c99 -o mos6502 mos6502.c
|
||||||
|
|
||||||
if command -v pkg-config >/dev/null; then
|
if command -v pkg-config >/dev/null; then
|
||||||
RAYLIB_FLAGS=$(pkg-config --cflags --libs raylib 2>/dev/null)
|
RAYLIB_FLAGS=$(pkg-config --cflags --libs raylib 2>/dev/null)
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo "building chip8..."
|
echo "building chip8..."
|
||||||
cc $WARNINGS -std=c99 -o chip8 chip8.c $RAYLIB_FLAGS
|
cc $COMMON -std=c99 -o chip8 chip8.c $RAYLIB_FLAGS
|
||||||
else
|
else
|
||||||
echo "raylib not found - skipping chip8..."
|
echo "raylib not found - skipping chip8..."
|
||||||
fi
|
fi
|
||||||
@@ -17,7 +17,7 @@ if command -v pkg-config >/dev/null; then
|
|||||||
LIBELF_FLAGS=$(pkg-config --cflags --libs libelf 2>/dev/null)
|
LIBELF_FLAGS=$(pkg-config --cflags --libs libelf 2>/dev/null)
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo "building riscv64..."
|
echo "building riscv64..."
|
||||||
cc $WARNINGS -std=gnu11 -o riscv64 riscv64.c $LIBELF_FLAGS
|
cc $COMMON -std=gnu11 -o riscv64 riscv64.c $LIBELF_FLAGS
|
||||||
else
|
else
|
||||||
echo "libelf not found - skipping riscv64..."
|
echo "libelf not found - skipping riscv64..."
|
||||||
fi
|
fi
|
||||||
|
|||||||
293
riscv64.c
293
riscv64.c
@@ -63,6 +63,7 @@ static const char *const REGS[32] = {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
size_t offset;
|
size_t offset;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
size_t entrypoint;
|
||||||
} Section;
|
} Section;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -85,6 +86,12 @@ Section riscv64_get_code_section(uint8_t *exe_bytes, size_t exe_size) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GElf_Ehdr ehdr;
|
||||||
|
if (gelf_getehdr(elf, &ehdr) == 0) {
|
||||||
|
fprintf(stderr, "gelf_getehdr failed: %s\n", elf_errmsg(-1));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
Elf_Scn *section = NULL;
|
Elf_Scn *section = NULL;
|
||||||
while ((section = elf_nextscn(elf, section)) != NULL) {
|
while ((section = elf_nextscn(elf, section)) != NULL) {
|
||||||
GElf_Shdr header;
|
GElf_Shdr header;
|
||||||
@@ -94,7 +101,10 @@ Section riscv64_get_code_section(uint8_t *exe_bytes, size_t exe_size) {
|
|||||||
const char *name = elf_strptr(elf, str_table_index, header.sh_name);
|
const char *name = elf_strptr(elf, str_table_index, header.sh_name);
|
||||||
if (name && strcmp(name, ".text") == 0) {
|
if (name && strcmp(name, ".text") == 0) {
|
||||||
elf_end(elf);
|
elf_end(elf);
|
||||||
return (Section){.offset = header.sh_offset, .size = header.sh_size};
|
return (Section){.offset = header.sh_offset,
|
||||||
|
.size = header.sh_size,
|
||||||
|
.entrypoint =
|
||||||
|
ehdr.e_entry - header.sh_addr + header.sh_offset};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +150,8 @@ void riscv64_disassemble_one(const RISCV64 *r) {
|
|||||||
printf("blt %s, %s, %d\n", REGS[rs1], REGS[rs2], imm);
|
printf("blt %s, %s, %d\n", REGS[rs1], REGS[rs2], imm);
|
||||||
} else if (funct3 == 0b101) {
|
} else if (funct3 == 0b101) {
|
||||||
printf("bge %s, %s, %d\n", REGS[rs1], REGS[rs2], imm);
|
printf("bge %s, %s, %d\n", REGS[rs1], REGS[rs2], imm);
|
||||||
break;
|
} else if (funct3 == 0b110) {
|
||||||
|
printf("bltu %s, %s, %d\n", REGS[rs1], REGS[rs2], imm);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "B-type: unrecognized funct3: %03b\n", funct3);
|
fprintf(stderr, "B-type: unrecognized funct3: %03b\n", funct3);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -152,7 +163,36 @@ void riscv64_disassemble_one(const RISCV64 *r) {
|
|||||||
if (funct3 == 0b000) {
|
if (funct3 == 0b000) {
|
||||||
printf("addi %s, %s, %d\n", REGS[rd], REGS[rs1], imm);
|
printf("addi %s, %s, %d\n", REGS[rd], REGS[rs1], imm);
|
||||||
} else if (funct3 == 0b001) {
|
} else if (funct3 == 0b001) {
|
||||||
printf("slli %s, %s, %d\n", REGS[rd], REGS[rs1], imm);
|
uint32_t shamt = (ins >> 20) & 0b111111;
|
||||||
|
uint32_t funct6 = (ins >> 26) & 0b111111;
|
||||||
|
|
||||||
|
if (funct6 == 0b000000) {
|
||||||
|
printf("slli %s, %s, %d\n", REGS[rd], REGS[rs1], shamt);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "I-type 1: funct3=001: unrecognized funct6: %b\n",
|
||||||
|
funct6);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (funct3 == 0b011) {
|
||||||
|
printf("sltiu %s, %s, %d\n", REGS[rd], REGS[rs1], imm);
|
||||||
|
} else if (funct3 == 0b100) {
|
||||||
|
printf("xori %s, %s, %d\n", REGS[rd], REGS[rs1], imm);
|
||||||
|
} else if (funct3 == 0b101) {
|
||||||
|
// of course this one just has to be different
|
||||||
|
uint32_t shamt = (ins >> 20) & 0b111111;
|
||||||
|
uint32_t funct6 = (ins >> 26) & 0b111111;
|
||||||
|
|
||||||
|
if (funct6 == 0b000000) {
|
||||||
|
printf("srli %s, %s, %d\n", REGS[rd], REGS[rs1], shamt);
|
||||||
|
} else if (funct6 == 0b010000) {
|
||||||
|
printf("srai %s, %s, %d\n", REGS[rd], REGS[rs1], shamt);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "I-type 1: funct3=101: unrecognized funct6: %b\n",
|
||||||
|
funct6);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (funct3 == 0b111) {
|
||||||
|
printf("andi %s, %s, %d\n", REGS[rd], REGS[rs1], imm);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "I-type 1: unrecognized funct3: %03b\n", funct3);
|
fprintf(stderr, "I-type 1: unrecognized funct3: %03b\n", funct3);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -163,8 +203,14 @@ void riscv64_disassemble_one(const RISCV64 *r) {
|
|||||||
|
|
||||||
if (funct3 == 0b000) {
|
if (funct3 == 0b000) {
|
||||||
printf("lb %s, %d(%s)\n", REGS[rd], imm, REGS[rs1]);
|
printf("lb %s, %d(%s)\n", REGS[rd], imm, REGS[rs1]);
|
||||||
|
} else if (funct3 == 0b001) {
|
||||||
|
printf("lh %s, %d(%s)\n", REGS[rd], imm, REGS[rs1]);
|
||||||
|
} else if (funct3 == 0b010) {
|
||||||
|
printf("lw %s, %d(%s)\n", REGS[rd], imm, REGS[rs1]);
|
||||||
} else if (funct3 == 0b011) {
|
} else if (funct3 == 0b011) {
|
||||||
printf("ld %s, %d(%s)\n", REGS[rd], imm, REGS[rs1]);
|
printf("ld %s, %d(%s)\n", REGS[rd], imm, REGS[rs1]);
|
||||||
|
} else if (funct3 == 0b100) {
|
||||||
|
printf("lbu %s, %d(%s)\n", REGS[rd], imm, REGS[rs1]);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "I-type 2: unrecognized funct3: %03b\n", funct3);
|
fprintf(stderr, "I-type 2: unrecognized funct3: %03b\n", funct3);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -184,7 +230,6 @@ void riscv64_disassemble_one(const RISCV64 *r) {
|
|||||||
fprintf(stderr, "I-type 4: funct3=000 unrecognized imm: %b\n", imm);
|
fprintf(stderr, "I-type 4: funct3=000 unrecognized imm: %b\n", imm);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "I-type 4: unrecognized funct3: %03b\n", funct3);
|
fprintf(stderr, "I-type 4: unrecognized funct3: %03b\n", funct3);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -208,6 +253,60 @@ void riscv64_disassemble_one(const RISCV64 *r) {
|
|||||||
funct7);
|
funct7);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
} else if (funct3 == 0b001) {
|
||||||
|
if (funct7 == 0b0000001) {
|
||||||
|
printf("mulh %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "R-type 1: funct3=0b001: unrecognized funct7: %b\n",
|
||||||
|
funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (funct3 == 0b010) {
|
||||||
|
if (funct7 == 0b0000000) {
|
||||||
|
printf("slt %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "R-type 1: funct3=0b010: unrecognized funct7: %b\n",
|
||||||
|
funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (funct3 == 0b011) {
|
||||||
|
if (funct7 == 0b0000000) {
|
||||||
|
printf("sltu %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
|
||||||
|
} else if (funct7 == 0b0000001) {
|
||||||
|
printf("mulhu %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "R-type 1: funct3=0b011: unrecognized funct7: %b\n",
|
||||||
|
funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (funct3 == 0b100) {
|
||||||
|
if (funct7 == 0b0000000) {
|
||||||
|
printf("xor %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
|
||||||
|
} else if (funct7 == 0b0000001) {
|
||||||
|
printf("div %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "R-type 1: funct3=0b100: unrecognized funct7: %b\n",
|
||||||
|
funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (funct3 == 0b110) {
|
||||||
|
if (funct7 == 0b0000001) {
|
||||||
|
printf("rem %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
|
||||||
|
} else if (funct7 == 0b0000000) {
|
||||||
|
printf("or %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "R-type 1: funct3=0b110: unrecognized funct7: %b\n",
|
||||||
|
funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (funct3 == 0b111) {
|
||||||
|
if (funct7 == 0b000) {
|
||||||
|
printf("and %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "R-type 1: funct3=0b111: unrecognized funct7: %b\n",
|
||||||
|
funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "R-type 1: unrecognized funct3: %03b\n", funct3);
|
fprintf(stderr, "R-type 1: unrecognized funct3: %03b\n", funct3);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -218,7 +317,19 @@ void riscv64_disassemble_one(const RISCV64 *r) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
case 0b0111011: {
|
case 0b0111011: {
|
||||||
PARSE_R_INS(ins);
|
PARSE_R_INS(ins);
|
||||||
if (funct3 == 0b101) {
|
if (funct3 == 0b000) {
|
||||||
|
if (funct7 == 0b0000000) {
|
||||||
|
printf("addw %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
|
||||||
|
} else if (funct7 == 0b0100000) {
|
||||||
|
printf("subw %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
|
||||||
|
} else if (funct7 == 0b0000001) {
|
||||||
|
printf("mulw %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "R-type 3: funct3=000: unrecognized funct7: %b\n",
|
||||||
|
funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (funct3 == 0b101) {
|
||||||
if (funct7 == 0b0000001) {
|
if (funct7 == 0b0000001) {
|
||||||
printf("divuw %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
|
printf("divuw %s, %s, %s\n", REGS[rd], REGS[rs1], REGS[rs2]);
|
||||||
} else {
|
} else {
|
||||||
@@ -238,6 +349,9 @@ void riscv64_disassemble_one(const RISCV64 *r) {
|
|||||||
if (funct3 == 0b000) {
|
if (funct3 == 0b000) {
|
||||||
PARSE_I_INS(ins);
|
PARSE_I_INS(ins);
|
||||||
printf("addiw %s, %s, %d\n", REGS[rd], REGS[rs1], imm);
|
printf("addiw %s, %s, %d\n", REGS[rd], REGS[rs1], imm);
|
||||||
|
} else if (funct3 == 0b001) {
|
||||||
|
PARSE_I_INS(ins);
|
||||||
|
printf("slliw %s, %s, %d\n", REGS[rd], REGS[rs1], imm);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "R-type 4: unrecognized funct3: %03b\n", funct3);
|
fprintf(stderr, "R-type 4: unrecognized funct3: %03b\n", funct3);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -248,6 +362,10 @@ void riscv64_disassemble_one(const RISCV64 *r) {
|
|||||||
|
|
||||||
if (funct3 == 0b000) {
|
if (funct3 == 0b000) {
|
||||||
printf("sb %s, %d(%s)\n", REGS[rs2], imm, REGS[rs1]);
|
printf("sb %s, %d(%s)\n", REGS[rs2], imm, REGS[rs1]);
|
||||||
|
} else if (funct3 == 0b001) {
|
||||||
|
printf("sh %s, %d(%s)\n", REGS[rs2], imm, REGS[rs1]);
|
||||||
|
} else if (funct3 == 0b010) {
|
||||||
|
printf("sw %s, %d(%s)\n", REGS[rs2], imm, REGS[rs1]);
|
||||||
} else if (funct3 == 0b011) {
|
} else if (funct3 == 0b011) {
|
||||||
printf("sd %s, %d(%s)\n", REGS[rs2], imm, REGS[rs1]);
|
printf("sd %s, %d(%s)\n", REGS[rs2], imm, REGS[rs1]);
|
||||||
} else {
|
} else {
|
||||||
@@ -270,7 +388,7 @@ void riscv64_disassemble_one(const RISCV64 *r) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void riscv64_execute(RISCV64 *r) {
|
void riscv64_execute(RISCV64 *r) {
|
||||||
r->pc = r->code_section.offset;
|
r->pc = r->code_section.entrypoint;
|
||||||
|
|
||||||
r->regs[2] = (20 * 1024 * 1024) - 1; // set the stack pointer
|
r->regs[2] = (20 * 1024 * 1024) - 1; // set the stack pointer
|
||||||
|
|
||||||
@@ -307,6 +425,11 @@ void riscv64_execute(RISCV64 *r) {
|
|||||||
r->pc += imm;
|
r->pc += imm;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
} else if (funct3 == 0b110) { // bltu
|
||||||
|
if ((uint64_t)r->regs[rs1] < (uint64_t)r->regs[rs2]) {
|
||||||
|
r->pc += imm;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "B-type: unrecognized funct3: %03b\n", funct3);
|
fprintf(stderr, "B-type: unrecognized funct3: %03b\n", funct3);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -318,7 +441,36 @@ void riscv64_execute(RISCV64 *r) {
|
|||||||
if (funct3 == 0b000) { // addi
|
if (funct3 == 0b000) { // addi
|
||||||
r->regs[rd] = r->regs[rs1] + imm;
|
r->regs[rd] = r->regs[rs1] + imm;
|
||||||
} else if (funct3 == 0b001) { // slli
|
} else if (funct3 == 0b001) { // slli
|
||||||
r->regs[rd] = r->regs[rs1] << (imm & 0b111111);
|
uint32_t shamt = (ins >> 20) & 0b111111;
|
||||||
|
uint32_t funct6 = (ins >> 26) & 0b111111;
|
||||||
|
|
||||||
|
if (funct6 == 0b000000) {
|
||||||
|
r->regs[rd] = r->regs[rs1] << shamt;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "I-type 1: funct3=001: unrecognized funct6: %b\n",
|
||||||
|
funct6);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (funct3 == 0b011) { // sltiu
|
||||||
|
r->regs[rd] = (r->regs[rs1] < (uint64_t)(int64_t)imm) ? 1 : 0;
|
||||||
|
} else if (funct3 == 0b100) { // xori
|
||||||
|
r->regs[rd] = r->regs[rs1] ^ imm;
|
||||||
|
} else if (funct3 == 0b101) {
|
||||||
|
// of course this one just has to be different
|
||||||
|
uint32_t shamt = (ins >> 20) & 0b111111;
|
||||||
|
uint32_t funct6 = (ins >> 26) & 0b111111;
|
||||||
|
|
||||||
|
if (funct6 == 0b000000) { // srli
|
||||||
|
r->regs[rd] = r->regs[rs1] >> shamt;
|
||||||
|
} else if (funct6 == 0b010000) { // srai
|
||||||
|
r->regs[rd] = (int32_t)r->regs[rs1] >> shamt;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "I-type 1: funct3=101: unrecognized funct6: %b\n",
|
||||||
|
funct6);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (funct3 == 0b111) {
|
||||||
|
r->regs[rd] = r->regs[rs1] & imm;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "I-type 1: unrecognized funct3: %03b\n", funct3);
|
fprintf(stderr, "I-type 1: unrecognized funct3: %03b\n", funct3);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -328,9 +480,15 @@ void riscv64_execute(RISCV64 *r) {
|
|||||||
PARSE_I_INS(ins);
|
PARSE_I_INS(ins);
|
||||||
|
|
||||||
if (funct3 == 0b000) { // lb
|
if (funct3 == 0b000) { // lb
|
||||||
r->regs[rd] = r->memory[r->regs[rs1] + imm];
|
r->regs[rd] = (int8_t)r->memory[r->regs[rs1] + imm];
|
||||||
|
} else if (funct3 == 0b001) { // lh
|
||||||
|
r->regs[rd] = *(int16_t *)&r->memory[r->regs[rs1] + imm];
|
||||||
|
} else if (funct3 == 0b010) { // lw
|
||||||
|
r->regs[rd] = *(int32_t *)&r->memory[r->regs[rs1] + imm];
|
||||||
} else if (funct3 == 0b011) { // ld
|
} else if (funct3 == 0b011) { // ld
|
||||||
r->regs[rd] = *(uint64_t *)&r->memory[r->regs[rs1] + imm];
|
r->regs[rd] = *(uint64_t *)&r->memory[r->regs[rs1] + imm];
|
||||||
|
} else if (funct3 == 0b100) { // lbu
|
||||||
|
r->regs[rd] = r->memory[r->regs[rs1] + imm];
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "I-type 2: unrecognized funct3: %03b\n", funct3);
|
fprintf(stderr, "I-type 2: unrecognized funct3: %03b\n", funct3);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -338,7 +496,7 @@ void riscv64_execute(RISCV64 *r) {
|
|||||||
}; break;
|
}; break;
|
||||||
case 0b1100111: { // jalr
|
case 0b1100111: { // jalr
|
||||||
PARSE_I_INS(ins);
|
PARSE_I_INS(ins);
|
||||||
uint32_t target = (r->regs[rs1] + imm) & ~1;
|
size_t target = (r->regs[rs1] + imm) & ~(size_t)1;
|
||||||
r->regs[rd] = r->pc + 4;
|
r->regs[rd] = r->pc + 4;
|
||||||
r->pc = target;
|
r->pc = target;
|
||||||
continue;
|
continue;
|
||||||
@@ -432,18 +590,86 @@ void riscv64_execute(RISCV64 *r) {
|
|||||||
if (funct3 == 0b000) {
|
if (funct3 == 0b000) {
|
||||||
if (funct7 == 0b0000000) { // add
|
if (funct7 == 0b0000000) { // add
|
||||||
r->regs[rd] = r->regs[rs1] + r->regs[rs2];
|
r->regs[rd] = r->regs[rs1] + r->regs[rs2];
|
||||||
break;
|
|
||||||
} else if (funct7 == 0b0100000) { // sub
|
} else if (funct7 == 0b0100000) { // sub
|
||||||
r->regs[rd] = r->regs[rs1] - r->regs[rs2];
|
r->regs[rd] = r->regs[rs1] - r->regs[rs2];
|
||||||
break;
|
|
||||||
} else if (funct7 == 0b0000001) { // mul
|
} else if (funct7 == 0b0000001) { // mul
|
||||||
r->regs[rd] = r->regs[rs1] * r->regs[rs2];
|
r->regs[rd] = r->regs[rs1] * r->regs[rs2];
|
||||||
break;
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "R-type 1: funct3=0b000: unrecognized funct7: %b\n",
|
fprintf(stderr, "R-type 1: funct3=0b000: unrecognized funct7: %b\n",
|
||||||
funct7);
|
funct7);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
} else if (funct3 == 0b001) {
|
||||||
|
if (funct7 == 0b0000001) { // mulh
|
||||||
|
int64_t a_hi = r->regs[rs1] >> 32;
|
||||||
|
int64_t b_hi = r->regs[rs2] >> 32;
|
||||||
|
uint64_t a_lo = (uint32_t)r->regs[rs1];
|
||||||
|
uint64_t b_lo = (uint32_t)r->regs[rs2];
|
||||||
|
uint64_t p0 = a_lo * b_lo;
|
||||||
|
int64_t p1 = a_hi * b_lo;
|
||||||
|
int64_t p2 = b_hi * a_lo;
|
||||||
|
int64_t p3 = a_hi * b_hi;
|
||||||
|
int64_t carry = (p0 >> 32);
|
||||||
|
int64_t mid = p1 + p2 + carry;
|
||||||
|
r->regs[rd] = p3 + (mid >> 32);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "R-type 1: funct3=0b001: unrecognized funct7: %b\n",
|
||||||
|
funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (funct3 == 0b010) {
|
||||||
|
if (funct7 == 0b0000000) { // slt
|
||||||
|
r->regs[rd] = ((int64_t)r->regs[rs1] < (int64_t)r->regs[rs2]) ? 1 : 0;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "R-type 1: funct3=0b010: unrecognized funct7: %b\n",
|
||||||
|
funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (funct3 == 0b011) {
|
||||||
|
if (funct7 == 0b0000000) { // sltu
|
||||||
|
r->regs[rd] =
|
||||||
|
((uint64_t)r->regs[rs1] < (uint64_t)r->regs[rs2]) ? 1 : 0;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "R-type 1: funct3=0b011: unrecognized funct7: %b\n",
|
||||||
|
funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (funct3 == 0b100) {
|
||||||
|
if (funct7 == 0b0000000) { // xor
|
||||||
|
r->regs[rd] = r->regs[rs1] ^ r->regs[rs2];
|
||||||
|
} else if (funct7 == 0b0000001) { // div
|
||||||
|
if (r->regs[rs2] == 0) {
|
||||||
|
r->regs[rd] = -1;
|
||||||
|
} else {
|
||||||
|
r->regs[rd] = (int64_t)r->regs[rs1] / (int64_t)r->regs[rs2];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "R-type 1: funct3=0b100: unrecognized funct7: %b\n",
|
||||||
|
funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (funct3 == 0b110) {
|
||||||
|
if (funct7 == 0b0000001) { // rem
|
||||||
|
if (r->regs[rs2] == 0) {
|
||||||
|
r->regs[rd] = r->regs[rs1];
|
||||||
|
} else {
|
||||||
|
r->regs[rd] = (int64_t)r->regs[rs1] % (int64_t)r->regs[rs2];
|
||||||
|
}
|
||||||
|
} else if (funct7 == 0b0000000) { // or
|
||||||
|
r->regs[rd] = r->regs[rs1] | r->regs[rs2];
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "R-type 1: funct3=0b110: unrecognized funct7: %b\n",
|
||||||
|
funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (funct3 == 0b111) {
|
||||||
|
if (funct7 == 0b000) { // and
|
||||||
|
r->regs[rd] = r->regs[rs1] & r->regs[rs2];
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "R-type 1: funct3=0b111: unrecognized funct7: %b\n",
|
||||||
|
funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "R-type 1: unrecognized funct3: %03b\n", funct3);
|
fprintf(stderr, "R-type 1: unrecognized funct3: %03b\n", funct3);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -451,23 +677,37 @@ void riscv64_execute(RISCV64 *r) {
|
|||||||
}; break;
|
}; break;
|
||||||
case 0b0111011: {
|
case 0b0111011: {
|
||||||
PARSE_R_INS(ins);
|
PARSE_R_INS(ins);
|
||||||
if (funct3 == 0b101) {
|
if (funct3 == 0b000) {
|
||||||
if (funct7 == 0b0000001) {
|
if (funct7 == 0b0000000) { // addw
|
||||||
|
r->regs[rd] = (int32_t)(r->regs[rs1] + r->regs[rs2]);
|
||||||
|
} else if (funct7 == 0b0100000) { // subw
|
||||||
|
r->regs[rd] = (int32_t)(r->regs[rs1] - r->regs[rs2]);
|
||||||
|
} else if (funct7 == 0b0000001) { // mulw
|
||||||
|
r->regs[rd] = (int32_t)(r->regs[rs1] * r->regs[rs2]);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "R-type 3: funct3=000: unrecognized funct7: %b\n",
|
||||||
|
funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (funct3 == 0b101) {
|
||||||
|
if (funct7 == 0b0000001) { // divuw
|
||||||
if (r->regs[rs2] == 0) {
|
if (r->regs[rs2] == 0) {
|
||||||
r->regs[rd] = -1LL;
|
r->regs[rd] = -1LL;
|
||||||
} else {
|
} else {
|
||||||
r->regs[rd] = (int32_t)(r->regs[rs1] / r->regs[rs2]);
|
r->regs[rd] =
|
||||||
|
(int32_t)((uint32_t)r->regs[rs1] / (uint32_t)r->regs[rs2]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "R-type 3: funct3=101: unrecognized funct7: %b\n",
|
fprintf(stderr, "R-type 3: funct3=101: unrecognized funct7: %b\n",
|
||||||
funct7);
|
funct7);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
} else if (funct3 == 0b111) {
|
} else if (funct3 == 0b111) { // remuw
|
||||||
if (r->regs[rs2] == 0) {
|
if (r->regs[rs2] == 0) {
|
||||||
r->regs[rd] = (int32_t)r->regs[rs1];
|
r->regs[rd] = (int32_t)r->regs[rs1];
|
||||||
} else {
|
} else {
|
||||||
r->regs[rd] = (int32_t)(r->regs[rs1] % r->regs[rs2]);
|
r->regs[rd] =
|
||||||
|
(int32_t)((uint32_t)r->regs[rs1] % (uint32_t)r->regs[rs2]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "R-type 3: unrecognized funct3: %03b\n", funct3);
|
fprintf(stderr, "R-type 3: unrecognized funct3: %03b\n", funct3);
|
||||||
@@ -475,11 +715,12 @@ void riscv64_execute(RISCV64 *r) {
|
|||||||
}
|
}
|
||||||
}; break;
|
}; break;
|
||||||
case 0b0011011: {
|
case 0b0011011: {
|
||||||
uint8_t funct3 = (ins >> 12) & 0b111;
|
|
||||||
if (funct3 == 0b000) {
|
|
||||||
PARSE_I_INS(ins);
|
PARSE_I_INS(ins);
|
||||||
int32_t result = r->regs[rs1] + imm;
|
if (funct3 == 0b000) { // addiw
|
||||||
r->regs[rd] = result;
|
r->regs[rd] = (int32_t)r->regs[rs1] + (int32_t)imm;
|
||||||
|
} else if (funct3 == 0b001) {
|
||||||
|
uint32_t shamt = (ins >> 20) & 0b11111;
|
||||||
|
r->regs[rd] = (int32_t)r->regs[rs1] << shamt;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "R-type 4: unrecognized funct3: %03b\n", funct3);
|
fprintf(stderr, "R-type 4: unrecognized funct3: %03b\n", funct3);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -491,6 +732,12 @@ void riscv64_execute(RISCV64 *r) {
|
|||||||
if (funct3 == 0b000) { // sb
|
if (funct3 == 0b000) { // sb
|
||||||
size_t addr = r->regs[rs1] + imm;
|
size_t addr = r->regs[rs1] + imm;
|
||||||
r->memory[addr] = r->regs[rs2];
|
r->memory[addr] = r->regs[rs2];
|
||||||
|
} else if (funct3 == 0b001) { // sh
|
||||||
|
size_t addr = r->regs[rs1] + imm;
|
||||||
|
*(uint16_t *)(&r->memory[addr]) = r->regs[rs2];
|
||||||
|
} else if (funct3 == 0b010) { // sw
|
||||||
|
size_t addr = r->regs[rs1] + imm;
|
||||||
|
*(uint32_t *)(&r->memory[addr]) = r->regs[rs2];
|
||||||
} else if (funct3 == 0b011) { // sd
|
} else if (funct3 == 0b011) { // sd
|
||||||
size_t addr = r->regs[rs1] + imm;
|
size_t addr = r->regs[rs1] + imm;
|
||||||
// take this rust
|
// take this rust
|
||||||
@@ -502,11 +749,11 @@ void riscv64_execute(RISCV64 *r) {
|
|||||||
}; break;
|
}; break;
|
||||||
case 0b0110111: { // lui
|
case 0b0110111: { // lui
|
||||||
PARSE_U_INS(ins);
|
PARSE_U_INS(ins);
|
||||||
r->regs[rd] = imm << 12;
|
r->regs[rd] = (int64_t)imm << 12;
|
||||||
}; break;
|
}; break;
|
||||||
case 0b0010111: { // auipc
|
case 0b0010111: { // auipc
|
||||||
PARSE_U_INS(ins);
|
PARSE_U_INS(ins);
|
||||||
r->regs[rd] = r->pc + (imm << 12);
|
r->regs[rd] = r->pc + ((int64_t)imm << 12);
|
||||||
}; break;
|
}; break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unrecognized opcode: %07b\n", opcode);
|
fprintf(stderr, "Unrecognized opcode: %07b\n", opcode);
|
||||||
|
|||||||
Reference in New Issue
Block a user