summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--instruction.c518
-rw-r--r--instruction.h15
2 files changed, 329 insertions, 204 deletions
diff --git a/instruction.c b/instruction.c
index 1846832..ecdaa45 100644
--- a/instruction.c
+++ b/instruction.c
@@ -41,7 +41,7 @@ static int unimplemented(struct nios2 *cpu, uint32_t code)
* Used as a placeholder for all instructions which do not have an effect on the
* simulator (e.g. flush, sync)
*/
-static int nop(struct nios2 *cpu, uint32_t code)
+static int nop(struct nios2 *cpu __unused, uint32_t code __unused)
{
/* Nothing to do here */
return PC_INC_NORMAL;
@@ -79,9 +79,14 @@ static int jmpi(struct nios2 *cpu, uint32_t code)
* I-Type instructions
*/
+/* rB <- 0x000000 : Mem8[rA + @(IMM16)] */
static int ldbu(struct nios2 *cpu, uint32_t code)
{
I_TYPE(instr, code);
+ uint32_t *gp_regs = cpu->gp_regs;
+ int32_t addr = gp_regs[instr->a] + (int16_t) instr->imm16;
+
+ gp_regs[instr->b] = memory_get_byte(cpu->mem, addr);
return PC_INC_NORMAL;
}
@@ -107,9 +112,9 @@ static int br(struct nios2 *cpu, uint32_t code)
return PC_INC_NORMAL;
}
-static int ldhu(struct nios2 *cpu, uint32_t code)
+static int ldhu(struct nios2 *cpu __unused, uint32_t code __unused)
{
- I_TYPE(instr, code);
+ /* TODO */
return PC_INC_NORMAL;
}
@@ -125,6 +130,65 @@ static int andi(struct nios2 *cpu, uint32_t code)
return PC_INC_NORMAL;
}
+/* */
+static int sth(struct nios2 *cpu __unused, uint32_t code __unused)
+{
+ /* TODO */
+ return PC_INC_NORMAL;
+}
+
+/*
+ * if ((signed) rA >= (signed) rB)
+ * PC <- PC + 4 + @(IMM16)
+ * else
+ * PC <- PC + 4
+ */
+static int bge(struct nios2 *cpu, uint32_t code)
+{
+ I_TYPE(instr, code);
+ uint32_t *gp_regs = cpu->gp_regs;
+
+ if ((int32_t) gp_regs[instr->a] >= (int32_t) gp_regs[instr->b])
+ cpu->pc += 4 + (instr->imm16 & 0xFFFC);
+ else
+ cpu->pc += 4;
+
+ return PC_INC_BY_INSTR;
+}
+
+/* */
+static int ldh(struct nios2 *cpu __unused, uint32_t code __unused)
+{
+ /* TODO */
+ return PC_INC_NORMAL;
+}
+
+/*
+ * if ((signed) rA < (signed) @(IMM16)
+ * rB <- 1
+ * else
+ * rB <- 0
+ */
+static int cmplti(struct nios2 *cpu, uint32_t code)
+{
+ I_TYPE(instr, code);
+ uint32_t *gp_regs = cpu->gp_regs;
+
+ if ((int32_t) gp_regs[instr->a] < (int32_t) ((int16_t) instr->imm16))
+ gp_regs[instr->b] = 1;
+ else
+ gp_regs[instr->b] = 0;
+
+ return PC_INC_NORMAL;
+}
+
+/* Initializes the data cache line currently caching address rA + @(IMM16) */
+static int initda(struct nios2 *cpu __unused, uint32_t code __unused)
+{
+ /* TODO */
+ return PC_INC_NORMAL;
+}
+
/* rB <- rA | IMM16 */
static int ori(struct nios2 *cpu, uint32_t code)
{
@@ -135,6 +199,14 @@ static int ori(struct nios2 *cpu, uint32_t code)
return PC_INC_NORMAL;
}
+/* */
+static int stw(struct nios2 *cpu, uint32_t code)
+{
+ /* TODO */
+
+ return PC_INC_NORMAL;
+}
+
/*
* if ((signed) rA < (signed) rB)
* PC <- PC + 4 + @(IMM16)
@@ -146,7 +218,7 @@ static int blt(struct nios2 *cpu, uint32_t code)
I_TYPE(instr, code);
uint32_t *gp_regs = cpu->gp_regs;
- if (((int32_t) gp_regs[instr->a]) < ((int32_t) gp_regs[instr->b]))
+ if ((int32_t) gp_regs[instr->a] < (int32_t) gp_regs[instr->b])
cpu->pc += 4 + (int16_t)(instr->imm16 & 0xFFFC);
else
cpu->pc += 4;
@@ -164,6 +236,25 @@ static int xori(struct nios2 *cpu, uint32_t code)
return PC_INC_NORMAL;
}
+/*
+ * if (rA != rB)
+ * PC <- PC + 4 + @(IMM16)
+ * else
+ * PC <- PC + 4
+ */
+static int bne(struct nios2 *cpu, uint32_t code)
+{
+ I_TYPE(instr, code);
+ uint32_t *gp_regs = cpu->gp_regs;
+
+ if (gp_regs[instr->a] != gp_regs[instr->b])
+ cpu->pc += 4 + (int16_t)(instr->imm16 & 0xFFFC);
+ else
+ cpu->pc += 4;
+
+ return PC_INC_BY_INSTR;
+}
+
/* rB <- (rA * @(IMM16))(31..0) */
static int muli(struct nios2 *cpu, uint32_t code)
{
@@ -173,10 +264,10 @@ static int muli(struct nios2 *cpu, uint32_t code)
/* Raise exception if instruction is not implemented */
if (!cpu->has_mul)
- return INSTR_EXECPTION;
+ return EXCEPTION(NIOS2_EX_UNIMPLEMENTED);
tmp = gp_regs[instr->a] * ((int16_t) instr->imm16);
- gp_regs[instr->b] = (uint32_t) (tmp & BIT_MASK(32));
+ gp_regs[instr->b] = (uint32_t) (tmp & BIT_MASK_FILL(32));
return PC_INC_NORMAL;
}
@@ -210,6 +301,14 @@ static int andhi(struct nios2 *cpu, uint32_t code)
return PC_INC_NORMAL;
}
+/* */
+static int initd(struct nios2 *cpu, uint32_t code)
+{
+ /* TODO */
+
+ return PC_INC_NORMAL;
+}
+
/* Prototype only, defined below */
static int handle_r_type_instr(struct nios2 *cpu, uint32_t code);
@@ -224,58 +323,70 @@ static int xorhi(struct nios2 *cpu, uint32_t code)
return PC_INC_NORMAL;
}
-static instruction_handler i_type_instr_handlers[I_TYPE_COUNT] = {
- [CALL] = call,
- [JMPI] = jmpi,
- [LDBU] = ldbu,
- [ADDI] = addi,
- [STB] = unimplemented,
- [BR] = br,
- [LDB] = unimplemented,
- [CMPGEI] = unimplemented,
- [LDHU] = ldhu,
- [ANDI] = andi,
- [STH] = unimplemented,
- [BGE] = unimplemented,
- [LDH] = unimplemented,
- [CMPLTI] = unimplemented,
- [INITDA] = unimplemented,
- [ORI] = ori,
- [STW] = unimplemented,
- [BLT] = blt,
- [LDW] = unimplemented,
- [CMPNEI] = unimplemented,
- [FLUSHDA] = nop,
- [XORI] = xori,
- [BNE] = unimplemented,
- [CMPEQI] = unimplemented,
- [LDBUIO] = unimplemented,
- [MULI] = muli,
- [STBIO] = unimplemented,
- [BEQ] = beq,
- [LDBIO] = unimplemented,
- [CMPGEUI] = unimplemented,
- [LDHUIO] = unimplemented,
- [ANDHI] = andhi,
- [STHIO] = unimplemented,
- [BGEU] = unimplemented,
- [LDHIO] = unimplemented,
- [CMPLTUI] = unimplemented,
- [CUSTOM] = unimplemented,
- [INITD] = unimplemented,
- [ORHI] = unimplemented,
- [STWIO] = unimplemented,
- [BLTU] = unimplemented,
- [LDWIO] = unimplemented,
- [R_TYPE] = handle_r_type_instr,
- [FLUSHD] = nop,
- [XORHI] = xorhi,
+static struct instruction i_type_instructions[I_TYPE_COUNT] = {
+ [CALL] = INSTRUCTION(call),
+ [JMPI] = INSTRUCTION(jmpi),
+ [LDBU] = INSTRUCTION(ldbu),
+ [ADDI] = INSTRUCTION(addi),
+ [STB] = INSTRUCTION_UNIMPLEMENTED(stb),
+ [BR] = INSTRUCTION(br),
+ [LDB] = INSTRUCTION_UNIMPLEMENTED(ldb),
+ [CMPGEI] = INSTRUCTION_UNIMPLEMENTED(cmpgei),
+ [LDHU] = INSTRUCTION(ldhu),
+ [ANDI] = INSTRUCTION(andi),
+ [STH] = INSTRUCTION(sth),
+ [BGE] = INSTRUCTION(bge),
+ [LDH] = INSTRUCTION(ldh),
+ [CMPLTI] = INSTRUCTION(cmplti),
+ [INITDA] = INSTRUCTION(initda),
+ [ORI] = INSTRUCTION(ori),
+ [STW] = INSTRUCTION(stw),
+ [BLT] = INSTRUCTION(blt),
+ [LDW] = INSTRUCTION_UNIMPLEMENTED(ldw),
+ [CMPNEI] = INSTRUCTION_UNIMPLEMENTED(cmpnei),
+ [FLUSHDA] = INSTRUCTION_NOP(flushda),
+ [XORI] = INSTRUCTION(xori),
+ [BNE] = INSTRUCTION(bne),
+ [CMPEQI] = INSTRUCTION_UNIMPLEMENTED(cmpeqi),
+ [LDBUIO] = INSTRUCTION_UNIMPLEMENTED(ldbuio),
+ [MULI] = INSTRUCTION(muli),
+ [STBIO] = INSTRUCTION_UNIMPLEMENTED(stbio),
+ [BEQ] = INSTRUCTION(beq),
+ [LDBIO] = INSTRUCTION_UNIMPLEMENTED(ldbio),
+ [CMPGEUI] = INSTRUCTION_UNIMPLEMENTED(cmpgeui),
+ [LDHUIO] = INSTRUCTION_UNIMPLEMENTED(ldhuio),
+ [ANDHI] = INSTRUCTION(andhi),
+ [STHIO] = INSTRUCTION_UNIMPLEMENTED(sthio),
+ [BGEU] = INSTRUCTION_UNIMPLEMENTED(bgeu),
+ [LDHIO] = INSTRUCTION_UNIMPLEMENTED(ldhio),
+ [CMPLTUI] = INSTRUCTION_UNIMPLEMENTED(cmpltui),
+ [CUSTOM] = INSTRUCTION_UNIMPLEMENTED(custom),
+ [INITD] = INSTRUCTION(initd),
+ [ORHI] = INSTRUCTION_UNIMPLEMENTED(orhi),
+ [STWIO] = INSTRUCTION_UNIMPLEMENTED(stwio),
+ [BLTU] = INSTRUCTION_UNIMPLEMENTED(bltu),
+ [LDWIO] = INSTRUCTION_UNIMPLEMENTED(ldwio),
+ [R_TYPE] = { "<R-type instruction>", handle_r_type_instr },
+ [FLUSHD] = INSTRUCTION_NOP(flushd),
+ [XORHI] = INSTRUCTION(xorhi),
};
/*
* R-Type instructions
*/
+/*
+ * status <- estatus
+ * PC <- ea
+ */
+static int eret(struct nios2 *cpu, uint32_t code __unused)
+{
+ cpu->ctrl_regs[status] = cpu->ctrl_regs[estatus];
+ cpu->pc = cpu->gp_regs[ea];
+
+ return PC_INC_BY_INSTR;
+}
+
/* rC <- rA rotated left IMM5 bit positions */
static int roli(struct nios2 *cpu, uint32_t code)
{
@@ -295,13 +406,29 @@ static int rol(struct nios2 *cpu, uint32_t code)
R_TYPE(instr, code);
uint32_t *gp_regs = cpu->gp_regs;
uint32_t a = gp_regs[instr->a];
- uint32_t shift_bits = gp_regs[instr->b] & BIT_MASK(5);
+ uint32_t shift_bits = gp_regs[instr->b] & BIT_MASK_FILL(5);
- gp_regs[instr->c] = (a << shift_bits) | (a >> (32 - shift_bits));
+ gp_regs[instr->c] = (a << shift_bits) | (a >> (32 - shift_bits));
return PC_INC_NORMAL;
}
+/* */
+static int flushp(struct nios2 *cpu __unused, uint32_t code __unused)
+{
+ /* TODO */
+
+ return PC_INC_NORMAL;
+}
+
+/* PC <- ra */
+static int ret(struct nios2 *cpu, uint32_t code __unused)
+{
+ cpu->pc = cpu->gp_regs[ra];
+
+ return PC_INC_BY_INSTR;
+}
+
/* rC <- ~(A | rB) */
static int nor(struct nios2 *cpu, uint32_t code)
{
@@ -313,6 +440,37 @@ static int nor(struct nios2 *cpu, uint32_t code)
return PC_INC_NORMAL;
}
+/* rC <- rA rotated right rb(4..0) bit positions */
+static int ror(struct nios2 *cpu, uint32_t code)
+{
+ R_TYPE(instr, code);
+ uint32_t *gp_regs = cpu->gp_regs;
+ uint32_t a = gp_regs[instr->a];
+ uint32_t shift_bits = gp_regs[instr->b] & BIT_MASK_FILL(5);
+
+ gp_regs[instr->c] = (a << (32 - shift_bits)) | (a >> shift_bits);
+
+ return PC_INC_NORMAL;
+}
+
+/* */
+static int flushi(struct nios2 *cpu, uint32_t code)
+{
+ /* TODO */
+
+ return PC_INC_NORMAL;
+}
+
+/* PC <- rA */
+static int jmp(struct nios2 *cpu, uint32_t code)
+{
+ R_TYPE(instr, code);
+
+ cpu->pc = cpu->gp_regs[instr->a];
+
+ return PC_INC_BY_INSTR;
+}
+
/* rC <- rA & rB */
static int and(struct nios2 *cpu, uint32_t code)
{
@@ -360,7 +518,7 @@ static int sll(struct nios2 *cpu, uint32_t code)
R_TYPE(instr, code);
uint32_t *gp_regs = cpu->gp_regs;
- gp_regs[instr->c] = gp_regs[instr->a] << (gp_regs[instr->b] & BIT_MASK(5));
+ gp_regs[instr->c] = gp_regs[instr->a] << (gp_regs[instr->b] & BIT_MASK_FILL(5));
return PC_INC_NORMAL;
}
@@ -412,7 +570,7 @@ static int srl(struct nios2 *cpu, uint32_t code)
R_TYPE(instr, code);
uint32_t *gp_regs = cpu->gp_regs;
- gp_regs[instr->c] = gp_regs[instr->a] >> (gp_regs[instr->b] & BIT_MASK(5));
+ gp_regs[instr->c] = gp_regs[instr->a] >> (gp_regs[instr->b] & BIT_MASK_FILL(5));
return PC_INC_NORMAL;
}
@@ -454,11 +612,11 @@ static int divu(struct nios2 *cpu, uint32_t code)
uint32_t *gp_regs = cpu->gp_regs;
if (!cpu->has_div)
- return INSTR_EXECPTION;
+ return EXCEPTION(NIOS2_EX_UNIMPLEMENTED);
/* Division by zero? */
if (gp_regs[instr->b] == 0)
- return INSTR_EXECPTION;
+ return EXCEPTION(NIOS2_EX_DIV_ERR);
gp_regs[instr->c] = gp_regs[instr->a] / gp_regs[instr->b];
@@ -473,15 +631,18 @@ static int div(struct nios2 *cpu, uint32_t code)
int32_t a, b;
if (!cpu->has_div)
- return INSTR_EXECPTION;
+ return EXCEPTION(NIOS2_EX_UNIMPLEMENTED);
+ a = (int32_t) gp_regs[instr->a];
b = (int32_t) gp_regs[instr->b];
/* Division by zero? */
- if (instr->b == 0)
- return INSTR_EXECPTION;
+ if (b == 0)
+ return EXCEPTION(NIOS2_EX_DIV_ERR);
+ /* Divide overflow? */
+ if (a == 0x80000000 && b == 0xFFFFFFFF)
+ return EXCEPTION(NIOS2_EX_DIV_ERR);
- a = (int32_t) gp_regs[instr->a];
gp_regs[instr->c] = (uint32_t)(a / b);
return PC_INC_NORMAL;
@@ -494,13 +655,56 @@ static int rdctl(struct nios2 *cpu, uint32_t code)
/* Instruction only allowed in supervisor mode */
if (!nios2_in_supervisor_mode(cpu))
- return INSTR_EXECPTION;
+ return EXCEPTION(NIOS2_EX_SUPERVISOR_ONLY_I);
cpu->gp_regs[instr->c] = cpu->ctrl_regs[instr->opx.imm5];
return PC_INC_NORMAL;
}
+/* */
+static int initi(struct nios2 *cpu __unused, uint32_t code __unused)
+{
+ /* TODO */
+
+ return PC_INC_NORMAL;
+}
+
+/*
+ * estatus <- status
+ * PIE <- 0
+ * U <- 0
+ * ea <- PC + 4
+ * PC <- exception handler address
+ */
+static int trap(struct nios2 *cpu, uint32_t code __unused)
+{
+ uint32_t *gp_regs = cpu->gp_regs;
+ uint32_t *ctrl_regs = cpu->ctrl_regs;
+
+ ctrl_regs[estatus] = ctrl_regs[status];
+ clear_bit(NIOS2_STATUS_PIE, &ctrl_regs[status]);
+ clear_bit(NIOS2_STATUS_U, &ctrl_regs[status]);
+ gp_regs[ea] = cpu->pc + 4;
+ cpu->pc = cpu->exception_handler_addr;
+
+ return PC_INC_BY_INSTR;
+}
+
+/* ctlN <- rA */
+static int wrctl(struct nios2 *cpu, uint32_t code)
+{
+ R_TYPE(instr, code);
+
+ /* Instruction only allowed in supervisor mode */
+ if (!nios2_in_supervisor_mode(cpu))
+ return EXCEPTION(NIOS2_EX_SUPERVISOR_ONLY_I);
+
+ cpu->ctrl_regs[instr->opx.imm5] = cpu->gp_regs[instr->a];
+
+ return PC_INC_NORMAL;
+}
+
/* rC <- rA + rB */
static int add(struct nios2 *cpu, uint32_t code)
{
@@ -523,48 +727,48 @@ static int sub(struct nios2 *cpu, uint32_t code)
return PC_INC_NORMAL;
}
-static instruction_handler r_type_instr_handlers[R_TYPE_COUNT] = {
- [ERET] = unimplemented,
- [ROLI] = roli,
- [ROL] = rol,
- [FLUSHP] = nop,
- [RET] = unimplemented,
- [NOR] = nor,
- [MULXUU] = unimplemented,
- [CMPGE] = unimplemented,
- [BRET] = unimplemented,
- [ROR] = unimplemented,
- [FLUSHI] = nop,
- [JMP] = unimplemented,
- [AND] = and,
- [CMPLT] = cmplt,
- [SLLI] = slli,
- [SLL] = sll,
- [OR] = or,
- [MULXSU] = unimplemented,
- [CMPNE] = cmpne,
- [SRLI] = srli,
- [SRL] = srl,
- [NEXTPC] = unimplemented,
- [CALLR] = unimplemented,
- [XOR] = xor,
- [MULXSS] = unimplemented,
- [CMPEQ] = cmpeq,
- [DIVU] = divu,
- [DIV] = div,
- [RDCTL] = rdctl,
- [MUL] = unimplemented,
- [CMPGEU] = unimplemented,
- [INITI] = unimplemented,
- [TRAP] = unimplemented,
- [WRCTL] = unimplemented,
- [CMPLTU] = unimplemented,
- [ADD] = add,
- [BREAK] = unimplemented,
- [SYNC] = nop,
- [SUB] = sub,
- [SRAI] = unimplemented,
- [SRA] = unimplemented,
+static struct instruction r_type_instructions[R_TYPE_COUNT] = {
+ [ERET] = INSTRUCTION(eret),
+ [ROLI] = INSTRUCTION(roli),
+ [ROL] = INSTRUCTION(rol),
+ [FLUSHP] = INSTRUCTION(flushp),
+ [RET] = INSTRUCTION(ret),
+ [NOR] = INSTRUCTION(nor),
+ [MULXUU] = INSTRUCTION_UNIMPLEMENTED(mulxuu),
+ [CMPGE] = INSTRUCTION_UNIMPLEMENTED(cmpge),
+ [BRET] = INSTRUCTION_UNIMPLEMENTED(bret),
+ [ROR] = INSTRUCTION(ror),
+ [FLUSHI] = INSTRUCTION(flushi),
+ [JMP] = INSTRUCTION(jmp),
+ [AND] = INSTRUCTION(and),
+ [CMPLT] = INSTRUCTION(cmplt),
+ [SLLI] = INSTRUCTION(slli),
+ [SLL] = INSTRUCTION(sll),
+ [OR] = INSTRUCTION(or),
+ [MULXSU] = INSTRUCTION_UNIMPLEMENTED(mulxsu),
+ [CMPNE] = INSTRUCTION(cmpne),
+ [SRLI] = INSTRUCTION(srli),
+ [SRL] = INSTRUCTION(srl),
+ [NEXTPC] = INSTRUCTION_UNIMPLEMENTED(nextpc),
+ [CALLR] = INSTRUCTION_UNIMPLEMENTED(callr),
+ [XOR] = INSTRUCTION(xor),
+ [MULXSS] = INSTRUCTION_UNIMPLEMENTED(mulxss),
+ [CMPEQ] = INSTRUCTION(cmpeq),
+ [DIVU] = INSTRUCTION(divu),
+ [DIV] = INSTRUCTION(div),
+ [RDCTL] = INSTRUCTION(rdctl),
+ [MUL] = INSTRUCTION_UNIMPLEMENTED(mul),
+ [CMPGEU] = INSTRUCTION_UNIMPLEMENTED(cmpgeu),
+ [INITI] = INSTRUCTION(initi),
+ [TRAP] = INSTRUCTION(trap),
+ [WRCTL] = INSTRUCTION(wrctl),
+ [CMPLTU] = INSTRUCTION_UNIMPLEMENTED(cmpltu),
+ [ADD] = INSTRUCTION(add),
+ [BREAK] = INSTRUCTION_UNIMPLEMENTED(break),
+ [SYNC] = INSTRUCTION(nop),
+ [SUB] = INSTRUCTION(sub),
+ [SRAI] = INSTRUCTION_UNIMPLEMENTED(srai),
+ [SRA] = INSTRUCTION_UNIMPLEMENTED(sra),
};
static int handle_r_type_instr(struct nios2 *cpu, uint32_t code)
@@ -578,7 +782,7 @@ static int handle_r_type_instr(struct nios2 *cpu, uint32_t code)
return INSTR_ERR;
}
- handle_instr = r_type_instr_handlers[opx];
+ handle_instr = r_type_instructions[opx].handler;
if (unlikely(handle_instr == NULL)) {
err("Invalid instruction %08x\n", code);
return INSTR_ERR;
@@ -593,100 +797,8 @@ instruction_handler instruction_get_handler(uint32_t code)
if (unlikely(op >= I_TYPE_COUNT))
return NULL;
- return i_type_instr_handlers[op];
-}
-
-static const char *i_type_instr_strings[I_TYPE_COUNT] = {
- [CALL] = "call",
- [JMPI] = "jmpi",
- [LDBU] = "ldbu",
- [ADDI] = "addi",
- [STB] = "stb",
- [BR] = "br",
- [LDB] = "ldb",
- [CMPGEI] = "cmpgei",
- [LDHU] = "ldhu",
- [ANDI] = "andi",
- [STH] = "sth",
- [BGE] = "bge",
- [LDH] = "ldh",
- [CMPLTI] = "cmplti",
- [INITDA] = "initda",
- [ORI] = "ori",
- [STW] = "stw",
- [BLT] = "blt",
- [LDW] = "ldw",
- [CMPNEI] = "cmpnei",
- [FLUSHDA] = "nop",
- [XORI] = "xori",
- [BNE] = "bne",
- [CMPEQI] = "cmpeqi",
- [LDBUIO] = "ldbuio",
- [MULI] = "muli",
- [STBIO] = "stbio",
- [BEQ] = "beq",
- [LDBIO] = "ldbio",
- [CMPGEUI] = "cmpgeui",
- [LDHUIO] = "ldhuio",
- [ANDHI] = "andhi",
- [STHIO] = "sthio",
- [BGEU] = "bgeu",
- [LDHIO] = "ldhio",
- [CMPLTUI] = "cmpltui",
- [CUSTOM] = "custom",
- [INITD] = "initd",
- [ORHI] = "orhi",
- [STWIO] = "stwio",
- [BLTU] = "bltu",
- [LDWIO] = "ldwio",
- [R_TYPE] = "<R-type instruction>",
- [FLUSHD] = "flushd",
- [XORHI] = "xorhi",
-};
-
-static const char *r_type_instr_strings[R_TYPE_COUNT] = {
- [ERET] = "eret",
- [ROLI] = "roli",
- [ROL] = "rol",
- [FLUSHP] = "flushp",
- [RET] = "ret",
- [NOR] = "nor",
- [MULXUU] = "mulxuu",
- [CMPGE] = "cmpge",
- [BRET] = "bret",
- [ROR] = "ror",
- [FLUSHI] = "flushi",
- [JMP] = "jmp",
- [AND] = "and",
- [CMPLT] = "cmplt",
- [SLLI] = "slli",
- [SLL] = "sll",
- [OR] = "or",
- [MULXSU] = "mulxsu",
- [CMPNE] = "cmpne",
- [SRLI] = "srli",
- [SRL] = "srl",
- [NEXTPC] = "nextpc",
- [CALLR] = "callr",
- [XOR] = "xor",
- [MULXSS] = "mulxss",
- [CMPEQ] = "cmpeq",
- [DIVU] = "divu",
- [DIV] = "div",
- [RDCTL] = "rdctl",
- [MUL] = "mul",
- [CMPGEU] = "cmpgeu",
- [INITI] = "initi",
- [TRAP] = "trap",
- [WRCTL] = "wrctl",
- [CMPLTU] = "cmpltu",
- [ADD] = "add",
- [BREAK] = "break",
- [SYNC] = "sync",
- [SUB] = "sub",
- [SRAI] = "srai",
- [SRA] = "sra",
-};
+ return i_type_instructions[op].handler;
+}
const char *instruction_get_string(uint32_t code)
{
@@ -698,7 +810,7 @@ const char *instruction_get_string(uint32_t code)
uint32_t opx = get_opxcode(code);
if (unlikely(opx >= R_TYPE_COUNT))
return "";
- return r_type_instr_strings[opx];
- }else
- return i_type_instr_strings[op];
+ return r_type_instructions[opx].name;
+ } else
+ return i_type_instructions[op].name;
}
diff --git a/instruction.h b/instruction.h
index 1053936..5a268d3 100644
--- a/instruction.h
+++ b/instruction.h
@@ -202,13 +202,26 @@ enum {
#define INSTR_ERR -1 /* Error in instruction */
#define PC_INC_NORMAL 0 /* Normal PC increment after instruction */
#define PC_INC_BY_INSTR 1 /* PC got incremented by instruction */
-#define INSTR_EXECPTION 2 /* Instruction generated an exception */
+#define INSTR_EXCEPTION_BASE 255 /* Instruction generated an exception */
+
+#define EXCEPTION(cause) (INSTR_EXCEPTION_BASE + (cause))
+#define IS_EXCEPTION(ret) ((ret) >= INSTR_EXCEPTION_BASE)
+#define EXCEPTION_CAUSE(ret) ((uint8_t)((ret) - INSTR_EXCEPTION_BASE))
/* Forward declaration */
struct nios2;
typedef int (*instruction_handler)(struct nios2 *cpu, uint32_t opcode);
+struct instruction {
+ const char *name;
+ instruction_handler handler;
+};
+
+#define INSTRUCTION(name) { __stringify(name), name }
+#define INSTRUCTION_NOP(name) { __stringify(name), nop }
+#define INSTRUCTION_UNIMPLEMENTED(name) { __stringify(name), unimplemented }
+
extern instruction_handler instruction_get_handler(uint32_t code);
extern const char *instruction_get_string(uint32_t code);