diff --git a/.gitattributes b/.gitattributes
index 40d44f34f2cd8f2fcd5c5a0c0132bb31bd84a6dc..3a625c81a70565fce04cd68f30d012c548ad0d67 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -19,11 +19,13 @@ include/interfaces/abstract/STARSFunction.h -text
 include/interfaces/abstract/STARSInstruction.h -text
 include/interfaces/abstract/STARSInstructionID.h -text
 include/interfaces/abstract/STARSInterface.h -text
+include/interfaces/abstract/STARSOp.h -text
 include/interfaces/abstract/STARSSegment.h -text
 include/interfaces/abstract/all.h -text
 include/interfaces/idapro/STARSFunction.h -text
 include/interfaces/idapro/STARSInstruction.h -text
 include/interfaces/idapro/STARSInterface.h -text
+include/interfaces/idapro/STARSOp.h -text
 include/interfaces/idapro/STARSSegment.h -text
 include/interfaces/idapro/all.h -text
 /install-sh -text
@@ -49,6 +51,7 @@ src/interfaces/abstract/STARSInstruction.cpp -text
 src/interfaces/idapro/Makefile.in -text
 src/interfaces/idapro/STARSFunction.cpp -text
 src/interfaces/idapro/STARSIDAInstruction.cpp -text
+src/interfaces/idapro/STARSIDAOp.cpp -text
 src/interfaces/idapro/STARSInterface.cpp -text
 src/interfaces/irdb/Makefile.in -text
 tests/commit/busybox.psexe -text
diff --git a/include/base/SMPInstr.h b/include/base/SMPInstr.h
index 7c9ccf008cef7d988f4775ab017c9a0a7ada3d49..5c9db66f961e61ae5c0b79abd55e3aec8ef47a28 100644
--- a/include/base/SMPInstr.h
+++ b/include/base/SMPInstr.h
@@ -659,6 +659,7 @@ private:
 	SMPBasicBlock *BasicBlock;  // basic block containing this instruction
 	insn_t SMPcmd; // copy of 'cmd' for this instruction
 	STARS_InstructionID_t STARS_ID;  // instruction ID; could be IDA Pro address or IRDB inst ID
+	STARS_Instruction_t *STARSInstPtr; // pointer to either STARS_IDA_Instruction_t or STARS_IRDB_Instruction_t
 	uint32 features; // Canonical features for SMPcmd
 	SMPitype  type; // Data flow analysis category
 	int OptType;   // Optimization category (see OptCategory[])
diff --git a/include/interfaces/abstract/STARSOp.h b/include/interfaces/abstract/STARSOp.h
new file mode 100644
index 0000000000000000000000000000000000000000..4e38766b2acd4fc6d943746c5ad9ae9fcc266e99
--- /dev/null
+++ b/include/interfaces/abstract/STARSOp.h
@@ -0,0 +1,44 @@
+#ifndef STARSOp_h
+#define STARSOp_h
+
+#include <stdint.h>
+#include <assert.h>
+#include <map>
+
+class STARS_op_t
+{
+	public:
+		
+		// Constructors
+		STARS_op_t();
+
+		// Operators
+		virtual bool operator<(const STARS_op_t &rOp) const = 0;
+
+		// Get methods
+		virtual uintptr_t GetAddr(void) const = 0;
+		virtual unsigned char GetType(void) const = 0; // Get type o_reg, o_displ, etc.
+		virtual uint16 GetReg(void) const = 0;  // Get reg field of operand, whether it is an addressing reg or directly used reg in register operand
+		virtual char GetSIB(void) const = 0; // Get x86 SIB byte (dense encoding of base reg, index reg, and scale factor)
+		virtual char GetSpecFlag4(void) const = 0; // Get specflag4 byte, used to hold a copy of the auxpref byte in x86-64 programs.
+		virtual uintptr_t GetImmedValue(void) const = 0; // Get value field for immediate operands; uint32 for x86-32, uint64 for x86-64
+
+		// Set methods
+		virtual void SetSpecFlag4(char value) = 0;
+		virtual void SetBitInSpecFlag4(char value) = 0; // OR in the value to set a bit
+
+		// Query methods
+		virtual bool IsRegOp(void) const = 0;
+		virtual bool IsVoidOp(void) const = 0;
+		virtual bool IsMemDisplacementOp(void) const = 0;
+		virtual bool IsStaticMemOp(void) const = 0;
+		virtual bool IsMemNoDisplacementOp(void) const = 0;
+		virtual bool HasSIBByte(void) const = 0;
+
+
+};
+
+#endif
+
+
+
diff --git a/include/interfaces/abstract/all.h b/include/interfaces/abstract/all.h
index 1c7259f5f526d8914eb83f8c6aab4c5effad11d1..92b69437bdf9eec1e9b84c03649388296f9448b6 100644
--- a/include/interfaces/abstract/all.h
+++ b/include/interfaces/abstract/all.h
@@ -6,4 +6,5 @@
 #include <interfaces/abstract/STARSFunction.h>
 #include <interfaces/abstract/STARSInstructionID.h>
 #include <interfaces/abstract/STARSInstruction.h>
+#include <interfaces/abstract/STARSOp.h>
 
diff --git a/include/interfaces/idapro/STARSInstruction.h b/include/interfaces/idapro/STARSInstruction.h
index 6e3508fdf15013376f2dc9acd1171116555588d5..41205475877714f64adc6f8e8b7f08183fd786b1 100644
--- a/include/interfaces/idapro/STARSInstruction.h
+++ b/include/interfaces/idapro/STARSInstruction.h
@@ -4,6 +4,7 @@
 #include <pro.h>
 #include <ua.hpp>
 #include "interfaces/SMPDBInterface.h"
+#include "interfaces/idapro/all.h"
 
 // struct to hold items that mimic the IDA Pro type insn_t.
 struct STARS_IDA_insn_t
@@ -57,7 +58,7 @@ struct STARS_IDA_insn_t
   char insnpref;                // processor dependent field
 
 // Information about instruction operands.
-  op_t Operands[UA_MAXOP];
+  STARS_IDA_op_t *Operands[UA_MAXOP];
 
   char flags;                   // instruction flags
 
@@ -68,11 +69,11 @@ class STARS_IDA_Instruction_t : public STARS_Instruction_t
 	public:
 		
 		STARS_IDA_Instruction_t(const STARS_InstructionID_t& p_id) : STARS_Instruction_t(p_id) {};
-		STARS_InstructionID_t GetNextInstructionID();
-		STARS_InstructionID_t GetTargetInstructionID();
+		STARS_InstructionID_t GetNextInstructionID(void);
+		STARS_InstructionID_t GetTargetInstructionID(void);
 		bool STARS_GetCmd(void);
 		inline uint32 GetFeatures(void) const { return STARSfeatures; };
-		inline bool IsRegOpnd(size_t OpndNum) const { return (STARScmd.Operands[OpndNum].type == o_reg); };
+		inline bool IsRegOpnd(size_t OpndNum) const { return (STARScmd.Operands[OpndNum]->GetType() == o_reg); };
 #if 0
 		STARSOpndTypePtr GetOpnd(size_t OpndNum);
 		STARSOpndTypePtr MakeVoidOpnd(void);
diff --git a/include/interfaces/idapro/STARSOp.h b/include/interfaces/idapro/STARSOp.h
new file mode 100644
index 0000000000000000000000000000000000000000..5a32bb7b47c11eedfd97d9853e401b3e044feea4
--- /dev/null
+++ b/include/interfaces/idapro/STARSOp.h
@@ -0,0 +1,45 @@
+#ifndef STARS_IDA_op_h
+#define STARS_IDA_op_h
+
+#include <stdint.h>
+#include <pro.h>
+#include <ua.hpp>
+
+class STARS_IDA_op_t : public STARS_op_t
+{
+	public:
+		
+		// Constructors
+		STARS_IDA_op_t(op_t IDAOp) : m_Opnd(IDAOp) {};
+
+		// Operators
+		bool operator<(const STARS_op_t &rOp) const;
+
+		// Get methods
+		uintptr_t GetAddr(void) const { return m_Opnd.addr; };
+		unsigned char GetType(void) const { return m_Opnd.type; };
+		uint16 GetReg(void) const { return m_Opnd.reg; };
+		char GetSIB(void) const { return m_Opnd.sib; }; // Get x86 SIB byte (dense encoding of base reg, index reg, and scale factor)
+		char GetSpecFlag4(void) const {return m_Opnd.specflag4; }; // Get specflag4 byte, used to hold a copy of the auxpref byte in x86-64 programs.
+		uintptr_t GetImmedValue(void) const {return m_Opnd.value; }; // Get value field for immediate operands; uint32 for x86-32, uint64 for x86-64
+
+		// Set methods
+		void SetSpecFlag4(char value) { m_Opnd.specflag4 = value; };
+		void SetBitInSpecFlag4(char value) { m_Opnd.specflag4 |= value; };
+
+		// Query methods
+		bool IsRegOp(void) const { return (m_Opnd.type == o_reg); };
+		bool IsVoidOp(void) const { return (m_Opnd.type == o_void); };
+		bool IsMemDisplacementOp(void) const { return (m_Opnd.type == o_displ); };
+		bool IsStaticMemOp(void) const { return (m_Opnd.type == o_mem); };
+		bool IsMemNoDisplacementOp(void) const { return (m_Opnd.type == o_phrase); };
+		bool HasSIBByte(void) const { return (m_Opnd.hasSIB != 0); };
+
+	protected:
+		op_t m_Opnd;
+};
+
+#endif
+
+
+
diff --git a/include/interfaces/idapro/all.h b/include/interfaces/idapro/all.h
index 2197d6d128c4170e16f3724ae5e634f89132944b..1ff16a1e85112ddfdff9cad740c79a2a6508d36c 100644
--- a/include/interfaces/idapro/all.h
+++ b/include/interfaces/idapro/all.h
@@ -21,4 +21,5 @@
 #include <interfaces/idapro/STARSFunction.h>
 #include <interfaces/idapro/STARSInterface.h>
 #include <interfaces/idapro/STARSInstruction.h>
+#include <interfaces/idapro/STARSOp.h>
 
diff --git a/src/base/SMPInstr.cpp b/src/base/SMPInstr.cpp
index 3403eec92332fc8b9c95697ebb888e88c2200611..4050e3d4ae71cca970227c5a688d471384e0a7f6 100644
--- a/src/base/SMPInstr.cpp
+++ b/src/base/SMPInstr.cpp
@@ -1551,9 +1551,11 @@ SMPInstr::SMPInstr(ea_t addr) : STARS_ID((uintptr_t) addr) {
 	this->OptType = 0;
 	this->address = addr;
 	this->StackPtrOffset = 0;
-	// We do not store the pointer returned by the following allocation because
-	//  we can look it up later via the STARS_ID member.
-	STARS_IDA_Instruction_t* TempPtr = new STARS_IDA_Instruction_t(this->STARS_ID);
+#ifdef STARS_IDA_INTERFACE
+	this->STARSInstPtr = new STARS_IDA_Instruction_t(this->STARS_ID);
+#else
+	this->STARSInstPtr = new STARS_IRDB_Instruction_t(this->STARS_ID);
+#endif
 #if 0
 	this->ResetGoodRTL();
 	this->ResetJumpTarget();
diff --git a/src/interfaces/idapro/Makefile.in b/src/interfaces/idapro/Makefile.in
index b658e8ffba2eab14b3a5a164d06c905a4efc3f0f..d57b178d3e4f84f19a2dc6b1d0f3d33a78ba625f 100644
--- a/src/interfaces/idapro/Makefile.in
+++ b/src/interfaces/idapro/Makefile.in
@@ -1,5 +1,5 @@
 
-OBJS=STARSFunction.o STARSInterface.o STARSIDAInstruction.o
+OBJS=STARSFunction.o STARSInterface.o STARSIDAInstruction.o STARSIDAOp.o
 CXX=@CXX@
 LD=@LD@
 EXTRA_CXXFLAGS=@EXTRA_CXXFLAGS@
diff --git a/src/interfaces/idapro/STARSIDAInstruction.cpp b/src/interfaces/idapro/STARSIDAInstruction.cpp
index 6f4f8cbca2f3a85320dd352671575e57316e09cd..8d21672995d2a08faa8e0213704ecb55897338c6 100644
--- a/src/interfaces/idapro/STARSIDAInstruction.cpp
+++ b/src/interfaces/idapro/STARSIDAInstruction.cpp
@@ -1,3 +1,4 @@
+#include <assert.h>
 
 #include "base/SMPDataFlowAnalysis.h"
 #include "base/SMPStaticAnalyzer.h"
@@ -20,7 +21,8 @@ STARS_InstructionID_t STARS_IDA_Instruction_t::GetNextInstructionID(void)
 };
 
 STARS_InstructionID_t STARS_IDA_Instruction_t::GetTargetInstructionID(void) {
-	STARS_ea_t TargetAddr = this->STARScmd.Operands[0].addr;
+	assert(NULL != this->STARScmd.Operands[0]);
+	STARS_ea_t TargetAddr = this->STARScmd.Operands[0]->GetAddr();
 	return STARS_InstructionID_t(TargetAddr);
 }
 
@@ -57,18 +59,19 @@ bool STARS_IDA_Instruction_t::STARS_GetCmd(void) {
 	this->STARSfeatures = cmd.get_canon_feature();
 
 	for (int i = 0; i < UA_MAXOP; ++i) {
-		this->STARScmd.Operands[i].specflag4 = 0; 
+		this->STARScmd.Operands[i] = new STARS_IDA_op_t(cmd.Operands[i]);
+		this->STARScmd.Operands[i]->SetSpecFlag4(0); 
 #ifdef __EA64__
 		if (STARS_ISA_Bitwidth == 64) {
 			// Copy the cmd.rex prefix into the op_t.specflag4 field for each operand
 			//  that has a SIB byte.
-			this->STARScmd.Operands[i].specflag4 = this->STARScmd.rex;
+			this->STARScmd.Operands[i]->SetSpecFlag4(this->STARScmd.rex);
 		}
 #endif
 		// See comments on STARS_VEXPR and STARS_VSIB in SMPDataFlowAnalysis.h.
 		//  These bits do not (as of IDA Pro 6.4) conflict with cmd.rex bits.
 		if ((cmd.auxpref & aux_vexpr) != 0) {
-			this->STARScmd.Operands[i].specflag4 |= STARS_VEXPR;
+			this->STARScmd.Operands[i]->SetBitInSpecFlag4(STARS_VEXPR);
 		}
 
 		switch (this->STARScmd.itype) {
@@ -80,7 +83,7 @@ bool STARS_IDA_Instruction_t::STARS_GetCmd(void) {
 			case NN_vpgatherdq:
 			case NN_vpgatherqd:
 			case NN_vpgatherqq:
-			  this->STARScmd.Operands[i].specflag4 |= STARS_VSIB;
+			  this->STARScmd.Operands[i]->SetBitInSpecFlag4(STARS_VSIB);
 			default:
 				;
 		}
diff --git a/src/interfaces/idapro/STARSIDAOp.cpp b/src/interfaces/idapro/STARSIDAOp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..438ade08da0b2fe258c6ec908bb99e8570f29245
--- /dev/null
+++ b/src/interfaces/idapro/STARSIDAOp.cpp
@@ -0,0 +1,45 @@
+#include <pro.h>
+#include <ua.hpp>
+
+#include "base/SMPDataFlowAnalysis.h"
+#include "base/SMPStaticAnalyzer.h"
+#include "interfaces/SMPDBInterface.h"
+#include "interfaces/abstract/all.h"
+#include "interfaces/idapro/all.h"
+
+
+bool STARS_IDA_op_t::operator<(const STARS_op_t &rOp) const {
+	unsigned char Type1 = this->GetType();
+	unsigned char Type2 = rOp.GetType();
+	if (Type1 != Type2)
+		return (Type1 < Type2);
+	switch (Type1) {
+		case o_void: return false;
+		case o_reg: return MDLessReg(this->GetReg(), rOp.GetReg());
+		case o_mem: return (this->GetAddr() < rOp.GetAddr());
+		case o_phrase: if (this->HasSIBByte() && rOp.HasSIBByte()) return ((this->GetSIB() < rOp.GetSIB()) || ((this->GetSIB() == rOp.GetSIB()) && (this->GetSpecFlag4() < rOp.GetSpecFlag4())));
+						else if (rOp.HasSIBByte()) return true;  // no SIB < has SIB
+						else if (this->HasSIBByte()) return false; // no SIB < has SIB
+						else return MDLessReg(this->GetReg(), rOp.GetReg()); // no SIB bytes
+		case o_displ: if (this->HasSIBByte() && rOp.HasSIBByte())
+						  return ((this->GetSIB() < rOp.GetSIB()) 
+							|| ((this->GetSIB() == rOp.GetSIB()) 
+								&& ((this->GetAddr() < rOp.GetAddr()) || ((this->GetAddr() == rOp.GetAddr()) && (this->GetSpecFlag4() < rOp.GetSpecFlag4())))));
+						else if (rOp.HasSIBByte()) return true;  // no SIB < has SIB
+						else if (this->HasSIBByte()) return false; // no SIB < has SIB
+						else return ((this->GetAddr() < rOp.GetAddr())
+							|| ((this->GetAddr() == rOp.GetAddr()) && MDLessReg(this->GetReg(), rOp.GetReg()))); // no SIB bytes
+		case o_imm: return (this->GetImmedValue() < rOp.GetImmedValue());
+		case o_far:  // fall through to o_near case
+		case o_near: return (this->GetAddr() < rOp.GetAddr());
+		case o_trreg:  // fall through
+		case o_dbreg:  // fall through
+		case o_crreg:  // fall through
+		case o_fpreg:  // fall through
+		case o_mmxreg: // fall through
+		case o_xmmreg: return (this->GetReg() < rOp.GetReg()); // no subword regs to deal with, don't need MDLessReg()
+
+		default: msg("ERROR: Unknown operand type in LessOp.\n"); return false;
+	}; // end switch (Opnd1.type)
+}; // end of operator less-than
+