/* * Copyright (C) 2010 Tobias Klauser * 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 _INSTRUCTION_H_ #define _INSTRUCTION_H_ /* * Instruction Word Formats */ /* I-Type instruction */ struct i_type { uint8_t op:6; uint16_t imm16:16; uint8_t b:5; 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; /* * Some R-Type instructions embed a small immediate value in the * low-order bits of OPX. */ uint8_t imm5:5; uint8_t opx6:6; uint8_t c:5; uint8_t b:5; 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 */ /* * OP Encodings for I-Type instructions (except for CALL and JMPI, which are * J-type instructions) */ enum { CALL = 0x00, /* J-type */ JMPI = 0x01, /* J-type */ /* 0x02 */ LDBU = 0x03, ADDI = 0x04, STB = 0x05, BR = 0x06, LDB = 0x07, CMPGEI = 0x08, /* 0x09 */ /* 0x0A */ LDHU = 0x0B, ANDI = 0x0C, STH = 0x0D, BGE = 0x0E, LDH = 0x0F, CMPLTI = 0x10, /* 0x11 */ /* 0x12 */ INITDA = 0x13, ORI = 0x14, STW = 0x15, BLT = 0x16, LDW = 0x17, CMPNEI = 0x18, /* 0x19 */ /* 0x1A */ FLUSHDA = 0x1B, XORI = 0x1C, /* 0x1D */ BNE = 0x1E, /* 0x1F */ CMPEQI = 0x20, /* 0x21 */ /* 0x22 */ LDBUIO = 0x23, MULI = 0x24, STBIO = 0x25, BEQ = 0x26, LDBIO = 0x27, CMPGEUI = 0x28, /* 0x29 */ /* 0x2A */ LDHUIO = 0x2B, ANDHI = 0x2C, STHIO = 0x2D, BGEU = 0x2E, LDHIO = 0x2F, CMPLTUI = 0x30, /* 0x31 */ CUSTOM = 0x32, INITD = 0x33, ORHI = 0x34, STWIO = 0x35, BLTU = 0x36, LDWIO = 0x37, /* 0x38 */ /* 0x39 */ R_TYPE = 0x3A, 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 /* * Return values for instruction handlers */ #define INSTR_UNIMPL -2 /* Unimplemented instruction */ #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_BREAK 2 /* Break encountered */ #define INSTR_EXCEPTION 255 /* Instruction generated an exception (the exception cause will be stored in struct nios2 */ #define EXCEPTION(cpu, cause) \ ({ \ (cpu)->exception_cause = cause; \ INSTR_EXCEPTION; \ }) /* 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); #endif /* _INSTRUCTION_H_ */