diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-05-11 15:38:00 +0200 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-05-11 15:38:00 +0200 |
commit | a64024a13a5c612f5ee393b20c02d531f9a671c2 (patch) | |
tree | 8b979c1e432ff585dd1816c16a8f95b6d4990e1b |
Initial commit
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | build.bat | 2 | ||||
-rw-r--r-- | main.c | 98 |
3 files changed, 101 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1feae78 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.exe
diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..593aa28 --- /dev/null +++ b/build.bat @@ -0,0 +1,2 @@ +clang main.c -o riscv.exe -std=c11
+
@@ -0,0 +1,98 @@ +#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <assert.h>
+
+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;
+}
|