#ifndef SRC_ASM_HPP_ #define SRC_ASM_HPP_ #include #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; uint32_t rs2 : 5; uint32_t rs1 : 5; 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 { uint32_t imm : 12; uint32_t rs1 : 5; 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 { uint32_t imm_hi : 7; uint32_t rs2 : 5; uint32_t rs1 : 5; 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 { uint32_t a : 1; uint32_t imm_hi : 6; uint32_t rs2 : 5; uint32_t rs1 : 5; uint32_t funct3 : 3; 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 { uint32_t a : 1; uint32_t imm_lo : 10; uint32_t b : 1; 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 type; union { 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_