diff options
author | David Phillips <david@sighup.nz> | 2019-04-14 16:10:18 +1200 |
---|---|---|
committer | David Phillips <david@sighup.nz> | 2019-08-03 12:42:57 +1200 |
commit | ac8150b7601d9611818bb8b265a125a347a67004 (patch) | |
tree | aa1440c18551fa415af53daedde76536ac2d000d /instruction.h | |
download | toy-cpu-assembler-ac8150b7601d9611818bb8b265a125a347a67004.tar.xz |
Dirst dump of working prototype
Diffstat (limited to 'instruction.h')
-rw-r--r-- | instruction.h | 145 |
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 */ |