summaryrefslogtreecommitdiff
path: root/instruction.h
diff options
context:
space:
mode:
Diffstat (limited to 'instruction.h')
-rw-r--r--instruction.h145
1 files changed, 145 insertions, 0 deletions
diff --git a/instruction.h b/instruction.h
new file mode 100644
index 0000000..3ee18d9
--- /dev/null
+++ b/instruction.h
@@ -0,0 +1,145 @@
+#ifndef INSTRUCTION_H
+#define INSTRUCTION_H
+
+/**
+ * Values used for software-only identification instruction types. Values not
+ * tied to machine language. Guaranteed unique.
+ */
+enum INST_TYPE {
+ INST_TYPE_R,
+ INST_TYPE_NI,
+ INST_TYPE_WI,
+ INST_TYPE_JR,
+ INST_TYPE_JI,
+ INST_TYPE_B
+};
+
+/**
+ * Masks for all four instruction types. Not guaranteed unique
+ */
+#define MASK_INST_RTYPE (0x0000)
+#define MASK_INST_NITYPE (0x4000)
+#define MASK_INST_WITYPE (0x8000)
+#define MASK_INST_JTYPE (0xC000)
+
+/**
+ * ALU operation types
+ * R-type and I-type take 3-bit ALU oper as bits:
+ * xx___xxx xxxxxxxx
+ */
+enum OPER {
+ OPER_ADD = 0,
+ OPER_SUB = 1,
+ OPER_SHL = 2,
+ OPER_SHR = 3,
+ OPER_AND = 4,
+ OPER_OR = 5,
+ OPER_XOR = 6,
+ OPER_MUL = 7,
+};
+#define OPER_SHAMT (11)
+#define MASK_OPER(x) ((x) << OPER_SHAMT)
+
+static const char *oper_to_human[] = {
+ [OPER_ADD] = "add",
+ [OPER_SUB] = "sub",
+ [OPER_SHL] = "shl",
+ [OPER_SHR] = "shr",
+ [OPER_AND] = "and",
+ [OPER_OR ] = "or",
+ [OPER_XOR] = "xor",
+ [OPER_MUL] = "mul"
+};
+
+/**
+ * Masks for jump and branch conditions
+ * J-type instructions (jump, branch) take these as follows:
+ * xxx___xx xxxxxxxx
+ */
+enum JCOND {
+ JB_UNCOND = 0x0,
+ JB_NEVER = 0x1,
+ JB_ZERO = 0x2,
+ JB_NZERO = 0x3,
+ JB_CARRY = 0x4,
+ JB_NCARRY = 0x5,
+ JB_CARRYZ = 0x6,
+ JB_NCARRYZ = 0x7
+};
+#define JB_SHAMT (10)
+#define MASK_JB_COND(x) ((x) << JB_SHAMT)
+#define MASK_IS_JUMP (0 << 13)
+#define MASK_IS_BRANCH (1 << 13)
+#define MASK_JI (0x0 << 8)
+#define MASK_JR (0x1 << 8)
+#define MASK_JUMP_REGISTER(x) ((x) << 5)
+
+static const char *j_to_human[] = {
+ [JB_UNCOND] = "jmp",
+ [JB_NEVER] = "jn",
+ [JB_ZERO] = "jz",
+ [JB_NZERO] = "jnz",
+ [JB_CARRY] = "jc",
+ [JB_NCARRY] = "jnc",
+ [JB_CARRYZ] = "jcz",
+ [JB_NCARRYZ] = "jncz"
+};
+static const char *b_to_human[] = {
+ [JB_UNCOND] = "bra",
+ [JB_NEVER] = "bn",
+ [JB_ZERO] = "bz",
+ [JB_NZERO] = "bnz",
+ [JB_CARRY] = "bc",
+ [JB_NCARRY] = "bnc",
+ [JB_CARRYZ] = "bcz",
+ [JB_NCARRYZ] = "bncz"
+};
+
+/**
+ * Register numbers used in all manner of instructions in varying positions
+ */
+enum REG {
+ REG_0 = 0,
+ REG_1 = 1,
+ REG_2 = 2,
+ REG_3 = 3,
+ REG_4 = 4,
+ REG_5 = 5,
+ REG_6 = 6,
+ REG_H = 7
+};
+
+static const char *reg_to_human[] = {
+ [REG_0] = "$0",
+ [REG_1] = "$1",
+ [REG_2] = "$2",
+ [REG_3] = "$3",
+ [REG_4] = "$4",
+ [REG_5] = "$5",
+ [REG_6] = "$6",
+ [REG_H] = "$H",
+};
+
+/**
+ * Offset macro to turn REG_* into mask for register operands of R-type and
+ * I-type instructions
+ */
+/* destination reg: xxxxx___ xxxxxxxx */
+#define REG_DEST_OFFSET (8)
+#define MASK_REG_DEST(x) ((x) << REG_DEST_OFFSET)
+
+/* left reg: xxxxxxxx ___xxxxx */
+#define REG_LEFT_OFFSET (5)
+#define MASK_REG_LEFT(x) ((x) << REG_LEFT_OFFSET)
+
+/* right reg (R-type only): xxxxxxxx xxx___xx */
+#define REG_RIGHT_OFFSET (2)
+#define MASK_REG_RIGHT(x) ((x) << REG_RIGHT_OFFSET)
+
+/* five LSb are narrow immediate value */
+#define MASK_NI_IMM(x) ((x) & 0x1F)
+
+/* 10 LSb is branch offset */
+#define MASK_B_OFFSET(x) ((x) & 0x3FF)
+
+#endif /* INSTRUCTION_H */