summaryrefslogtreecommitdiff
path: root/src/asm.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/asm.hpp')
-rw-r--r--src/asm.hpp104
1 files changed, 95 insertions, 9 deletions
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_