aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qtmips_machine/core.cpp8
-rw-r--r--qtmips_machine/instruction.cpp318
-rw-r--r--qtmips_machine/instruction.h3
3 files changed, 188 insertions, 141 deletions
diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp
index 4edf35a..c6093dd 100644
--- a/qtmips_machine/core.cpp
+++ b/qtmips_machine/core.cpp
@@ -73,9 +73,11 @@ struct Core::dtFetch Core::fetch() {
struct Core::dtDecode Core::decode(const struct dtFetch &dt) {
uint8_t rwrite;
emit instruction_decoded(dt.inst);
- enum InstructionFlags flags = dt.inst.flags();
- enum AluOp alu_op = dt.inst.alu_op();
- enum AccessControl mem_ctl = dt.inst.mem_ctl();
+ enum InstructionFlags flags;
+ enum AluOp alu_op;
+ enum AccessControl mem_ctl;
+
+ dt.inst.flags_alu_op_mem_ctl(flags, alu_op, mem_ctl);
if (!(flags & IMF_SUPPORTED))
throw QTMIPS_EXCEPTION(UnsupportedInstruction, "Instruction with following opcode is not supported", QString::number(dt.inst.opcode(), 16));
diff --git a/qtmips_machine/instruction.cpp b/qtmips_machine/instruction.cpp
index c11e621..56bc616 100644
--- a/qtmips_machine/instruction.cpp
+++ b/qtmips_machine/instruction.cpp
@@ -59,172 +59,216 @@ using namespace machine;
#define NOALU .alu = ALU_OP_SLL
#define NOMEM .mem_ctl = AC_NONE
-#define IM_UNKNOWN {"UNKNOWN", Instruction::T_UNKNOWN, NOALU, NOMEM, .flags = 0}
+#define IM_UNKNOWN {"UNKNOWN", Instruction::T_UNKNOWN, NOALU, NOMEM, nullptr, .flags = 0}
struct InstructionMap {
const char *name;
enum Instruction::Type type;
enum AluOp alu;
enum AccessControl mem_ctl;
+ const struct InstructionMap *subclass; // when subclass is used then flags has special meaning
unsigned int flags;
};
+#define IMF_SUB_ENCODE(bits, shift) (((bits) << 8) | (shift))
+#define IMF_SUB_GET_BITS(subcode) (((subcode) >> 8) & 0xff)
+#define IMF_SUB_GET_SHIFT(subcode) ((subcode) & 0xff)
+
#define IT_R Instruction::T_R
#define IT_I Instruction::T_I
#define IT_J Instruction::T_J
+// This table is indexed by funct
+static const struct InstructionMap alu_instruction_map[] = {
+ {"SLL", IT_R, ALU_OP_SLL, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_STD},
+ IM_UNKNOWN,
+ {"SRL", IT_R, ALU_OP_SRL, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_SD},
+ {"SRA", IT_R, ALU_OP_SRA, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_SD},
+ {"SLLV", IT_R, ALU_OP_SLLV, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_STD},
+ IM_UNKNOWN,
+ {"SRLV", IT_R, ALU_OP_SRLV, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_STD},
+ {"SRAV", IT_R, ALU_OP_SRAV, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_STD},
+ {"JR", IT_R, ALU_OP_JR, NOMEM, nullptr,
+ .flags = IMF_SUPPORTED | IMF_BJR_REQ_RS},
+ {"JALR", IT_R, ALU_OP_JALR, NOMEM, nullptr,
+ .flags = IMF_SUPPORTED | IMF_REGD | IMF_REGWRITE | IMF_BJR_REQ_RS | IMF_PC8_TO_RT},
+ {"MOVZ", IT_R, ALU_OP_MOVZ, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_STD},
+ {"MOVN", IT_R, ALU_OP_MOVN, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_STD},
+ IM_UNKNOWN,
+ {"BREAK", IT_R, ALU_OP_BREAK, NOMEM, nullptr,
+ .flags = IMF_SUPPORTED},
+ IM_UNKNOWN,
+ IM_UNKNOWN,
+ {"MFHI", IT_R, ALU_OP_MFHI, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_D | IMF_READ_HILO},
+ {"MTHI", IT_R, ALU_OP_MTHI, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_S | IMF_WRITE_HILO},
+ {"MFLO", IT_R, ALU_OP_MFLO, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_D | IMF_READ_HILO},
+ {"MTLO", IT_R, ALU_OP_MTLO, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_S | IMF_WRITE_HILO},
+ IM_UNKNOWN,
+ IM_UNKNOWN,
+ IM_UNKNOWN,
+ IM_UNKNOWN,
+ {"MULT", IT_R, ALU_OP_MULT, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_ST | IMF_WRITE_HILO}, // 24
+ {"MULTU", IT_R, ALU_OP_MULTU, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_ST | IMF_WRITE_HILO}, // 25
+ {"DIV", IT_R, ALU_OP_DIV, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_ST | IMF_WRITE_HILO}, // 26
+ {"DIVU", IT_R, ALU_OP_DIVU, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_ST | IMF_WRITE_HILO}, // 27
+ IM_UNKNOWN, // 28
+ IM_UNKNOWN, // 29
+ IM_UNKNOWN, // 30
+ IM_UNKNOWN, // 31
+ {"ADD", IT_R, ALU_OP_ADDU, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_STD}, // 32
+ {"ADDU", IT_R, ALU_OP_ADDU, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_STD},
+ {"SUB", IT_R, ALU_OP_SUB, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_STD},
+ {"SUBU", IT_R, ALU_OP_SUBU, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_STD},
+ {"AND", IT_R, ALU_OP_AND, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_STD},
+ {"OR", IT_R, ALU_OP_OR, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_STD},
+ {"XOR", IT_R, ALU_OP_XOR, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_STD},
+ {"NOR", IT_R, ALU_OP_NOR, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_STD},
+ IM_UNKNOWN,
+ IM_UNKNOWN,
+ {"SLT", IT_R, ALU_OP_SLT, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_STD},
+ {"SLTU", IT_R, ALU_OP_SLTU, NOMEM, nullptr,
+ .flags = FLAGS_ALU_T_R_STD},
+};
+
+const std::int32_t instruction_map_opcode_field = IMF_SUB_ENCODE(6, 26);
+
// This table is indexed by opcode
static const struct InstructionMap instruction_map[] = {
- {"ALU", IT_R, NOALU, NOMEM, // Alu operations
- .flags = 0},
- {"REGIMM", IT_I, NOALU, NOMEM, // REGIMM (BLTZ, BGEZ)
+ {"ALU", IT_R, NOALU, NOMEM, alu_instruction_map, // Alu operations
+ .flags = IMF_SUB_ENCODE(6, 0)},
+ {"REGIMM", IT_I, NOALU, NOMEM, nullptr, // REGIMM (BLTZ, BGEZ)
.flags = IMF_SUPPORTED | IMF_BJR_REQ_RS},
- {"J", IT_J, NOALU, NOMEM, // J
+ {"J", IT_J, NOALU, NOMEM, nullptr, // J
.flags = IMF_SUPPORTED},
- {"JAL", IT_J, ALU_OP_PASS_S, NOMEM, // JAL
+ {"JAL", IT_J, ALU_OP_PASS_S, NOMEM, nullptr, // JAL
.flags = IMF_SUPPORTED | IMF_PC_TO_R31 | IMF_REGWRITE},
- {"BEQ", IT_I, NOALU, NOMEM, // BEQ
+ {"BEQ", IT_I, NOALU, NOMEM, nullptr, // BEQ
.flags = IMF_SUPPORTED | IMF_BJR_REQ_RS | IMF_BJR_REQ_RT},
- {"BNE", IT_I, NOALU, NOMEM, // BNE
+ {"BNE", IT_I, NOALU, NOMEM, nullptr, // BNE
.flags = IMF_SUPPORTED | IMF_BJR_REQ_RS | IMF_BJR_REQ_RT},
- {"BLEZ", IT_I, NOALU, NOMEM, // BLEZ
+ {"BLEZ", IT_I, NOALU, NOMEM, nullptr, // BLEZ
.flags = IMF_SUPPORTED | IMF_BJR_REQ_RS},
- {"BGTZ", IT_I, NOALU, NOMEM, // BGTZ
+ {"BGTZ", IT_I, NOALU, NOMEM, nullptr, // BGTZ
.flags = IMF_SUPPORTED | IMF_BJR_REQ_RS},
- {"ADDI", IT_I, ALU_OP_ADD, NOMEM, // ADDI
+ {"ADDI", IT_I, ALU_OP_ADD, NOMEM, nullptr, // ADDI
.flags = FLAGS_ALU_I},
- {"ADDIU", IT_I, ALU_OP_ADDU, NOMEM, // ADDIU
+ {"ADDIU", IT_I, ALU_OP_ADDU, NOMEM, nullptr, // ADDIU
.flags = FLAGS_ALU_I},
- {"SLTI", IT_I, ALU_OP_SLT, NOMEM, // SLTI
+ {"SLTI", IT_I, ALU_OP_SLT, NOMEM, nullptr, // SLTI
.flags = FLAGS_ALU_I},
- {"SLTIU", IT_I, ALU_OP_SLTU, NOMEM, // SLTIU
+ {"SLTIU", IT_I, ALU_OP_SLTU, NOMEM, nullptr, // SLTIU
.flags = FLAGS_ALU_I},
- {"ANDI", IT_I, ALU_OP_AND, NOMEM, // ANDI
+ {"ANDI", IT_I, ALU_OP_AND, NOMEM, nullptr, // ANDI
.flags = FLAGS_ALU_I_ZE},
- {"ORI", IT_I, ALU_OP_OR, NOMEM, // ORI
+ {"ORI", IT_I, ALU_OP_OR, NOMEM, nullptr, // ORI
.flags = FLAGS_ALU_I_ZE},
- {"XORI", IT_I, ALU_OP_XOR, NOMEM, // XORI
+ {"XORI", IT_I, ALU_OP_XOR, NOMEM, nullptr, // XORI
.flags = FLAGS_ALU_I_ZE},
- {"LUI", IT_I, ALU_OP_LUI, NOMEM, // LUI
+ {"LUI", IT_I, ALU_OP_LUI, NOMEM, nullptr, // LUI
.flags = FLAGS_ALU_I},
- IM_UNKNOWN, // 16
- IM_UNKNOWN, // 17
- IM_UNKNOWN, // 18
- IM_UNKNOWN, // 19
- IM_UNKNOWN, // 20
- IM_UNKNOWN, // 21
- IM_UNKNOWN, // 22
- IM_UNKNOWN, // 23
- IM_UNKNOWN, // 24
- IM_UNKNOWN, // 25
- IM_UNKNOWN, // 26
- IM_UNKNOWN, // 27
- IM_UNKNOWN, // 28
- IM_UNKNOWN, // 29
- IM_UNKNOWN, // 30
- IM_UNKNOWN, // 31
- {"LB", IT_I, ALU_OP_ADDU, AC_BYTE, // LB
+ IM_UNKNOWN, // 16
+ IM_UNKNOWN, // 17
+ IM_UNKNOWN, // 18
+ IM_UNKNOWN, // 19
+ IM_UNKNOWN, // 20
+ IM_UNKNOWN, // 21
+ IM_UNKNOWN, // 22
+ IM_UNKNOWN, // 23
+ IM_UNKNOWN, // 24
+ IM_UNKNOWN, // 25
+ IM_UNKNOWN, // 26
+ IM_UNKNOWN, // 27
+ IM_UNKNOWN, // 28
+ IM_UNKNOWN, // 29
+ IM_UNKNOWN, // 30
+ IM_UNKNOWN, // 31
+ {"LB", IT_I, ALU_OP_ADDU, AC_BYTE, nullptr, // LB
.flags = FLAGS_ALU_I_LOAD},
- {"LH", IT_I, ALU_OP_ADDU, AC_HALFWORD, // LH
+ {"LH", IT_I, ALU_OP_ADDU, AC_HALFWORD, nullptr, // LH
.flags = FLAGS_ALU_I_LOAD},
- {"LWL", IT_I, ALU_OP_ADDU, NOMEM, // LWL - unsupported
+ {"LWL", IT_I, ALU_OP_ADDU, NOMEM, nullptr, // LWL - unsupported
.flags = IMF_MEM},
- {"LW", IT_I, ALU_OP_ADDU, AC_WORD, // LW
+ {"LW", IT_I, ALU_OP_ADDU, AC_WORD, nullptr, // LW
.flags = FLAGS_ALU_I_LOAD},
- {"LBU", IT_I, ALU_OP_ADDU, AC_BYTE_UNSIGNED, // LBU
+ {"LBU", IT_I, ALU_OP_ADDU, AC_BYTE_UNSIGNED, nullptr, // LBU
.flags = FLAGS_ALU_I_LOAD},
- {"LHU", IT_I, ALU_OP_ADDU, AC_HALFWORD_UNSIGNED, // LHU
+ {"LHU", IT_I, ALU_OP_ADDU, AC_HALFWORD_UNSIGNED, nullptr, // LHU
.flags = FLAGS_ALU_I_LOAD},
- {"LWR", IT_I, ALU_OP_ADDU, NOMEM, // LWR - unsupported
+ {"LWR", IT_I, ALU_OP_ADDU, NOMEM, nullptr, // LWR - unsupported
.flags = IMF_MEM},
- IM_UNKNOWN, // 39
- {"SB", IT_I, ALU_OP_ADDU, AC_BYTE, // SB
+ IM_UNKNOWN, // 39
+ {"SB", IT_I, ALU_OP_ADDU, AC_BYTE, nullptr, // SB
.flags = FLAGS_ALU_I_STORE},
- {"SH", IT_I, ALU_OP_ADDU, AC_HALFWORD, // SH
+ {"SH", IT_I, ALU_OP_ADDU, AC_HALFWORD, nullptr, // SH
.flags = FLAGS_ALU_I_STORE},
- {"SWL", IT_I, ALU_OP_ADDU, NOMEM, // SWL
+ {"SWL", IT_I, ALU_OP_ADDU, NOMEM, nullptr, // SWL
.flags = IMF_MEM | IMF_MEM_STORE},
- {"SW", IT_I, ALU_OP_ADDU, AC_WORD, // SW
+ {"SW", IT_I, ALU_OP_ADDU, AC_WORD, nullptr, // SW
.flags = FLAGS_ALU_I_STORE},
- IM_UNKNOWN, // 44,NOPE, // 44
- IM_UNKNOWN, // 45,NOPE, // 45
- {"SWR", IT_I, ALU_OP_ADDU, NOMEM, // SWR
+ IM_UNKNOWN, // 44
+ IM_UNKNOWN, // 45
+ {"SWR", IT_I, ALU_OP_ADDU, NOMEM, nullptr, // SWR
.flags = IMF_MEM | IMF_MEM_STORE},
- {"CACHE", IT_I, ALU_OP_ADDU, AC_CACHE_OP, // CACHE
+ {"CACHE", IT_I, ALU_OP_ADDU, AC_CACHE_OP, nullptr, // CACHE
.flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_MEM| IMF_MEM_STORE},
- IM_UNKNOWN, // 48
- IM_UNKNOWN, // 49
- IM_UNKNOWN, // 50
- IM_UNKNOWN, // 51
- IM_UNKNOWN, // 52
- IM_UNKNOWN, // 53
- IM_UNKNOWN, // 54
- IM_UNKNOWN, // 55
- IM_UNKNOWN, // 56
- IM_UNKNOWN, // 57
- IM_UNKNOWN, // 58
- IM_UNKNOWN, // 59
- IM_UNKNOWN, // 60
- IM_UNKNOWN, // 61
- IM_UNKNOWN, // 62
- IM_UNKNOWN, // 63
+ IM_UNKNOWN, // 48
+ IM_UNKNOWN, // 49
+ IM_UNKNOWN, // 50
+ IM_UNKNOWN, // 51
+ IM_UNKNOWN, // 52
+ IM_UNKNOWN, // 53
+ IM_UNKNOWN, // 54
+ IM_UNKNOWN, // 55
+ IM_UNKNOWN, // 56
+ IM_UNKNOWN, // 57
+ IM_UNKNOWN, // 58
+ IM_UNKNOWN, // 59
+ IM_UNKNOWN, // 60
+ IM_UNKNOWN, // 61
+ IM_UNKNOWN, // 62
+ IM_UNKNOWN, // 63
};
-#undef IM_UNKNOWN
-struct AluInstructionMap {
- const char *name;
- unsigned int flags;
-};
+#undef IM_UNKNOWN
-#define AIM_UNKNOWN {"UNKNOWN", IMF_NONE}
-// This table is indexed by funct
-static const struct AluInstructionMap alu_instruction_map[] = {
- {"SLL", FLAGS_ALU_T_R_STD},
- AIM_UNKNOWN,
- {"SRL", FLAGS_ALU_T_R_SD},
- {"SRA", FLAGS_ALU_T_R_SD},
- {"SLLV", FLAGS_ALU_T_R_STD},
- AIM_UNKNOWN,
- {"SRLV", FLAGS_ALU_T_R_STD},
- {"SRAV", FLAGS_ALU_T_R_STD},
- {"JR", IMF_SUPPORTED | IMF_BJR_REQ_RS},
- {"JALR", IMF_SUPPORTED | IMF_REGD | IMF_REGWRITE | IMF_BJR_REQ_RS | IMF_PC8_TO_RT},
- {"MOVZ", FLAGS_ALU_T_R_STD},
- {"MOVN", FLAGS_ALU_T_R_STD},
- AIM_UNKNOWN,
- {"BREAK", IMF_SUPPORTED},
- AIM_UNKNOWN,
- AIM_UNKNOWN,
- {"MFHI", FLAGS_ALU_T_R_D | IMF_READ_HILO},
- {"MTHI", FLAGS_ALU_T_R_S | IMF_WRITE_HILO},
- {"MFLO", FLAGS_ALU_T_R_D | IMF_READ_HILO},
- {"MTLO", FLAGS_ALU_T_R_S | IMF_WRITE_HILO},
- AIM_UNKNOWN,
- AIM_UNKNOWN,
- AIM_UNKNOWN,
- AIM_UNKNOWN,
- {"MULT", FLAGS_ALU_T_R_ST | IMF_WRITE_HILO}, // 24
- {"MULTU", FLAGS_ALU_T_R_ST | IMF_WRITE_HILO}, // 25
- {"DIV", FLAGS_ALU_T_R_ST | IMF_WRITE_HILO}, // 26
- {"DIVU", FLAGS_ALU_T_R_ST | IMF_WRITE_HILO}, // 27
- AIM_UNKNOWN, // 28
- AIM_UNKNOWN, // 29
- AIM_UNKNOWN, // 30
- AIM_UNKNOWN, // 31
- {"ADD", FLAGS_ALU_T_R_STD}, // 32
- {"ADDU", FLAGS_ALU_T_R_STD},
- {"SUB", FLAGS_ALU_T_R_STD},
- {"SUBU", FLAGS_ALU_T_R_STD},
- {"AND", FLAGS_ALU_T_R_STD},
- {"OR", FLAGS_ALU_T_R_STD},
- {"XOR", FLAGS_ALU_T_R_STD},
- {"NOR", FLAGS_ALU_T_R_STD},
- AIM_UNKNOWN,
- AIM_UNKNOWN,
- {"SLT", FLAGS_ALU_T_R_STD},
- {"SLTU", FLAGS_ALU_T_R_STD}
-};
-#undef AIM_UNKNOWN
+static inline const struct InstructionMap &InstructionMapFind(std::uint32_t code) {
+ const struct InstructionMap *im = instruction_map;
+ std::uint32_t flags = instruction_map_opcode_field;
+ do {
+ unsigned int bits = IMF_SUB_GET_BITS(flags);
+ unsigned int shift = IMF_SUB_GET_SHIFT(flags);
+ im = im + ((code >> shift) & ((1 << bits) - 1));
+ if (im->subclass == nullptr)
+ return *im;
+ flags = im->flags;
+ im = im->subclass;
+ } while(1);
+}
Instruction::Instruction() {
this->dt = 0;
@@ -302,34 +346,32 @@ std::uint32_t Instruction::data() const {
}
enum Instruction::Type Instruction::type() const {
- if (opcode() >= (sizeof(instruction_map) / sizeof(struct InstructionMap)))
- return T_UNKNOWN;
- const struct InstructionMap &im = instruction_map[opcode()];
+ const struct InstructionMap &im = InstructionMapFind(dt);
return im.type;
}
enum InstructionFlags Instruction::flags() const {
- if (opcode() >= (sizeof(instruction_map) / sizeof(struct InstructionMap)))
- return (enum InstructionFlags)0;
- if (opcode() == 0) {
- return (enum InstructionFlags)alu_instruction_map[funct()].flags;
- }
- const struct InstructionMap &im = instruction_map[opcode()];
+ const struct InstructionMap &im = InstructionMapFind(dt);
return (enum InstructionFlags)im.flags;
}
enum AluOp Instruction::alu_op() const {
- if (opcode() >= (sizeof(instruction_map) / sizeof(struct InstructionMap)))
- return ALU_OP_UNKNOWN;
- const struct InstructionMap &im = instruction_map[opcode()];
- return opcode() == 0? (enum AluOp)funct(): im.alu;
+ const struct InstructionMap &im = InstructionMapFind(dt);
+ return im.alu;
}
+
enum AccessControl Instruction::mem_ctl() const {
- if (opcode() >= (sizeof(instruction_map) / sizeof(struct InstructionMap)))
- return AC_NONE;
- const struct InstructionMap &im = instruction_map[opcode()];
+ const struct InstructionMap &im = InstructionMapFind(dt);
return im.mem_ctl;
}
+void Instruction::flags_alu_op_mem_ctl(enum InstructionFlags &flags,
+ enum AluOp &alu_op, enum AccessControl &mem_ctl) const {
+ const struct InstructionMap &im = InstructionMapFind(dt);
+ flags = (enum InstructionFlags)im.flags;
+ alu_op = im.alu;
+ mem_ctl = im.mem_ctl;
+}
+
bool Instruction::is_break() const {
return opcode() == 0 && funct() == ALU_OP_BREAK;
}
@@ -377,9 +419,9 @@ QString Instruction::to_str() const {
case T_R:
{
// Note that all R instructions we support has opcode == 0 and so they are processed by alu table
- if (funct() >= (sizeof(alu_instruction_map) / sizeof(struct AluInstructionMap)))
+ if (funct() >= (sizeof(alu_instruction_map) / sizeof(*alu_instruction_map)))
return QString("UNKNOWN");
- const struct AluInstructionMap &am = alu_instruction_map[funct()];
+ const struct InstructionMap &am = alu_instruction_map[funct()];
res += am.name;
res += " $" + QString::number(rd()) + ", $" + QString::number(rs()) + ", $" + QString::number(rt());
break;
diff --git a/qtmips_machine/instruction.h b/qtmips_machine/instruction.h
index c19a205..496f75e 100644
--- a/qtmips_machine/instruction.h
+++ b/qtmips_machine/instruction.h
@@ -95,6 +95,9 @@ public:
enum AluOp alu_op() const;
enum AccessControl mem_ctl() const;
+ void flags_alu_op_mem_ctl(enum InstructionFlags &flags,
+ enum AluOp &alu_op, enum AccessControl &mem_ctl) const;
+
bool is_break() const;
bool operator==(const Instruction &c) const;