#include "cpu.h" #include static void printBinary(int num) { if (num > 1) { printBinary(num / 2); } printf("%d", num % 2); } int execute_instruction_on_cpu(CPU *cpu, uint32_t instruction) { AddressSpace *addressSpace = cpu->addressSpace; uint32_t *registers = cpu->registers; registers[0] = 0; // x0 is always 0 uint8_t opcode = instruction & 0x7F; uint8_t rd = instruction >> 7 & 0x1F; printf("\nPC: %d\n", cpu->programCounter); if (opcode != 0) { printf("Instruction: "); printBinary(instruction); printf("\nOpcode: 0x%X (", opcode); printBinary(opcode); printf(")\n"); printf("Dest. reg.: x%d\n", rd); } switch (opcode) { case 0b0010011: { // OP-IMM for Integer Register-Immediate Instructions (I type) uint8_t funct3 = instruction >> 12 & 0x7; uint8_t rs1 = instruction >> 15 & 0x1F; uint32_t imm = (int32_t)instruction >> 20; switch (funct3) { case 0b000: // ADDI registers[rd] = registers[rs1] + imm; break; default: // TODO other and illegal instruction break; } /* code */ break; } case 0b0110111: { // LUI load upper immediate (U type) uint32_t imm = instruction & 0xFFFFF000; registers[rd] = imm; break; } case 0b1100111: { // JALR for unconditional jump and link register (I type) uint8_t funct3 = instruction >> 12 & 0x7; if (funct3 != 0) { // TODO illegal instruction } uint8_t rs1 = instruction >> 15 & 0x1F; uint32_t imm = (int32_t)instruction >> 20; int result = registers[rs1] + imm; result &= ~1; // set LSB to 0 registers[rd] = cpu->programCounter + 4; cpu->programCounter = result - 4; // program counter is always incremented after executing instruction break; } default: // TODO illegal instruction break; } // TODO return 0; }