From a64024a13a5c612f5ee393b20c02d531f9a671c2 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Sat, 11 May 2024 15:38:00 +0200 Subject: Initial commit --- main.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 main.c (limited to 'main.c') diff --git a/main.c b/main.c new file mode 100644 index 0000000..c68fcbe --- /dev/null +++ b/main.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include + +inline uint32_t sign_extend(uint32_t word, uint32_t size) +{ + const uint32_t mask = 1U << (size - 1); + return (word ^ mask) - mask; +} + +struct Instruction +{ + uint8_t opcode; + uint8_t rs1; + uint8_t rs2; + uint8_t rd; + uint8_t funct3; + uint8_t funct7; + uint32_t imm; +}; + +struct Instruction decode_r_type(uint32_t word) +{ + struct Instruction instruction = {0}; + instruction.opcode = word & 0x7F; + instruction.rd = (word >> 7) & 0x1F; + instruction.funct3 = (word >> 12) & 0x07; + instruction.rs1 = (word >> 15) & 0x1F; + instruction.rs2 = (word >> 20) & 0x1F; + instruction.funct7 = word >> 25; + return instruction; +}; + +struct Instruction decode_i_type(uint32_t word) +{ + struct Instruction instruction = {0}; + instruction.opcode = word & 0x7F; + instruction.rd = (word >> 7) & 0x1F; + instruction.funct3 = (word >> 12) & 0x07; + instruction.rs1 = (word >> 15) & 0x1F; + instruction.imm = sign_extend(word >> 20, 12); + return instruction; +}; + +struct Instruction decode_s_type(uint32_t word) +{ + struct Instruction instruction = {0}; + instruction.opcode = word & 0x7F; + instruction.funct3 = (word >> 12) & 0x07; + instruction.rs1 = (word >> 15) & 0x1F; + instruction.rs2 = (word >> 20) & 0x1F; + instruction.imm = sign_extend(((word >> 7) & 0x1F) | (word >> 25), 12); + return instruction; +}; + +struct Instruction decode_b_type(uint32_t word) +{ + struct Instruction instruction = decode_s_type(word); + instruction.imm = ((instruction.imm << 11) & 0x800) | (instruction.imm & 0xfffff7ff); + return instruction; +}; + +struct Instruction decode_u_type(uint32_t word) +{ + struct Instruction instruction = {0}; + instruction.opcode = word & 0x7F; + instruction.rd = (word >> 7) & 0x1F; + instruction.imm = word & 0xFFFFF000; + return instruction; +}; + +struct Instruction decode_j_type(uint32_t word) +{ + struct Instruction instruction = {0}; + instruction.opcode = word & 0x7F; + instruction.rd = (word >> 7) & 0x1F; + instruction.imm = sign_extend( + ((word & 0x80000000) >> 11) | + ((word & 0x000FF000) >> 0) | + ((word & 0x00100000) >> 9) | + ((word & 0x7FE00000) >> 20), 21); + return instruction; +} + +struct Hart +{ + uint32_t pc; + uint32_t regs[32]; +}; + +int main(int argc, char* argv[]) +{ + uint32_t instruction = 0xfa728213; + struct Instruction instr = decode_i_type(instruction); + printf("%u %u %u\n", instr.rd, instr.rs1, instr.imm); + return EXIT_SUCCESS; +} -- cgit