summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob McDonnell <jacob@jacobmcdonnell.com>2026-04-21 19:56:41 -0400
committerJacob McDonnell <jacob@jacobmcdonnell.com>2026-04-21 19:56:41 -0400
commitef375d2a484fd0c3dced72174f0dc39694de433a (patch)
treedc322fafc9447ebf0d10f91ee62807d3beb5f8e1
parent2999bd3b9466617938f2f7ceb689cfbe33b46cd9 (diff)
feat: Encoded Assembly InstructionsHEADmain
Initial Encoding of assembly instructions in C++ structs.
-rw-r--r--.clang-format33
-rw-r--r--Makefile24
-rw-r--r--src/asm.cpp269
-rw-r--r--src/asm.hpp104
-rw-r--r--src/lexer.l147
-rw-r--r--src/opcode.hpp33
6 files changed, 360 insertions, 250 deletions
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..03e32b4
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,33 @@
+---
+BasedOnStyle: LLVM
+ColumnLimit: 120
+IndentWidth: 4
+InsertNewlineAtEOF: true
+KeepEmptyLines:
+ AtEndOfFile: true
+AlignAfterOpenBracket: true
+AlignConsecutiveAssignments: Consecutive
+AlignConsecutiveBitFields: Consecutive
+AlignConsecutiveDeclarations: Consecutive
+AlignArrayOfStructures: Left
+BinPackArguments: false
+BinPackParameters: OnePerLine
+DerivePointerAlignment: false
+IncludeBlocks: Merge
+IncludeCategories:
+ - Regex: '<.*\.h>'
+ Priority: 2
+ - Regex: '<.*>'
+ Priority: 3
+ - Regex: '".*"'
+ Priority: 4
+PointerAlignment: Right
+SortIncludes: true
+SpacesBeforeTrailingComments: 2
+---
+Language: Cpp
+AccessModifierOffset: -4
+BreakConstructorInitializers: AfterColon
+PackConstructorInitializers: CurrentLine
+ReferenceAlignment: Left
+---
diff --git a/Makefile b/Makefile
index c10ffc6..daaad16 100644
--- a/Makefile
+++ b/Makefile
@@ -1,15 +1,26 @@
CC = gcc-15
+CFLAGS = -Wall \
+ -Wextra \
+ -Wpedantic \
+ -std=c23
+CXX = g++-15
+CXXFLAGS = -Wall \
+ -Werror \
+ -Wextra \
+ -Wpedantic \
+ -std=c++17
SRC_DIR = src
-SRCS = $(SRC_DIR)/lex.yy.c \
+SRCS = $(SRC_DIR)/asm.cpp
+GENERATED = $(SRC_DIR)/lex.yy.c \
$(SRC_DIR)/parser.tab.c
PROG = jas
OBJS = $(patsubst %.c, %.o, \
$(patsubst %.cpp, %.o, \
$(patsubst %.cxx, %.o, \
- $(patsubst %.cc, %.o, $(SRCS)))))
+ $(patsubst %.cc, %.o, $(SRCS) $(GENERATED)))))
$(PROG): $(OBJS)
- $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
+ $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
$(SRC_DIR)/parser.tab.c: $(SRC_DIR)/parser.y
bison $(BISONFLAGS) -d $< -o $@
@@ -29,8 +40,11 @@ $(SRC_DIR)/lex.yy.c: $(SRC_DIR)/lexer.l $(SRC_DIR)/parser.tab.c
%.o: %.cc
$(CXX) $(CXXFLAGS) -c $< -o $@
+format: $(SRCS)
+ clang-format -i $^
+
clean:
- rm -rf $(PROG) $(OBJS) $(SRC_DIR)/lex.yy.c $(SRC_DIR)/parser.tab.c $(SRC_DIR)/parser.tab.h
+ rm -rf $(PROG) $(OBJS) $(GENERATED)
-.PHONY: all clean
+.PHONY: all clean format
diff --git a/src/asm.cpp b/src/asm.cpp
index d79f086..15f8a41 100644
--- a/src/asm.cpp
+++ b/src/asm.cpp
@@ -1,143 +1,144 @@
+#include "asm.hpp"
#include <cstdint>
#include <map>
#include <string>
-#include "asm.hpp"
+#include "opcode.hpp"
namespace {
-std::map<std::string, instruction_t> instructions = {
- {"lb", {}},
- {"lh", {}},
- {"lw", {}},
- {"ld", {}},
- {"lbu", {}},
- {"lhu", {}},
- {"lwu", {}},
- {"sb", {}},
- {"sh", {}},
- {"sw", {}},
- {"sd", {}},
- {"li", {}},
- {"lui", {}},
- {"auipc", {}},
- {"mv", {}},
- {"sext.b", {}},
- {"sext.h", {}},
- {"sext.w", {}},
- {"zext.b", {}},
- {"zext.h", {}},
- {"zext.w", {}},
- {"rev8", {}},
- {"czero.eqz", {}},
- {"czero.nez", {}},
- {"addi", {}},
- {"add", {}},
- {"sh1add", {}},
- {"sh2add", {}},
- {"sh3add", {}},
- {"add.wu", {}},
- {"sh1add.wu", {}},
- {"sh2add.wu", {}},
- {"sh3add.wu", {}},
- {"addiw", {}},
- {"addw", {}},
- {"sub", {}},
- {"subw", {}},
- {"neg", {}},
- {"negw", {}},
- {"mul", {}},
- {"mulw", {}},
- {"mulh", {}},
- {"mulhu", {}},
- {"mulhsu", {}},
- {"div", {}},
- {"divu", {}},
- {"rem", {}},
- {"remu", {}},
- {"min", {}},
- {"max", {}},
- {"minu", {}},
- {"maxu", {}},
- {"seqz", {}},
- {"snez", {}},
- {"slti", {}},
- {"slt", {}},
- {"sltiu", {}},
- {"sltu", {}},
- {"bexti", {}},
- {"bext", {}},
- {"andi", {}},
- {"and", {}},
- {"andn", {}},
- {"bclri", {}},
- {"bclr", {}},
- {"ori", {}},
- {"or", {}},
- {"orn", {}},
- {"bseti", {}},
- {"bset", {}},
- {"xori", {}},
- {"xor", {}},
- {"xnor", {}},
- {"binvi", {}},
- {"binv", {}},
- {"not", {}},
- {"orc.b", {}},
- {"slli", {}},
- {"sll", {}},
- {"slliw", {}},
- {"sllw", {}},
- {"slli.wu", {}},
- {"srli", {}},
- {"srl", {}},
- {"srliw", {}},
- {"srlw", {}},
- {"srai", {}},
- {"sra", {}},
- {"sraiw", {}},
- {"sraw", {}},
- {"rori", {}},
- {"ror", {}},
- {"rol", {}},
- {"roriw", {}},
- {"rorw", {}},
- {"rolw", {}},
- {"clz", {}},
- {"clzw", {}},
- {"ctz", {}},
- {"ctzw", {}},
- {"cpop", {}},
- {"cpopw", {}},
- {"j", {}},
- {"jal", {}},
- {"jr", {}},
- {"jalr", {}},
- {"call", {}},
- {"tail", {}},
- {"ret", {}},
- {"beq", {}},
- {"bne", {}},
- {"blt", {}},
- {"bgt", {}},
- {"bge", {}},
- {"ble", {}},
- {"bltu", {}},
- {"bgtu", {}},
- {"bgeu", {}},
- {"bleu", {}},
- {"nop", {}},
- {"ecall", {}},
- {"ebreak", {}},
+const std::map<std::string, instruction_t> instructions = {
+ {"lui", instruction_t{u_type{0, 0, opcode::LUI}} },
+ {"auipc", instruction_t{u_type{0, 0, opcode::AUIPC}} },
+ {"jal", instruction_t{j_type{0, 0, 0, 0, 0, opcode::JAL}} },
+ {"jalr", instruction_t{i_type{0, 0, 0b000, 0, opcode::JALR}} },
+ {"beq", instruction_t{b_type{0, 0, 0, 0, 0b000, 0, 0, opcode::BRANCH}} },
+ {"bne", instruction_t{b_type{0, 0, 0, 0, 0b001, 0, 0, opcode::BRANCH}} },
+ {"blt", instruction_t{b_type{0, 0, 0, 0, 0b100, 0, 0, opcode::BRANCH}} },
+ {"bge", instruction_t{b_type{0, 0, 0, 0, 0b101, 0, 0, opcode::BRANCH}} },
+ {"bltu", instruction_t{b_type{0, 0, 0, 0, 0b110, 0, 0, opcode::BRANCH}} },
+ {"bgeu", instruction_t{b_type{0, 0, 0, 0, 0b111, 0, 0, opcode::BRANCH}} },
+ {"lb", instruction_t{i_type{0, 0, 0b000, 0, opcode::LOAD}} },
+ {"lh", instruction_t{i_type{0, 0, 0b001, 0, opcode::LOAD}} },
+ {"lw", instruction_t{i_type{0, 0, 0b010, 0, opcode::LOAD}} },
+ {"lbu", instruction_t{i_type{0, 0, 0b100, 0, opcode::LOAD}} },
+ {"lhu", instruction_t{i_type{0, 0, 0b101, 0, opcode::LOAD}} },
+ {"sb", instruction_t{s_type{0, 0, 0, 0b000, 0, opcode::STORE}} },
+ {"sh", instruction_t{s_type{0, 0, 0, 0b001, 0, opcode::STORE}} },
+ {"sw", instruction_t{s_type{0, 0, 0, 0b010, 0, opcode::STORE}} },
+ {"addi", instruction_t{i_type{0, 0, 0b000, 0, opcode::OP_IMM}} },
+ {"slti", instruction_t{i_type{0, 0, 0b010, 0, opcode::OP_IMM}} },
+ {"sltiu", instruction_t{i_type{0, 0, 0b011, 0, opcode::OP_IMM}} },
+ {"xori", instruction_t{i_type{0, 0, 0b100, 0, opcode::OP_IMM}} },
+ {"ori", instruction_t{i_type{0, 0, 0b110, 0, opcode::OP_IMM}} },
+ {"andi", instruction_t{i_type{0, 0, 0b111, 0, opcode::OP_IMM}} },
+ {"slli", instruction_t{i_shift_type{0b000000, 0, 0, 0b001, 0, opcode::OP_IMM}} },
+ {"srli", instruction_t{i_shift_type{0b000000, 0, 0, 0b101, 0, opcode::OP_IMM}} },
+ {"srai", instruction_t{i_shift_type{0b010000, 0, 0, 0b101, 0, opcode::OP_IMM}} },
+ {"add", instruction_t{r_type{0b0000000, 0, 0, 0b000, 0, opcode::OP}} },
+ {"sub", instruction_t{r_type{0b0100000, 0, 0, 0b000, 0, opcode::OP}} },
+ {"sll", instruction_t{r_type{0b0000000, 0, 0, 0b001, 0, opcode::OP}} },
+ {"slt", instruction_t{r_type{0b0000000, 0, 0, 0b010, 0, opcode::OP}} },
+ {"sltu", instruction_t{r_type{0b0000000, 0, 0, 0b011, 0, opcode::OP}} },
+ {"xor", instruction_t{r_type{0b0000000, 0, 0, 0b100, 0, opcode::OP}} },
+ {"srl", instruction_t{r_type{0b0000000, 0, 0, 0b101, 0, opcode::OP}} },
+ {"sra", instruction_t{r_type{0b0100000, 0, 0, 0b101, 0, opcode::OP}} },
+ {"or", instruction_t{r_type{0b0000000, 0, 0, 0b110, 0, opcode::OP}} },
+ {"and", instruction_t{r_type{0b0000000, 0, 0, 0b111, 0, opcode::OP}} },
+ {"fence", instruction_t{i_type{0, 0, 0b000, 0, opcode::MISC_MEM}} },
+ {"ecall", instruction_t{i_type{0b000000000000, 0, 0b000, 0, opcode::SYSTEM}} },
+ {"ebreak", instruction_t{i_type{0b000000000001, 0, 0b000, 0, opcode::SYSTEM}} },
+ {"addiw", instruction_t{i_type{0, 0, 0b000, 0, opcode::OP_IMM_32}} },
+ {"slliw", instruction_t{i_shift_type{0b000000, 0, 0, 0b001, 0, opcode::OP_IMM_32}}},
+ {"srliw", instruction_t{i_shift_type{0b000000, 0, 0, 0b101, 0, opcode::OP_IMM_32}}},
+ {"sraiw", instruction_t{i_shift_type{0b010000, 0, 0, 0b101, 0, opcode::OP_IMM_32}}},
+ {"addw", instruction_t{r_type{0b0000000, 0, 0, 0b000, 0, opcode::OP_32}} },
+ {"subw", instruction_t{r_type{0b0100000, 0, 0, 0b000, 0, opcode::OP_32}} },
+ {"sllw", instruction_t{r_type{0b0000000, 0, 0, 0b001, 0, opcode::OP_32}} },
+ {"srlw", instruction_t{r_type{0b0000000, 0, 0, 0b101, 0, opcode::OP_32}} },
+ {"sraw", instruction_t{r_type{0b0100000, 0, 0, 0b101, 0, opcode::OP_32}} },
+ {"ld", instruction_t{i_type{0, 0, 0b011, 0, opcode::LOAD}} },
+ {"lwu", instruction_t{i_type{0, 0, 0b110, 0, opcode::LOAD}} },
+ {"sd", instruction_t{s_type{0, 0, 0, 0b011, 0, opcode::STORE}} },
+ {"mul", instruction_t{r_type{0b0000001, 0, 0, 0b000, 0, opcode::OP}} },
+ {"mulh", instruction_t{r_type{0b0000001, 0, 0, 0b001, 0, opcode::OP}} },
+ {"mulhsu", instruction_t{r_type{0b0000001, 0, 0, 0b010, 0, opcode::OP}} },
+ {"mulhu", instruction_t{r_type{0b0000001, 0, 0, 0b011, 0, opcode::OP}} },
+ {"div", instruction_t{r_type{0b0000001, 0, 0, 0b100, 0, opcode::OP}} },
+ {"divu", instruction_t{r_type{0b0000001, 0, 0, 0b101, 0, opcode::OP}} },
+ {"rem", instruction_t{r_type{0b0000001, 0, 0, 0b110, 0, opcode::OP}} },
+ {"remu", instruction_t{r_type{0b0000001, 0, 0, 0b111, 0, opcode::OP}} },
+ {"mulw", instruction_t{r_type{0b0000001, 0, 0, 0b000, 0, opcode::OP_32}} },
+ {"divw", instruction_t{r_type{0b0000001, 0, 0, 0b100, 0, opcode::OP_32}} },
+ {"divuw", instruction_t{r_type{0b0000001, 0, 0, 0b101, 0, opcode::OP_32}} },
+ {"remw", instruction_t{r_type{0b0000001, 0, 0, 0b110, 0, opcode::OP_32}} },
+ {"remuw", instruction_t{r_type{0b0000001, 0, 0, 0b111, 0, opcode::OP_32}} },
};
-std::map<std::string, uint8_t> registers = {
- {"x0", 0}, {"x1", 1}, {"x2", 2}, {"x3", 3}, {"x4", 4}, {"x5", 5}, {"x6", 6}, {"x7", 7}, {"x8", 8},
- {"x9", 9}, {"x10", 10}, {"x11", 11}, {"x12", 12}, {"x13", 13}, {"x14", 14}, {"x15", 15}, {"x16", 16}, {"x17", 17},
- {"x18", 18}, {"x19", 19}, {"x20", 20}, {"x21", 21}, {"x22", 22}, {"x23", 23}, {"x24", 24}, {"x25", 25}, {"x26", 26},
- {"x27", 27}, {"x28", 28}, {"x29", 29}, {"x30", 30}, {"x31", 31}, {"zero", 0}, {"ra", 1}, {"sp", 2}, {"gp", 3},
- {"tp", 4}, {"t0", 5}, {"t1", 6}, {"t2", 7}, {"s0", 8}, {"fp", 8}, {"s1", 9}, {"a0", 10}, {"a1", 11},
- {"a2", 12}, {"a3", 13}, {"a4", 14}, {"a5", 15}, {"a6", 16}, {"a7", 17}, {"s2", 18}, {"s3", 19}, {"s4", 20},
- {"s5", 21}, {"s6", 22}, {"s7", 23}, {"s8", 24}, {"s9", 25}, {"s10", 26}, {"s11", 27}, {"t3", 28}, {"t4", 29},
- {"t5", 30}, {"t6", 31},
+const std::map<std::string, uint8_t> registers = {
+ {"x0", 0 },
+ {"x1", 1 },
+ {"x2", 2 },
+ {"x3", 3 },
+ {"x4", 4 },
+ {"x5", 5 },
+ {"x6", 6 },
+ {"x7", 7 },
+ {"x8", 8 },
+ {"x9", 9 },
+ {"x10", 10},
+ {"x11", 11},
+ {"x12", 12},
+ {"x13", 13},
+ {"x14", 14},
+ {"x15", 15},
+ {"x16", 16},
+ {"x17", 17},
+ {"x18", 18},
+ {"x19", 19},
+ {"x20", 20},
+ {"x21", 21},
+ {"x22", 22},
+ {"x23", 23},
+ {"x24", 24},
+ {"x25", 25},
+ {"x26", 26},
+ {"x27", 27},
+ {"x28", 28},
+ {"x29", 29},
+ {"x30", 30},
+ {"x31", 31},
+ {"zero", 0 },
+ {"ra", 1 },
+ {"sp", 2 },
+ {"gp", 3 },
+ {"tp", 4 },
+ {"t0", 5 },
+ {"t1", 6 },
+ {"t2", 7 },
+ {"s0", 8 },
+ {"fp", 8 },
+ {"s1", 9 },
+ {"a0", 10},
+ {"a1", 11},
+ {"a2", 12},
+ {"a3", 13},
+ {"a4", 14},
+ {"a5", 15},
+ {"a6", 16},
+ {"a7", 17},
+ {"s2", 18},
+ {"s3", 19},
+ {"s4", 20},
+ {"s5", 21},
+ {"s6", 22},
+ {"s7", 23},
+ {"s8", 24},
+ {"s9", 25},
+ {"s10", 26},
+ {"s11", 27},
+ {"t3", 28},
+ {"t4", 29},
+ {"t5", 30},
+ {"t6", 31},
};
-} // namespace
+} // namespace
diff --git a/src/asm.hpp b/src/asm.hpp
index 4d5eb73..1105409 100644
--- a/src/asm.hpp
+++ b/src/asm.hpp
@@ -3,7 +3,9 @@
#include <cstdint>
-enum class type_t {R, I, S, U, B, J};
+#define VERIFY_SIZE(X) static_assert(sizeof(X) == sizeof(uint32_t), "Size Does Not Match.")
+
+enum class type_t { R, I, S, U, B, J, I_SHIFT };
struct r_type {
uint32_t funct7 : 7;
@@ -12,6 +14,14 @@ struct r_type {
uint32_t funct3 : 3;
uint32_t rd : 5;
uint32_t opcode : 7;
+
+ r_type(uint32_t funct7, uint32_t rs2, uint32_t rs1, uint32_t funct3, uint32_t rd, uint32_t opcode) :
+ funct7(funct7 & 7),
+ rs2(rs2 & 5),
+ rs1(rs1 & 5),
+ funct3(funct3 & 3),
+ rd(rd & 5),
+ opcode(opcode & 7) {}
};
struct i_type {
@@ -20,6 +30,30 @@ struct i_type {
uint32_t funct3 : 3;
uint32_t rd : 5;
uint32_t opcode : 7;
+
+ i_type(uint32_t imm, uint32_t rs1, uint32_t funct3, uint32_t rd, uint32_t opcode) :
+ imm(imm & 12),
+ rs1(rs1 & 5),
+ funct3(funct3 & 3),
+ rd(rd & 5),
+ opcode(opcode & 7) {}
+};
+
+struct i_shift_type {
+ uint32_t shtyp : 6;
+ uint32_t shmat : 6;
+ uint32_t rs1 : 5;
+ uint32_t funct3 : 3;
+ uint32_t rd : 5;
+ uint32_t opcode : 7;
+
+ i_shift_type(uint32_t shtyp, uint32_t shmat, uint32_t rs1, uint32_t funct3, uint32_t rd, uint32_t opcode) :
+ shtyp(shtyp & 6),
+ shmat(shmat & 6),
+ rs1(rs1 & 5),
+ funct3(funct3 & 3),
+ rd(rd & 5),
+ opcode(opcode & 7) {}
};
struct s_type {
@@ -29,12 +63,22 @@ struct s_type {
uint32_t funct3 : 3;
uint32_t imm_lo : 5;
uint32_t opcode : 7;
+
+ s_type(uint32_t imm_hi, uint32_t rs2, uint32_t rs1, uint32_t funct3, uint32_t imm_lo, uint32_t opcode) :
+ imm_hi(imm_hi & 7),
+ rs2(rs2 & 5),
+ rs1(rs1 & 5),
+ funct3(funct3 & 3),
+ imm_lo(imm_lo & 5),
+ opcode(opcode & 7) {}
};
struct u_type {
uint32_t imm : 10;
uint32_t rd : 5;
uint32_t opcode : 7;
+
+ u_type(uint32_t imm, uint32_t rd, uint32_t opcode) : imm(imm & 10), rd(rd & 5), opcode(opcode & 7) {}
};
struct b_type {
@@ -46,6 +90,23 @@ struct b_type {
uint32_t imm_lo : 4;
uint32_t b : 1;
uint32_t opcode : 7;
+
+ b_type(uint32_t a,
+ uint32_t imm_hi,
+ uint32_t rs2,
+ uint32_t rs1,
+ uint32_t funct3,
+ uint32_t imm_lo,
+ uint32_t b,
+ uint32_t opcode) :
+ a(a & 1),
+ imm_hi(imm_hi & 6),
+ rs2(rs2 & 5),
+ rs1(rs1 & 5),
+ funct3(funct3 & 3),
+ imm_lo(imm_lo & 4),
+ b(b & 1),
+ opcode(opcode & 7) {}
};
struct j_type {
@@ -55,19 +116,44 @@ struct j_type {
uint32_t imm_hi : 8;
uint32_t rd : 5;
uint32_t opcode : 7;
+
+ j_type(uint32_t a, uint32_t imm_lo, uint32_t b, uint32_t imm_hi, uint32_t rd, uint32_t opcode) :
+ a(a & 1),
+ imm_lo(imm_lo & 10),
+ b(b & 1),
+ imm_hi(imm_hi & 8),
+ rd(rd & 5),
+ opcode(opcode & 7) {}
};
+VERIFY_SIZE(r_type);
+VERIFY_SIZE(i_type);
+VERIFY_SIZE(i_shift_type);
+VERIFY_SIZE(s_type);
+VERIFY_SIZE(u_type);
+VERIFY_SIZE(b_type);
+VERIFY_SIZE(j_type);
+
struct instruction_t {
- type_t t;
+ type_t type;
union {
- r_type r;
- i_type i;
- s_type s;
- u_type u;
- b_type b;
- j_type j;
- uint32_t value;
+ r_type r;
+ i_type i;
+ i_shift_type is;
+ s_type s;
+ u_type u;
+ b_type b;
+ j_type j;
+ uint32_t value;
};
+
+ explicit instruction_t(const r_type r) : type(type_t::R), r(r) {}
+ explicit instruction_t(const i_type i) : type(type_t::I), i(i) {}
+ explicit instruction_t(const i_shift_type is) : type(type_t::I_SHIFT), is(is) {}
+ explicit instruction_t(const s_type s) : type(type_t::S), s(s) {}
+ explicit instruction_t(const u_type u) : type(type_t::U), u(u) {}
+ explicit instruction_t(const b_type b) : type(type_t::B), b(b) {}
+ explicit instruction_t(const j_type j) : type(type_t::J), j(j) {}
};
#endif // SRC_ASM_HPP_
diff --git a/src/lexer.l b/src/lexer.l
index 6daaf6b..7a24b90 100644
--- a/src/lexer.l
+++ b/src/lexer.l
@@ -23,128 +23,71 @@ extern size_t line_number;
\n { ++line_number; return T_ENDL; }
0x[0-9A-Fa-f]+ { yylval.i_val = atoi(yytext); return T_INTEGER; }
-*[0-9]+ { yylval.i_val = atoi(yytext); return T_INTEGER; }
+lui { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+auipc { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+jal { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+jalr { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+beq { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+bne { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+blt { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+bge { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+bltu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+bgeu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
lb { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
lh { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
lw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-ld { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
lbu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
lhu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-lwu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
sb { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
sh { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
sw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sd { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-li { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-lui { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-auipc { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-mv { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sext.b { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sext.h { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sext.w { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-zext.b { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-zext.h { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-zext.w { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-rev8 { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-czero.eqz { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-czero.nez { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
addi { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+slti { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+sltiu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+xori { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+ori { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+andi { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+slli { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+srli { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+srai { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
add { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sh1add { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sh2add { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sh3add { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-add.wu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sh1add.wu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sh2add.wu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sh3add.wu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+sub { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+sll { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+slt { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+sltu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+xor { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+srl { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+sra { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+or { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+and { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+fence { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+ecall { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+ebreak { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
addiw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+slliw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+srliw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+sraiw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
addw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sub { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
subw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-neg { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-negw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+sllw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+srlw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+sraw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+ld { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+lwu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+sd { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
mul { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-mulw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
mulh { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-mulhu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
mulhsu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+mulhu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
div { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
divu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
rem { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
remu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-min { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-max { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-minu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-maxu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-seqz { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-snez { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-slti { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-slt { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sltiu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sltu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-bexti { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-bext { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-andi { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-and { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-andn { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-bclri { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-bclr { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-ori { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-or { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-orn { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-bseti { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-bset { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-xori { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-xor { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-xnor { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-binvi { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-binv { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-not { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-orc.b { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-slli { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sll { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-slliw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sllw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-slli.wu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-srli { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-srl { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-srliw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-srlw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-srai { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sra { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sraiw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-sraw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-rori { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-ror { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-rol { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-roriw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-rorw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-rolw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-clz { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-clzw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-ctz { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-ctzw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-cpop { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-cpopw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-j { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-jal { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-jr { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-jalr { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-call { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-tail { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-ret { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-beq { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-bne { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-blt { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-bgt { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-bge { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-ble { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-bltu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-bgtu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-bgeu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-bleu { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-nop { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-ecall { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
-ebreak { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+mulw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+divw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+divuw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+remw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
+remuw { yylval.instruction = strdup(yytext); return T_INSTRUCTION; }
zero { yylval.reg = strdup(yytext); return T_REGISTER; }
ra { yylval.reg = strdup(yytext); return T_REGISTER; }
sp { yylval.reg = strdup(yytext); return T_REGISTER; }
diff --git a/src/opcode.hpp b/src/opcode.hpp
new file mode 100644
index 0000000..32254f3
--- /dev/null
+++ b/src/opcode.hpp
@@ -0,0 +1,33 @@
+#ifndef SRC_OPCODES_HPP_
+#define SRC_OPCODES_HPP_
+
+#include <cstdint>
+
+namespace opcode {
+constexpr uint32_t LOAD = 0b0000011;
+constexpr uint32_t LOAD_FP = 0b0000111;
+constexpr uint32_t MISC_MEM = 0b0001111;
+constexpr uint32_t OP_IMM = 0b0010011;
+constexpr uint32_t AUIPC = 0b0010111;
+constexpr uint32_t OP_IMM_32 = 0b0011011;
+constexpr uint32_t STORE = 0b0100011;
+constexpr uint32_t STORE_FP = 0b0100111;
+constexpr uint32_t AMO = 0b0101111;
+constexpr uint32_t OP = 0b0110011;
+constexpr uint32_t OP_32 = 0b0111011;
+constexpr uint32_t LUI = 0b0110111;
+constexpr uint32_t MADD = 0b1000011;
+constexpr uint32_t MSUB = 0b1000111;
+constexpr uint32_t NMSUB = 0b1001011;
+constexpr uint32_t NMADD = 0b1001111;
+constexpr uint32_t OP_FP = 0b1010011;
+constexpr uint32_t OP_IMM_64 = 0b1011011;
+constexpr uint32_t BRANCH = 0b1100011;
+constexpr uint32_t JALR = 0b1100111;
+constexpr uint32_t JAL = 0b1101111;
+constexpr uint32_t SYSTEM = 0b1110011;
+constexpr uint32_t OP_64 = 0b1111011;
+} // namespace opcode
+
+#endif // SRC_OPCODES_HPP_
+