All opcodes except the syscalls
This commit is contained in:
parent
2e47ad73ae
commit
b8fb51f5e6
1 changed files with 232 additions and 203 deletions
29
src/vm.cpp
29
src/vm.cpp
|
@ -219,6 +219,35 @@ void eval(uint8_t* memory, size_t memory_size) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case 0x6F: { // JAL
|
||||
int32_t offset = ((instr & 0x80000000) ? 0xFFF00000 : 0) | // Sign-extension for imm[20]
|
||||
((instr >> 21) & 0x3FF) << 1 | // imm[10:1]
|
||||
((instr >> 20) & 0x1) << 11 | // imm[11]
|
||||
((instr & 0xFF000)); // imm[19:12]
|
||||
offset <<= 1; // Multiply by 2 (JAL offsets are word-aligned)
|
||||
|
||||
registers[rd] = pc; // Save return address
|
||||
pc += offset - 4;
|
||||
break;
|
||||
}
|
||||
case 0x67: { // JALR
|
||||
int32_t offset = (instr >> 20); // Sign-extended 12-bit immediate
|
||||
uint32_t target = (registers[rs1] + offset) & ~1; // Target address (LSB cleared)
|
||||
|
||||
registers[rd] = pc; // Save return address
|
||||
pc = target - 4;
|
||||
break;
|
||||
}
|
||||
case 0x37: { // LUI
|
||||
uint32_t imm = (instr >> 12) & 0xFFFFF; // Extract 20-bit immediate
|
||||
registers[rd] = imm << 12; // Shift the immediate to the upper 20 bits of the register
|
||||
break;
|
||||
}
|
||||
case 0x17: { // AUIPC
|
||||
uint32_t imm = (instr >> 12) & 0xFFFFF; // Extract 20-bit immediate
|
||||
registers[rd] = pc + (imm << 12); // Add the immediate (shifted left) to the current PC
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw std::runtime_error("Unknown opcode");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue