All opcodes except the syscalls

This commit is contained in:
Konstantin Nazarov 2024-12-06 21:58:16 +00:00
parent 2e47ad73ae
commit b8fb51f5e6
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22

View file

@ -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");
}