summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--instruction.c59
-rw-r--r--instruction.h150
-rw-r--r--nios2.h33
3 files changed, 175 insertions, 67 deletions
diff --git a/instruction.c b/instruction.c
new file mode 100644
index 0000000..ef7e9f9
--- /dev/null
+++ b/instruction.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Tobias Klauser <tklauser@distanz.ch>
+ *
+ * This file is part of nios2sim-ng.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include "nios2sim-ng.h"
+#include "instruction.h"
+#include "nios2.h"
+
+/*
+ * J-Type instructions
+ */
+
+uint32_t call(struct nios2 *cpu, uint32_t opcode)
+{
+ J_TYPE(instr, opcode);
+
+ return PC_INC_BY_INSTR;
+}
+
+uint32_t jmpi(struct nios2 *cpu, uint32_t opcode)
+{
+ J_TYPE(instr, opcode);
+
+ return PC_INC_BY_INSTR;
+}
+
+/*
+ * I-Type instructions
+ */
+
+uint32_t ldbu(struct nios2 *cpu, uint32_t opcode)
+{
+ I_TYPE(instr, opcode);
+
+ return PC_INC_NORMAL;
+}
+
+uint32_t addi(struct nios2 *cpu, uint32_t opcode)
+{
+ I_TYPE(instr, opcode);
+
+ /* rB <- rA + IMM16 */
+ cpu->gp_regs[instr->b] = cpu->gp_regs[instr->a] + (int16_t) (instr->imm16);
+
+ return PC_INC_NORMAL;
+}
+
+instruction_handler i_type_inst_handlers[I_TYPE_COUNT] = {
+ [CALL] = call,
+ [JMPI] = jmpi,
+ [LDBU] = ldbu,
+ [ADDI] = addi,
+};
diff --git a/instruction.h b/instruction.h
index 7b5d510..57fd1b6 100644
--- a/instruction.h
+++ b/instruction.h
@@ -24,6 +24,9 @@ struct i_type {
uint8_t a:5;
} __packed;
+#define I_TYPE(instr, op) \
+ struct i_type *instr = (struct i_type *) &op
+
/* R-Type instruction */
struct r_type {
uint8_t op:6;
@@ -43,87 +46,29 @@ struct r_type {
uint8_t a:5;
} __packed;
+#define R_TYPE(instr, op) \
+ struct r_type *instr = (struct r_type *) &op
+
/* J-Type instruction */
struct j_type {
uint8_t op:6;
uint32_t imm26:26;
} __packed;
+#define J_TYPE(instr, op) \
+ struct j_type *instr = (struct j_type *) &op
+
/*
* Instruction Opcodes
*/
-/* OPX Encodings for R-Type instructions */
-enum {
- /* 0x00 */
- ERET = 0x01,
- ROLI = 0x02,
- ROL = 0x03,
- FLUSHP = 0x04,
- RET = 0x05,
- NOR = 0x06,
- MULXUU = 0x07,
- CMPGE = 0x08,
- BRET = 0x09,
- /* 0x0A */
- ROR = 0x0B,
- FLUSHI = 0x0C,
- JMP = 0x0D,
- AND = 0x0E,
- /* 0x0F */
- CMPLT = 0x10,
- /* 0x11 */
- SLLI = 0x12,
- SLL = 0x13,
- /* 0x14 */
- /* 0x15 */
- OR = 0x16,
- MULXSU = 0x17,
- CMPNE = 0x18,
- /* 0x19 */
- SRLI = 0x1A,
- SRL = 0x1B,
- NEXTPC = 0x1C,
- CALLR = 0x1D,
- XOR = 0x1E,
- MULXSS = 0x1F,
- CMPEQ = 0x20,
- /* 0x21 */
- /* 0x22 */
- /* 0x23 */
- DIVU = 0x24,
- DIV = 0x25,
- RDCTL = 0x26,
- MUL = 0x27,
- CMPGEU = 0x28,
- INITI = 0x29,
- /* 0x2A */
- /* 0x2B */
- /* 0x2C */
- TRAP = 0x2D,
- WRCTL = 0x2E,
- /* 0x2F */
- CMPLTU = 0x30,
- ADD = 0x31,
- /* 0x32 */
- /* 0x33 */
- BREAK = 0x34,
- /* 0x35 */
- SYNC = 0x36,
- /* 0x37 */
- /* 0x38 */
- SUB = 0x39,
- SRAI = 0x3A,
- SRA = 0x3b,
-};
-
/*
- * OP Encodings for I-Type instructions (except for CALL, which is a J-type
- * instruction)
+ * OP Encodings for I-Type instructions (except for CALL and JMPI, which are
+ * J-type instructions)
*/
enum {
CALL = 0x00, /* J-type */
- JMPI = 0x01,
+ JMPI = 0x01, /* J-type */
/* 0x02 */
LDBU = 0x03,
ADDI = 0x04,
@@ -184,5 +129,76 @@ enum {
FLUSHD = 0x3B,
XORHI = 0x3C,
};
+#define I_TYPE_COUNT 0x40
+
+/* OPX Encodings for R-Type instructions */
+enum {
+ /* 0x00 */
+ ERET = 0x01,
+ ROLI = 0x02,
+ ROL = 0x03,
+ FLUSHP = 0x04,
+ RET = 0x05,
+ NOR = 0x06,
+ MULXUU = 0x07,
+ CMPGE = 0x08,
+ BRET = 0x09,
+ /* 0x0A */
+ ROR = 0x0B,
+ FLUSHI = 0x0C,
+ JMP = 0x0D,
+ AND = 0x0E,
+ /* 0x0F */
+ CMPLT = 0x10,
+ /* 0x11 */
+ SLLI = 0x12,
+ SLL = 0x13,
+ /* 0x14 */
+ /* 0x15 */
+ OR = 0x16,
+ MULXSU = 0x17,
+ CMPNE = 0x18,
+ /* 0x19 */
+ SRLI = 0x1A,
+ SRL = 0x1B,
+ NEXTPC = 0x1C,
+ CALLR = 0x1D,
+ XOR = 0x1E,
+ MULXSS = 0x1F,
+ CMPEQ = 0x20,
+ /* 0x21 */
+ /* 0x22 */
+ /* 0x23 */
+ DIVU = 0x24,
+ DIV = 0x25,
+ RDCTL = 0x26,
+ MUL = 0x27,
+ CMPGEU = 0x28,
+ INITI = 0x29,
+ /* 0x2A */
+ /* 0x2B */
+ /* 0x2C */
+ TRAP = 0x2D,
+ WRCTL = 0x2E,
+ /* 0x2F */
+ CMPLTU = 0x30,
+ ADD = 0x31,
+ /* 0x32 */
+ /* 0x33 */
+ BREAK = 0x34,
+ /* 0x35 */
+ SYNC = 0x36,
+ /* 0x37 */
+ /* 0x38 */
+ SUB = 0x39,
+ SRAI = 0x3A,
+ SRA = 0x3b,
+};
+#define R_TYPE_COUNT 0x40
+
+/* Forward declaration */
+struct nios2;
+
+typedef uint32_t (*instruction_handler)(struct nios2 *cpu, uint32_t opcode);
#endif /* _INSTRUCTION_H_ */
diff --git a/nios2.h b/nios2.h
new file mode 100644
index 0000000..a299bc3
--- /dev/null
+++ b/nios2.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 Tobias Klauser <tklauser@distanz.ch>
+ * Copyright (C) 2010 chysun2000@gmail.com
+ *
+ * This file is part of nios2sim-ng.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _NIOS2_H_
+#define _NIOS2_H_
+
+#include "instruction.h"
+
+#define NIOS2_GP_REG_COUNT 32
+/* there are really 32, but 16-31 are reserved for future use */
+#define NIOS2_CTRL_REG_COUNT 16
+
+struct nios2 {
+ /* General-Purpose Registers */
+ uint32_t gp_regs[NIOS2_GP_REG_COUNT];
+ /* Control Registers */
+ uint32_t ctrl_regs[NIOS2_CTRL_REG_COUNT];
+ /* Program counter */
+ uint32_t pc;
+};
+
+#define PC_INC_NORMAL 0
+#define PC_INC_BY_INSTR 1
+
+#endif /* _NIOS2_H_ */