From 1f48837af82e5bc226b62b509d61986c2b82f11b Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Sat, 11 May 2024 19:08:19 +0200 Subject: Finish I --- main.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/main.c b/main.c index feba3b9..223403a 100644 --- a/main.c +++ b/main.c @@ -206,10 +206,130 @@ void execute_branch(struct Hart* hart, uint32_t instruction) } } +uint32_t load_byte(struct Hart* hart, uint32_t address) +{ + return 0; +} + +uint32_t load_half(struct Hart* hart, uint32_t address) +{ + return 0; +} + +uint32_t load_word(struct Hart* hart, uint32_t address) +{ + return 0; +} + +void store_byte(struct Hart* hart, uint32_t address, uint8_t value) {} +void store_half(struct Hart* hart, uint32_t address, uint16_t value) {} +void store_word(struct Hart* hart, uint32_t address, uint32_t value) {} + +void execute_op_load(struct Hart* hart, uint32_t instruction) +{ + const struct Instruction inst = decode_i_type(instruction); + const uint32_t address = hart->regs[inst.rs1] + inst.imm; + + uint32_t value = 0; + + switch (inst.funct3 & 0x03) + { + case 0: + value = load_byte(hart, address); + if ((inst.funct3 & 0x40) == 0) + { + value = sign_extend(value, 8); + } + break; + case 1: + value = load_half(hart, address); + if ((inst.funct3 & 0x40) == 0) + { + value = sign_extend(value, 16); + } + break; + case 2: + value = load_byte(hart, address); + break; + default: + assert(!"Unhandled load size"); + break; + } + + if (inst.rd != 0) + { + hart->regs[inst.rd] = value; + } +} + +void execute_op_store(struct Hart* hart, uint32_t instruction) +{ + const struct Instruction inst = decode_s_type(instruction); + const uint32_t address = hart->regs[inst.rs1] + inst.imm; + const uint32_t value = hart->regs[inst.rs2]; + + switch (inst.funct3 & 0x03) + { + case 0: store_byte(hart, address, value & 0xFF); break; + case 1: store_half(hart, address, value & 0xFFFF); break; + case 2: store_word(hart, address, value); break; + default: + assert(!"Unhandled store size"); + break; + } +} + +void execute_misc_mem(struct Hart* hart, uint32_t instruction) +{ + const struct Instruction inst = decode_i_type(instruction); + + if (inst.funct3 == 0) + { + // FENCE + } + else + { + assert(!"Unhandled MISC-MEM instruction"); + } +} + +void execute_system(struct Hart* hart, uint32_t instruction) +{ + const struct Instruction inst = decode_i_type(instruction); + + if (inst.funct3 == 0 && inst.rs1 == 0 && inst.rd == 0) + { + if (inst.imm == 0) + { + // ECALL + } + else if (inst.imm == 1) + { + // EBREAK + } + else + { + assert(!"Unhandled SYSTEM/PRIV instruction"); + } + } + else + { + assert(!"Unhandled SYSTEM instruction"); + } +} + void execute(struct Hart* hart, uint32_t instruction) { switch (instruction & 0x7f) { + case 0x03: + execute_op_load(hart, instruction); + hart->pc += 4; + break; + case 0x0F: + execute_misc_mem(hart, instruction); + hart->pc += 4; + break; case 0x13: execute_op_imm(hart, instruction); hart->pc += 4; @@ -224,6 +344,10 @@ void execute(struct Hart* hart, uint32_t instruction) hart->pc += 4; break; } + case 0x23: + execute_op_store(hart, instruction); + hart->pc += 4; + break; case 0x33: execute_op(hart, instruction); hart->pc += 4; @@ -262,6 +386,12 @@ void execute(struct Hart* hart, uint32_t instruction) hart->pc += inst.imm; break; } + case 0x73: + { + execute_system(hart, instruction); + hart->pc += 4; + break; + } default: assert(!"Unhandled opcode"); } -- cgit