diff --git a/SConscript b/SConscript
index 34ced56d3f98c6f75632d0efb441f0fb03a4e6a9..65f9d965e8023c3dca4117234a3a4b0015f43107 100644
--- a/SConscript
+++ b/SConscript
@@ -25,9 +25,6 @@ if not os.path.isfile("manifest.txt.config"):
 libirdb=      SConscript("irdb-libs/SConscript") 
 libsmpsa=     SConscript("SMPStaticAnalyzer/SConscript") 
 
-# specify some explicit dependencies to make sure these build in order
-Depends(libsmpsa,libirdb)
-
 # now finish building irdb-libs once stars is setup
 libirdbdeep=SConscript("irdb-libs/SConscript.deep")
 Depends(libirdbdeep,libsmpsa)
diff --git a/SMPStaticAnalyzer b/SMPStaticAnalyzer
index 99ca54f01ec147cb30aaeec1b03f0158b4c5e370..8c405f65d2a77cb76d9239e8829594a71ffeb8ac 160000
--- a/SMPStaticAnalyzer
+++ b/SMPStaticAnalyzer
@@ -1 +1 @@
-Subproject commit 99ca54f01ec147cb30aaeec1b03f0158b4c5e370
+Subproject commit 8c405f65d2a77cb76d9239e8829594a71ffeb8ac
diff --git a/irdb-libs/libEXEIO/include/exeio.h b/irdb-libs/libEXEIO/include/exeio.h
index 1bb3a06d56c6f2f7ddf745f014f2c5c8ffb02fb2..f9057d3dc64f1a8002dcfaaffcd8f9fd0e73c751 100644
--- a/irdb-libs/libEXEIO/include/exeio.h
+++ b/irdb-libs/libEXEIO/include/exeio.h
@@ -13,7 +13,7 @@ namespace EXEIO
 	class exeio_t; // forward decl
 
 	typedef enum { ELF64, ELF32, PE32, PE64 } execlass_t;
-	typedef enum {  mtX86_64, mtI386, mtArm32, mtAarch64 } MachineType_t; 
+	typedef enum {  mtX86_64, mtI386, mtArm32, mtAarch64, mtMips32, mtMips64 } MachineType_t; 
 
 	typedef uintptr_t virtual_offset_t;
 
diff --git a/irdb-libs/libEXEIO/src/exeio_elf.h b/irdb-libs/libEXEIO/src/exeio_elf.h
index cd2230b757b674a77aff6ab723d9ccdd1327a76d..fcd07c6b5d786cce3e9ab224f1373952f4686f2f 100644
--- a/irdb-libs/libEXEIO/src/exeio_elf.h
+++ b/irdb-libs/libEXEIO/src/exeio_elf.h
@@ -98,6 +98,7 @@ namespace EXEIO
 				assert(e);
 				switch(e->get_machine())
 				{
+					case EM_MIPS	: return mtMips32;
 					case EM_ARM	: return mtArm32;
 					case EM_AARCH64	: return mtAarch64;
 					case EM_386     : return mtI386;
diff --git a/irdb-libs/libIRDB-core/include/decode_csmips.hpp b/irdb-libs/libIRDB-core/include/decode_csmips.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..cfad0e36e22b77a628edb1e879524ad609c7a477
--- /dev/null
+++ b/irdb-libs/libIRDB-core/include/decode_csmips.hpp
@@ -0,0 +1,143 @@
+
+namespace libIRDB
+{
+
+	using namespace libIRDB;
+	using namespace std;
+
+	class DecodedOperandCapstoneMIPS_t;
+	class DecodedInstructionCapstoneMIPS_t : virtual public IRDB_SDK::DecodedInstruction_t
+	{
+		public:
+			DecodedInstructionCapstoneMIPS_t& operator=(const DecodedInstructionCapstoneMIPS_t& copy)
+			{
+				my_insn = copy.my_insn;
+				return *this;
+			}
+
+			virtual ~DecodedInstructionCapstoneMIPS_t() { } 
+
+		protected:
+			DecodedInstructionCapstoneMIPS_t()
+			{
+				if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL);
+			}
+
+			shared_ptr<void> my_insn;
+
+			class CapstoneHandle_t
+			{
+				public:
+					CapstoneHandle_t(FileIR_t* firp=NULL);
+					inline unsigned long getHandle() { return handle; }
+
+				private:
+					// csh handle;   # this is the real type, but it's an alias and I don't want to export capstone values.
+					unsigned long handle;
+			};
+			static CapstoneHandle_t *cs_handle;
+
+			friend class IRDB_SDK::DecodedInstruction_t;
+			friend class DecodedOperandCapstoneMIPS_t;
+	};
+
+	class DecodedOperandCapstoneMIPS32_t;
+	class DecodedInstructionCapstoneMIPS32_t : public DecodedInstructionCapstoneMIPS_t
+	{
+		public:
+			DecodedInstructionCapstoneMIPS32_t()=delete;
+			DecodedInstructionCapstoneMIPS32_t& operator=(const DecodedInstructionCapstoneMIPS32_t& copy);
+
+			virtual ~DecodedInstructionCapstoneMIPS32_t();
+
+			virtual string getDisassembly() const override;
+			virtual bool valid() const override;
+			virtual uint32_t length() const override;
+			virtual bool isBranch() const override;
+			virtual bool isCall() const override;
+			virtual bool isUnconditionalBranch() const override; 
+			virtual bool isConditionalBranch() const override; 
+			virtual bool isReturn() const override; 
+			virtual string getMnemonic() const override; 
+			virtual int64_t getImmediate() const override; 
+			virtual virtual_offset_t getAddress() const override; 
+			virtual bool setsStackPointer() const override; 
+			virtual uint32_t getPrefixCount() const override; 
+			virtual bool hasRelevantRepPrefix() const override; 
+			virtual bool hasRelevantRepnePrefix() const override; 
+			virtual bool hasRelevantOperandSizePrefix() const override; 
+			virtual bool hasRexWPrefix() const override; 
+			virtual bool hasImplicitlyModifiedRegs() const override;
+			virtual IRDB_SDK::VirtualOffset_t getMemoryDisplacementOffset(const DecodedOperand_t* t, const IRDB_SDK::Instruction_t* insn) const override;
+
+			// 0-based.  first operand is numbered 0.
+			virtual bool hasOperand(const int op_num) const override;
+			virtual std::shared_ptr<DecodedOperand_t> getOperand(const int op_num) const override;
+			virtual DecodedOperandVector_t getOperands() const override;
+
+		protected:
+
+			void Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len);
+
+		private:
+			DecodedInstructionCapstoneMIPS32_t(const shared_ptr<void> &my_insn) ;
+			DecodedInstructionCapstoneMIPS32_t(const Instruction_t* my_insn) ;
+			DecodedInstructionCapstoneMIPS32_t(const virtual_offset_t sa, const void *data, uint32_t max_len  ) ;
+			DecodedInstructionCapstoneMIPS32_t(const virtual_offset_t sa, const void *data, const void* endptr) ;
+			DecodedInstructionCapstoneMIPS32_t(const DecodedInstructionCapstoneMIPS32_t& copy) ;
+
+			friend class IRDB_SDK::DecodedInstruction_t;
+			friend class DecodedOperandCapstoneMIPS32_t;
+	};
+
+	class DecodedOperandCapstoneMIPS64_t;
+	class DecodedInstructionCapstoneMIPS64_t : public DecodedInstructionCapstoneMIPS_t
+	{
+		public:
+			DecodedInstructionCapstoneMIPS64_t()=delete;
+			DecodedInstructionCapstoneMIPS64_t& operator=(const DecodedInstructionCapstoneMIPS64_t& copy);
+
+			virtual ~DecodedInstructionCapstoneMIPS64_t();
+
+			virtual string getDisassembly() const override;
+			virtual bool valid() const override;
+			virtual uint32_t length() const override;
+			virtual bool isBranch() const override;
+			virtual bool isCall() const override;
+			virtual bool isUnconditionalBranch() const override; 
+			virtual bool isConditionalBranch() const override; 
+			virtual bool isReturn() const override; 
+			virtual string getMnemonic() const override; 
+			virtual int64_t getImmediate() const override; 
+			virtual virtual_offset_t getAddress() const override; 
+			virtual bool setsStackPointer() const override; 
+			virtual uint32_t getPrefixCount() const override; 
+			virtual bool hasRelevantRepPrefix() const override; 
+			virtual bool hasRelevantRepnePrefix() const override; 
+			virtual bool hasRelevantOperandSizePrefix() const override; 
+			virtual bool hasRexWPrefix() const override; 
+			virtual bool hasImplicitlyModifiedRegs() const override;
+			virtual IRDB_SDK::VirtualOffset_t getMemoryDisplacementOffset(const DecodedOperand_t* t, const IRDB_SDK::Instruction_t* insn) const override;
+
+			// 0-based.  first operand is numbered 0.
+			virtual bool hasOperand(const int op_num) const override;
+			virtual std::shared_ptr<DecodedOperand_t> getOperand(const int op_num) const override;
+			virtual DecodedOperandVector_t getOperands() const override;
+
+		protected:
+
+			void Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len);
+
+		private:
+			DecodedInstructionCapstoneMIPS64_t(const shared_ptr<void> &my_insn) ;
+			DecodedInstructionCapstoneMIPS64_t(const Instruction_t*) ;
+			DecodedInstructionCapstoneMIPS64_t(const virtual_offset_t sa, const void *data, uint32_t max_len  ) ;
+			DecodedInstructionCapstoneMIPS64_t(const virtual_offset_t sa, const void *data, const void* endptr) ;
+			DecodedInstructionCapstoneMIPS64_t(const DecodedInstructionCapstoneMIPS64_t& copy) ;
+
+			friend class IRDB_SDK::DecodedInstruction_t;
+			friend class DecodedOperandCapstoneMIPS64_t;
+	};
+
+}
+
diff --git a/irdb-libs/libIRDB-core/include/operand_csmips.hpp b/irdb-libs/libIRDB-core/include/operand_csmips.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6df2bf2cf6d28838f48f3f91742418d9435d3141
--- /dev/null
+++ b/irdb-libs/libIRDB-core/include/operand_csmips.hpp
@@ -0,0 +1,107 @@
+
+namespace libIRDB
+{
+
+	using namespace std;
+	using namespace libIRDB;
+
+	class DecodedOperandCapstoneMIPS_t : virtual public IRDB_SDK::DecodedOperand_t
+	{
+		public:
+			DecodedOperandCapstoneMIPS_t() =delete;
+			virtual ~DecodedOperandCapstoneMIPS_t() { }
+
+		protected:
+
+			DecodedOperandCapstoneMIPS_t( const shared_ptr<void> &p_my_insn, uint8_t p_op_num)
+				: my_insn(p_my_insn), op_num(p_op_num)
+			{
+			}
+
+			shared_ptr<void> my_insn;
+			uint8_t op_num;
+
+			friend class DecodedInstructionCapstoneMIPS_t;
+	};
+
+	class DecodedOperandCapstoneMIPS32_t : public DecodedOperandCapstoneMIPS_t
+	{
+		public:
+			DecodedOperandCapstoneMIPS32_t() =delete;
+			virtual ~DecodedOperandCapstoneMIPS32_t();
+			virtual bool isConstant() const override;
+			virtual uint64_t getConstant() const override;
+			virtual string getString() const override;
+			virtual bool isRegister() const override;
+			virtual bool isGeneralPurposeRegister() const override;
+			virtual bool isMmxRegister() const override;
+			virtual bool isFpuRegister() const override;
+			virtual bool isSseRegister() const override;
+			virtual bool isAvxRegister() const override;
+			virtual bool isZmmRegister() const override;
+			virtual bool isSpecialRegister() const override;
+			virtual bool isSegmentRegister() const override;
+			virtual uint32_t getRegNumber() const override;
+			virtual bool isMemory() const override;
+			virtual bool hasSegmentRegister() const override;
+			virtual uint32_t getSegmentRegister() const override;
+			virtual bool hasBaseRegister() const override;
+			virtual bool hasIndexRegister() const override;
+			virtual uint32_t getBaseRegister() const override;
+			virtual uint32_t getIndexRegister() const override;
+			virtual bool hasMemoryDisplacement() const override;
+			virtual virtual_offset_t getMemoryDisplacement() const override;
+			virtual bool isPcrel() const override;
+			virtual uint32_t getScaleValue() const override;
+			virtual uint32_t getMemoryDisplacementEncodingSize() const override;
+			virtual uint32_t getArgumentSizeInBytes() const override;
+			virtual uint32_t getArgumentSizeInBits() const override;
+			virtual bool isRead() const override; 
+			virtual bool isWritten() const override; 
+		private:
+			DecodedOperandCapstoneMIPS32_t( const shared_ptr<void> &p_my_insn, uint8_t p_op_num);
+			friend class DecodedInstructionCapstoneMIPS32_t;
+
+
+	};
+
+	class DecodedOperandCapstoneMIPS64_t : public DecodedOperandCapstoneMIPS_t
+	{
+		public:
+			DecodedOperandCapstoneMIPS64_t() =delete;
+			virtual ~DecodedOperandCapstoneMIPS64_t();
+			virtual bool isConstant() const override;
+			virtual uint64_t getConstant() const override;
+			virtual string getString() const override;
+			virtual bool isRegister() const override;
+			virtual bool isGeneralPurposeRegister() const override;
+			virtual bool isMmxRegister() const override;
+			virtual bool isFpuRegister() const override;
+			virtual bool isSseRegister() const override;
+			virtual bool isAvxRegister() const override;
+			virtual bool isZmmRegister() const override;
+			virtual bool isSpecialRegister() const override;
+			virtual bool isSegmentRegister() const override;
+			virtual uint32_t getRegNumber() const override;
+			virtual bool isMemory() const override;
+			virtual bool hasSegmentRegister() const override;
+			virtual uint32_t getSegmentRegister() const override;
+			virtual bool hasBaseRegister() const override;
+			virtual bool hasIndexRegister() const override;
+			virtual uint32_t getBaseRegister() const override;
+			virtual uint32_t getIndexRegister() const override;
+			virtual bool hasMemoryDisplacement() const override;
+			virtual virtual_offset_t getMemoryDisplacement() const override;
+			virtual bool isPcrel() const override;
+			virtual uint32_t getScaleValue() const override;
+			virtual uint32_t getMemoryDisplacementEncodingSize() const override;
+			virtual uint32_t getArgumentSizeInBytes() const override;
+			virtual uint32_t getArgumentSizeInBits() const override;
+			virtual bool isRead() const override; 
+			virtual bool isWritten() const override; 
+
+		private:
+			DecodedOperandCapstoneMIPS64_t( const shared_ptr<void> &p_my_insn, uint8_t p_op_num);
+			friend class DecodedInstructionCapstoneMIPS64_t;
+	};
+}
diff --git a/irdb-libs/libIRDB-core/src/SConscript b/irdb-libs/libIRDB-core/src/SConscript
index 8e67fe4f1c16b57fd27ecbb2c931535b5b98d458..2ebee5283f22a3f2345194b85ed2bf0e9bcddbbd 100644
--- a/irdb-libs/libIRDB-core/src/SConscript
+++ b/irdb-libs/libIRDB-core/src/SConscript
@@ -24,9 +24,11 @@ files=  '''
 	eh.cpp
 	reloc.cpp
 	decode_csx86.cpp
-	operand_csx86.cpp
+	decode_csmips32.cpp
 	decode_csarm32.cpp
 	decode_csarm64.cpp
+	operand_csx86.cpp
+	operand_csmips32.cpp
 	operand_csarm32.cpp
 	operand_csarm64.cpp
 	IRDB_Objects.cpp
diff --git a/irdb-libs/libIRDB-core/src/decode_base.cpp b/irdb-libs/libIRDB-core/src/decode_base.cpp
index 3790cc0e12245c9111455a5931127507bc593422..23e83fd440c3555b166af72b1afd8e2e7c2b32d3 100644
--- a/irdb-libs/libIRDB-core/src/decode_base.cpp
+++ b/irdb-libs/libIRDB-core/src/decode_base.cpp
@@ -6,6 +6,8 @@
 #include <operand_csx86.hpp>
 #include <decode_csarm.hpp>
 #include <operand_csarm.hpp>
+#include <decode_csmips.hpp>
+#include <operand_csmips.hpp>
 #include <exception>
 
 using namespace std;
@@ -16,30 +18,36 @@ unique_ptr<IRDB_SDK::DecodedInstruction_t> IRDB_SDK::DecodedInstruction_t::facto
 {
 	const auto i=dynamic_cast<const libIRDB::Instruction_t*>(p_i);
 	assert(i);
-	auto op = IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtArm32   ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM32_t(i) : 
-	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtAarch64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM64_t(i) : 
-	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtX86_64  ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t  (i) : 
-	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtI386    ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t  (i) : 
+	auto op = 
+	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtMips32  ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneMIPS32_t(i) : 
+	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtArm32   ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM32_t (i) : 
+	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtAarch64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM64_t (i) : 
+	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtX86_64  ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t   (i) : 
+	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtI386    ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t   (i) : 
 	          throw invalid_argument("Unknown machine type");
 	return unique_ptr<DecodedInstruction_t>(op);
 }
 
 unique_ptr<IRDB_SDK::DecodedInstruction_t> IRDB_SDK::DecodedInstruction_t::factory(const IRDB_SDK::VirtualOffset_t start_addr, const void *data, uint32_t max_len)
 {
-	auto op = IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtArm32   ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM32_t(start_addr,data,max_len) : 
-	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtAarch64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM64_t(start_addr,data,max_len) : 
-	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtX86_64  ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t  (start_addr,data,max_len) : 
-	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtI386    ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t  (start_addr,data,max_len) : 
+	auto op = 
+	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtMips32  ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneMIPS32_t(start_addr,data,max_len) : 
+	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtArm32   ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM32_t (start_addr,data,max_len) : 
+	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtAarch64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM64_t (start_addr,data,max_len) : 
+	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtX86_64  ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t   (start_addr,data,max_len) : 
+	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtI386    ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t   (start_addr,data,max_len) : 
 	          throw invalid_argument("Unknown machine type");
 	return unique_ptr<DecodedInstruction_t>(op);
 }
 
 unique_ptr<IRDB_SDK::DecodedInstruction_t> IRDB_SDK::DecodedInstruction_t::factory(const IRDB_SDK::VirtualOffset_t start_addr, const void *data, const void* endptr)
 {
-	auto op = IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtArm32   ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM32_t(start_addr,data,endptr) : 
-	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtAarch64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM64_t(start_addr,data,endptr) : 
-	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtX86_64  ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t  (start_addr,data,endptr) : 
-	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtI386    ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t  (start_addr,data,endptr) : 
+	auto op = 
+	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtMips32  ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneMIPS32_t(start_addr,data,endptr) : 
+	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtArm32   ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM32_t (start_addr,data,endptr) : 
+	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtAarch64 ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneARM64_t (start_addr,data,endptr) : 
+	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtX86_64  ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t   (start_addr,data,endptr) : 
+	          IRDB_SDK::FileIR_t::getArchitecture()->getMachineType()==IRDB_SDK::admtI386    ? (IRDB_SDK::DecodedInstruction_t*)new DecodedInstructionCapstoneX86_t   (start_addr,data,endptr) : 
 	          throw invalid_argument("Unknown machine type");
 	return unique_ptr<DecodedInstruction_t>(op);
 }
diff --git a/irdb-libs/libIRDB-core/src/decode_csmips32.cpp b/irdb-libs/libIRDB-core/src/decode_csmips32.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..45a1fe84928e7d7d4942a26abfcd54058eaadb79
--- /dev/null
+++ b/irdb-libs/libIRDB-core/src/decode_csmips32.cpp
@@ -0,0 +1,304 @@
+
+#include <libIRDB-core.hpp>
+#include <decode_base.hpp>
+#include <decode_csmips.hpp>
+#include <operand_base.hpp>
+#include <operand_csmips.hpp>
+
+
+#include <capstone.h>
+#include <mips.h>
+#include <string>
+#include <functional>
+#include <set>
+#include <algorithm>
+#include <stdexcept>
+
+using namespace libIRDB;
+using namespace std;
+
+#define ALLOF(a) begin(a),end(a)
+
+static bool isPartOfGroup(const cs_insn* the_insn, const mips_insn_group the_grp) 
+{
+	const auto grp_it=find(ALLOF(the_insn->detail->groups), the_grp);
+	return grp_it!=end(the_insn->detail->groups);
+}
+
+template<class type>
+static inline type mips32InsnToImmedHelper(cs_insn* the_insn, csh handle)
+{
+        const auto count = cs_op_count(handle, the_insn, ARM_OP_IMM);
+        const auto mips = &(the_insn->detail->mips);
+
+        if (count==0)
+                return 0;        /* no immediate is the same as an immediate of 0, i guess? */
+        else if (count==1)
+        {
+                const auto index = cs_op_index(handle, the_insn, MIPS_OP_IMM, 1);
+                return mips->operands[index].imm;
+        }
+        else
+                throw std::logic_error(string("Called ")+__FUNCTION__+" with number of immedaites not equal 1");
+}
+
+
+// shared code 
+// constructors, destructors, operators.
+
+void DecodedInstructionCapstoneMIPS32_t::Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len)
+{
+	using namespace std::placeholders;
+	auto insn=cs_malloc(cs_handle->getHandle());
+	auto address=(uint64_t)start_addr;
+	auto size=(size_t)max_len;
+	const uint8_t* code=(uint8_t*)data;
+	const auto ok = cs_disasm_iter(cs_handle->getHandle(), &code, &size, &address, insn);
+	if(!ok)
+		insn->size=0;
+
+	const auto cs_freer=[](cs_insn * insn) -> void 
+		{  
+			cs_free(insn,1); 
+		} ; 
+	my_insn.reset(insn,cs_freer);
+}
+
+DecodedInstructionCapstoneMIPS32_t::DecodedInstructionCapstoneMIPS32_t(const Instruction_t* i)
+{
+	if(!i) throw std::invalid_argument("No instruction given to DecodedInstruction_t(Instruction_t*)");
+
+        const auto length=i->getDataBits().size();
+	const auto &databits=i->getDataBits();
+	const auto data=databits.data();
+	const auto address=i->getAddress()->getVirtualOffset();
+        Disassemble(address,data,length);
+
+	if(!valid()) throw std::invalid_argument("The Instruction_t::getDataBits field is not a valid instruction.");
+}
+
+DecodedInstructionCapstoneMIPS32_t::DecodedInstructionCapstoneMIPS32_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len)
+{
+        Disassemble(start_addr, data, max_len);
+}
+
+DecodedInstructionCapstoneMIPS32_t::DecodedInstructionCapstoneMIPS32_t(const virtual_offset_t start_addr, const void *data, const void* endptr)
+{
+        const auto length=(char*)endptr-(char*)data;
+        Disassemble(start_addr,data,length);
+}
+
+DecodedInstructionCapstoneMIPS32_t::DecodedInstructionCapstoneMIPS32_t(const DecodedInstructionCapstoneMIPS32_t& copy)
+{
+	*this=copy;
+}
+
+DecodedInstructionCapstoneMIPS32_t::DecodedInstructionCapstoneMIPS32_t(const shared_ptr<void> &p_my_insn)
+{
+	my_insn = p_my_insn;
+}
+
+DecodedInstructionCapstoneMIPS32_t::~DecodedInstructionCapstoneMIPS32_t()
+{
+	// no need to cs_free(my_insn) because shared pointer will do that for us!
+}
+
+DecodedInstructionCapstoneMIPS32_t& DecodedInstructionCapstoneMIPS32_t::operator=(const DecodedInstructionCapstoneMIPS32_t& copy)
+{
+	my_insn=copy.my_insn;
+	return *this;
+}
+
+// public methods
+
+string DecodedInstructionCapstoneMIPS32_t::getDisassembly() const
+{
+
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	auto full_str=getMnemonic()+" "+the_insn->op_str;
+
+	return full_str;
+}
+
+bool DecodedInstructionCapstoneMIPS32_t::valid() const
+{
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	return the_insn->size!=0;
+}
+
+uint32_t DecodedInstructionCapstoneMIPS32_t::length() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	return the_insn->size;
+}
+
+bool DecodedInstructionCapstoneMIPS32_t::isBranch() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	return isCall() || isReturn() || isPartOfGroup(the_insn,MIPS_GRP_JUMP);
+}
+
+bool DecodedInstructionCapstoneMIPS32_t::isCall() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	assert(the_insn);
+	return isPartOfGroup(the_insn, MIPS_GRP_CALL);
+
+}
+
+bool DecodedInstructionCapstoneMIPS32_t::isUnconditionalBranch() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+ 	return isPartOfGroup(the_insn, MIPS_GRP_JUMP) && getMnemonic()=="b";
+}
+
+bool DecodedInstructionCapstoneMIPS32_t::isConditionalBranch() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	assert(the_insn);
+ 	return isPartOfGroup(the_insn, MIPS_GRP_JUMP)  && !isUnconditionalBranch();
+}
+
+bool DecodedInstructionCapstoneMIPS32_t::isReturn() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn  = static_cast<cs_insn*>(my_insn.get());
+	assert(the_insn);
+	return isPartOfGroup(the_insn, MIPS_GRP_RET);
+}
+
+bool DecodedInstructionCapstoneMIPS32_t::hasOperand(const int op_num) const
+{
+	if(op_num<0) throw std::logic_error(string("Called ")+ __FUNCTION__+" with opnum="+to_string(op_num));
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	const auto &mips = (the_insn->detail->mips);
+	return 0 <= op_num  && op_num < mips.op_count;
+}
+
+// 0-based.  first operand is numbered 0.
+shared_ptr<DecodedOperand_t> DecodedInstructionCapstoneMIPS32_t::getOperand(const int op_num) const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	if(!hasOperand(op_num)) throw std::logic_error(string("Called ")+__FUNCTION__+" on without hasOperand()==true");
+
+	return shared_ptr<DecodedOperand_t>(new DecodedOperandCapstoneMIPS32_t(my_insn,(uint8_t)op_num));
+	
+}
+
+DecodedOperandVector_t DecodedInstructionCapstoneMIPS32_t::getOperands() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	const auto &mips = (the_insn->detail->mips);
+	const auto opcount=mips.op_count;
+
+	auto ret_val=DecodedOperandVector_t();
+	
+	for(auto i=0;i<opcount;i++)
+		ret_val.push_back(getOperand(i));
+
+	return ret_val;
+}
+
+string DecodedInstructionCapstoneMIPS32_t::getMnemonic() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+
+	// return the new string.
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	return the_insn->mnemonic;
+
+	
+}
+
+
+int64_t DecodedInstructionCapstoneMIPS32_t::getImmediate() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+
+	// direct calls and jumps have a "immediate" which is really an address"  those are returned by getAddress
+	if(isCall() || isPartOfGroup(the_insn, MIPS_GRP_JUMP) )
+		return 0;
+
+	return mips32InsnToImmedHelper<int64_t>(the_insn, cs_handle->getHandle());
+}
+
+
+virtual_offset_t DecodedInstructionCapstoneMIPS32_t::getAddress() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	if(isCall() || isPartOfGroup(the_insn, MIPS_GRP_JUMP) )
+	{
+		const auto mnemonic=getMnemonic();
+		if( mnemonic=="tbnz" || mnemonic=="tbz")
+			return getOperand(2)->getConstant();
+		return mips32InsnToImmedHelper<int64_t>(the_insn, cs_handle->getHandle());
+	}
+	return 0;
+
+}
+
+
+bool DecodedInstructionCapstoneMIPS32_t::setsStackPointer() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+
+	if(!hasOperand(0)) return false;
+
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	const auto &mips = (the_insn->detail->mips);
+	return (mips.operands[0].type==MIPS_OP_REG && mips.operands[0].reg==MIPS_REG_SP);
+}
+
+uint32_t DecodedInstructionCapstoneMIPS32_t::getPrefixCount() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	return 0;
+}
+
+IRDB_SDK::VirtualOffset_t DecodedInstructionCapstoneMIPS32_t::getMemoryDisplacementOffset(const IRDB_SDK::DecodedOperand_t* t, const IRDB_SDK::Instruction_t* insn) const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	assert(0);
+}
+
+bool DecodedInstructionCapstoneMIPS32_t::hasRelevantRepPrefix() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	return false;
+}
+
+bool DecodedInstructionCapstoneMIPS32_t::hasRelevantRepnePrefix() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	return false;
+}
+
+bool DecodedInstructionCapstoneMIPS32_t::hasRelevantOperandSizePrefix() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	return false;
+}
+
+bool DecodedInstructionCapstoneMIPS32_t::hasRexWPrefix() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	return false;
+}
+
+bool DecodedInstructionCapstoneMIPS32_t::hasImplicitlyModifiedRegs() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	return false;
+}
+
+DecodedInstructionCapstoneMIPS_t::CapstoneHandle_t* DecodedInstructionCapstoneMIPS_t::cs_handle=nullptr;
diff --git a/irdb-libs/libIRDB-core/src/decode_csmips64.cpp b/irdb-libs/libIRDB-core/src/decode_csmips64.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fcf7282e0a6f98142ca799f4e56c1abbfb4caec0
--- /dev/null
+++ b/irdb-libs/libIRDB-core/src/decode_csmips64.cpp
@@ -0,0 +1,355 @@
+
+#include <libIRDB-core.hpp>
+#include <decode_base.hpp>
+#include <decode_csmips.hpp>
+#include <operand_base.hpp>
+#include <operand_csmips.hpp>
+
+
+#include <capstone.h>
+#include <mips64.h>
+#include <string>
+#include <functional>
+#include <set>
+#include <algorithm>
+#include <stdexcept>
+
+using namespace libIRDB;
+using namespace std;
+
+#define ALLOF(a) begin(a),end(a)
+static const auto MIPS64_REG_PC=(mips64_reg)(MIPS64_REG_ENDING+1);
+
+
+DecodedInstructionCapstoneMIPS_t::CapstoneHandle_t* DecodedInstructionCapstoneMIPS_t::cs_handle=nullptr;
+
+DecodedInstructionCapstoneMIPS_t::CapstoneHandle_t::CapstoneHandle_t(FileIR_t* firp)
+{
+	static_assert(sizeof(csh)==sizeof(handle), "Capstone handle size is unexpected.  Has CS changed?");
+
+	const auto mode = CS_MODE_LITTLE_ENDIAN;
+	const auto arch = 
+		firp->getArchitectureBitWidth() == 64 ? CS_ARCH_MIPS64 : 
+		firp->getArchitectureBitWidth() == 32 ? CS_ARCH_MIPS   : 
+		throw invalid_argument("Unknown bit width: "+to_string(firp->getArchitectureBitWidth()));
+	const auto err  = cs_open(arch, mode,  (csh*)&handle);
+	if (err)
+	{
+		const auto s=string("Failed on cs_open() with error returned: ")+to_string(err)+"\n";
+		throw std::runtime_error(s);
+	}
+	cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
+	cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL);
+}
+
+static bool isPartOfGroup(const cs_insn* the_insn, const mips64_insn_group the_grp) 
+{
+	const auto grp_it=find(ALLOF(the_insn->detail->groups), the_grp);
+	return grp_it!=end(the_insn->detail->groups);
+}
+
+static bool isArm64Jmp(cs_insn* the_insn) 
+{
+	return isPartOfGroup(the_insn,MIPS64_GRP_JUMP);
+}
+
+template<class type>
+static inline type mips64InsnToImmedHelper(cs_insn* the_insn, csh handle)
+{
+        const auto count = cs_op_count(handle, the_insn, MIPS64_OP_IMM);
+	const auto mips = &(the_insn->detail->mips64);
+
+        if (count==0) 
+		return 0;	 /* no immediate is the same as an immediate of 0, i guess? */
+        else if (count==1) 
+	{
+		const auto index = cs_op_index(handle, the_insn, MIPS64_OP_IMM, 1);
+		return mips->operands[index].imm;
+	}
+	else
+		throw std::logic_error(string("Called ")+__FUNCTION__+" with number of immedaites not equal 1");
+}
+
+
+// shared code 
+// constructors, destructors, operators.
+
+void DecodedInstructionCapstoneMIPS64_t::Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len)
+{
+	using namespace std::placeholders;
+	auto insn=cs_malloc(cs_handle->getHandle());
+	auto address=(uint64_t)start_addr;
+	auto size=(size_t)max_len;
+	const uint8_t* code=(uint8_t*)data;
+	const auto ok = cs_disasm_iter(cs_handle->getHandle(), &code, &size, &address, insn);
+	if(!ok)
+		insn->size=0;
+
+        auto &op0 = (insn->detail->mips64.operands[0]); // might change these.
+        auto &op1 = (insn->detail->mips64.operands[1]);
+
+	const auto mnemonic=string(insn->mnemonic);
+	const auto is_ldr_type = mnemonic=="ldr"  || mnemonic=="ldrsw" ;
+	if(is_ldr_type && op1.type==MIPS64_OP_IMM)
+	{
+		// no, this is a pcrel load.
+		const auto imm=op1.imm;
+		op1.type=MIPS64_OP_MEM;
+		op1.mem.base=MIPS64_REG_PC;
+		op1.mem.index=MIPS64_REG_INVALID;
+		op1.mem.disp=imm;
+	}
+	if(mnemonic=="prfm" && op0.type==MIPS64_OP_IMM)
+	{
+		// no, this is a pcrel load.
+		const auto imm=op0.imm;
+		op0.type=MIPS64_OP_MEM;
+		op0.mem.base=MIPS64_REG_PC;
+		op0.mem.index=MIPS64_REG_INVALID;
+		op0.mem.disp=imm;
+	}
+
+
+	const auto cs_freer=[](cs_insn * insn) -> void 
+		{  
+			cs_free(insn,1); 
+		} ; 
+	my_insn.reset(insn,cs_freer);
+}
+
+DecodedInstructionCapstoneMIPS64_t::DecodedInstructionCapstoneMIPS64_t(const Instruction_t* i)
+{
+	if(!i) throw std::invalid_argument("No instruction given to DecodedInstruction_t(Instruction_t*)");
+
+        const auto length=i->getDataBits().size();
+	const auto &databits=i->getDataBits();
+	const auto data=databits.data();
+	const auto address=i->getAddress()->getVirtualOffset();
+        Disassemble(address,data,length);
+
+	if(!valid()) throw std::invalid_argument("The Instruction_t::getDataBits field is not a valid instruction.");
+}
+
+DecodedInstructionCapstoneMIPS64_t::DecodedInstructionCapstoneMIPS64_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len)
+{
+        Disassemble(start_addr, data, max_len);
+}
+
+DecodedInstructionCapstoneMIPS64_t::DecodedInstructionCapstoneMIPS64_t(const virtual_offset_t start_addr, const void *data, const void* endptr)
+{
+        const auto length=(char*)endptr-(char*)data;
+        Disassemble(start_addr,data,length);
+}
+
+DecodedInstructionCapstoneMIPS64_t::DecodedInstructionCapstoneMIPS64_t(const DecodedInstructionCapstoneMIPS64_t& copy)
+{
+	*this=copy;
+}
+
+DecodedInstructionCapstoneMIPS64_t::DecodedInstructionCapstoneMIPS64_t(const shared_ptr<void> &p_my_insn)
+{
+	my_insn = p_my_insn;
+}
+
+DecodedInstructionCapstoneMIPS64_t::~DecodedInstructionCapstoneMIPS64_t()
+{
+	// no need to cs_free(my_insn) because shared pointer will do that for us!
+}
+
+DecodedInstructionCapstoneMIPS64_t& DecodedInstructionCapstoneMIPS64_t::operator=(const DecodedInstructionCapstoneMIPS64_t& copy)
+{
+	my_insn=copy.my_insn;
+	return *this;
+}
+
+// public methods
+
+string DecodedInstructionCapstoneMIPS64_t::getDisassembly() const
+{
+
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	auto full_str=getMnemonic()+" "+the_insn->op_str;
+
+	return full_str;
+}
+
+bool DecodedInstructionCapstoneMIPS64_t::valid() const
+{
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	return the_insn->size!=0;
+}
+
+uint32_t DecodedInstructionCapstoneMIPS64_t::length() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	return the_insn->size;
+}
+
+bool DecodedInstructionCapstoneMIPS64_t::isBranch() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	return isCall() || isReturn() || isArm64Jmp(the_insn);
+}
+
+bool DecodedInstructionCapstoneMIPS64_t::isCall() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+
+	const auto mnemonic=getMnemonic();
+	return mnemonic=="bl" || mnemonic=="blr";
+}
+
+bool DecodedInstructionCapstoneMIPS64_t::isUnconditionalBranch() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+
+	return isArm64Jmp(the_insn) && 
+		(getMnemonic()=="b" || getMnemonic()=="br");
+}
+
+bool DecodedInstructionCapstoneMIPS64_t::isConditionalBranch() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	return isArm64Jmp(the_insn) && !isUnconditionalBranch();
+}
+
+bool DecodedInstructionCapstoneMIPS64_t::isReturn() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	return isPartOfGroup(the_insn,MIPS64_GRP_RET);
+}
+
+bool DecodedInstructionCapstoneMIPS64_t::hasOperand(const int op_num) const
+{
+	if(op_num<0) throw std::logic_error(string("Called ")+ __FUNCTION__+" with opnum="+to_string(op_num));
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	const auto &mips = (the_insn->detail->mips64);
+	return 0 <= op_num  && op_num < mips.op_count;
+}
+
+// 0-based.  first operand is numbered 0.
+shared_ptr<DecodedOperand_t> DecodedInstructionCapstoneMIPS64_t::getOperand(const int op_num) const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	if(!hasOperand(op_num)) throw std::logic_error(string("Called ")+__FUNCTION__+" on without hasOperand()==true");
+
+	return shared_ptr<DecodedOperand_t>(new DecodedOperandCapstoneMIPS64_t(my_insn,(uint8_t)op_num));
+	
+}
+
+DecodedOperandVector_t DecodedInstructionCapstoneMIPS64_t::getOperands() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	const auto &mips = (the_insn->detail->mips64);
+	const auto opcount=mips.op_count;
+
+	auto ret_val=DecodedOperandVector_t();
+	
+	for(auto i=0;i<opcount;i++)
+		ret_val.push_back(getOperand(i));
+
+	return ret_val;
+}
+
+string DecodedInstructionCapstoneMIPS64_t::getMnemonic() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+
+	// return the new string.
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	return the_insn->mnemonic;
+
+	
+}
+
+
+int64_t DecodedInstructionCapstoneMIPS64_t::getImmediate() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+
+	// direct calls and jumps have a "immediate" which is really an address"  those are returned by getAddress
+	if(isCall() || isArm64Jmp(the_insn))
+		return 0;
+
+	return mips64InsnToImmedHelper<int64_t>(the_insn, cs_handle->getHandle());
+}
+
+
+virtual_offset_t DecodedInstructionCapstoneMIPS64_t::getAddress() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	if(isCall() || isArm64Jmp(the_insn))
+	{
+		const auto mnemonic=getMnemonic();
+		if( mnemonic=="tbnz" || mnemonic=="tbz")
+			return getOperand(2)->getConstant();
+		return mips64InsnToImmedHelper<int64_t>(the_insn, cs_handle->getHandle());
+	}
+	assert(0);
+
+}
+
+
+bool DecodedInstructionCapstoneMIPS64_t::setsStackPointer() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+
+	if(!hasOperand(0)) return false;
+
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	const auto &mips = (the_insn->detail->mips64);
+	return (mips.operands[0].type==MIPS64_OP_REG && mips.operands[0].reg==MIPS64_REG_SP);
+}
+
+uint32_t DecodedInstructionCapstoneMIPS64_t::getPrefixCount() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	return 0;
+}
+
+IRDB_SDK::VirtualOffset_t DecodedInstructionCapstoneMIPS64_t::getMemoryDisplacementOffset(const IRDB_SDK::DecodedOperand_t* t, const IRDB_SDK::Instruction_t* insn) const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	assert(0);
+}
+
+bool DecodedInstructionCapstoneMIPS64_t::hasRelevantRepPrefix() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	return false;
+}
+
+bool DecodedInstructionCapstoneMIPS64_t::hasRelevantRepnePrefix() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	return false;
+}
+
+bool DecodedInstructionCapstoneMIPS64_t::hasRelevantOperandSizePrefix() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	return false;
+}
+
+bool DecodedInstructionCapstoneMIPS64_t::hasRexWPrefix() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	return false;
+}
+
+bool DecodedInstructionCapstoneMIPS64_t::hasImplicitlyModifiedRegs() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	return false;
+}
+
diff --git a/irdb-libs/libIRDB-core/src/operand_csmips32.cpp b/irdb-libs/libIRDB-core/src/operand_csmips32.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4a2266d52d244025b2d7ce7ed961ff799118bf0c
--- /dev/null
+++ b/irdb-libs/libIRDB-core/src/operand_csmips32.cpp
@@ -0,0 +1,334 @@
+
+#include <libIRDB-core.hpp>
+#include <memory>
+#include <decode_base.hpp>
+#include <decode_csmips.hpp>
+#include <operand_base.hpp>
+#include <operand_csmips.hpp>
+
+
+using namespace std;
+using namespace libIRDB;
+
+#include <capstone.h>
+
+DecodedOperandCapstoneMIPS32_t::DecodedOperandCapstoneMIPS32_t( const shared_ptr<void> & p_my_insn, uint8_t p_op_num)
+	: DecodedOperandCapstoneMIPS_t(p_my_insn,p_op_num)
+{
+	
+}
+
+DecodedOperandCapstoneMIPS32_t::~DecodedOperandCapstoneMIPS32_t()
+{
+}
+
+
+bool DecodedOperandCapstoneMIPS32_t::isConstant() const
+{
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips.operands[op_num]);
+	return op.type==MIPS_OP_IMM;
+}
+
+uint64_t DecodedOperandCapstoneMIPS32_t::getConstant() const
+{
+	if(!isConstant()) throw logic_error(string("Cannot ")+__FUNCTION__+"  of non-constant operand");
+	
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips.operands[op_num]);
+	return op.imm;
+}
+
+string DecodedOperandCapstoneMIPS32_t::getString() const
+{
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips.operands[op_num]);
+        const auto handle=DecodedInstructionCapstoneMIPS32_t::cs_handle->getHandle();
+
+        switch(op.type)
+        {
+                case MIPS_OP_REG:
+                        return string(cs_reg_name(handle, op.reg));
+                case MIPS_OP_IMM:
+                        return to_string(op.imm);
+                case MIPS_OP_MEM:
+                {
+			string ret_val;
+			if (op.mem.base != MIPS_REG_INVALID)
+				ret_val+=cs_reg_name(handle, op.mem.base);
+
+			if (op.mem.disp != 0)
+				ret_val+=" + "+ to_string(op.mem.disp);
+
+			ret_val += " lsl/ror? ?? ";
+
+			return ret_val;
+		}
+                default:
+                        assert(0);
+        }
+}
+
+bool DecodedOperandCapstoneMIPS32_t::isRegister() const
+{
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips.operands[op_num]);
+	return op.type==MIPS_OP_REG;
+}
+
+bool DecodedOperandCapstoneMIPS32_t::isGeneralPurposeRegister() const
+{
+	const auto gp_regs=set<mips_reg>({
+		MIPS_REG_0,
+		MIPS_REG_1,
+		MIPS_REG_2,
+		MIPS_REG_3,
+		MIPS_REG_4,
+		MIPS_REG_5,
+		MIPS_REG_6,
+		MIPS_REG_7,
+		MIPS_REG_8,
+		MIPS_REG_9,
+		MIPS_REG_10,
+		MIPS_REG_11,
+		MIPS_REG_12,
+		MIPS_REG_13,
+		MIPS_REG_14,
+		MIPS_REG_15,
+		MIPS_REG_16,
+		MIPS_REG_17,
+		MIPS_REG_18,
+		MIPS_REG_19,
+		MIPS_REG_20,
+		MIPS_REG_21,
+		MIPS_REG_22,
+		MIPS_REG_23,
+		MIPS_REG_24,
+		MIPS_REG_25,
+		MIPS_REG_26,
+		MIPS_REG_27,
+		MIPS_REG_28,
+		MIPS_REG_29,
+		MIPS_REG_30,
+		MIPS_REG_31,
+		});
+
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips.operands[op_num]);
+        return isRegister() &&  gp_regs.find((mips_reg)op.reg)!=end(gp_regs);
+
+}
+
+bool DecodedOperandCapstoneMIPS32_t::isMmxRegister() const
+{
+	return false;
+}
+
+bool DecodedOperandCapstoneMIPS32_t::isFpuRegister() const
+{
+	const auto fpu_regs=set<mips_reg>({
+		MIPS_REG_F0,
+		MIPS_REG_F1,
+		MIPS_REG_F2,
+		MIPS_REG_F3,
+		MIPS_REG_F4,
+		MIPS_REG_F5,
+		MIPS_REG_F6,
+		MIPS_REG_F7,
+		MIPS_REG_F8,
+		MIPS_REG_F9,
+		MIPS_REG_F10,
+		MIPS_REG_F11,
+		MIPS_REG_F12,
+		MIPS_REG_F13,
+		MIPS_REG_F14,
+		MIPS_REG_F15,
+		MIPS_REG_F16,
+		MIPS_REG_F17,
+		MIPS_REG_F18,
+		MIPS_REG_F19,
+		MIPS_REG_F20,
+		MIPS_REG_F21,
+		MIPS_REG_F22,
+		MIPS_REG_F23,
+		MIPS_REG_F24,
+		MIPS_REG_F25,
+		MIPS_REG_F26,
+		MIPS_REG_F27,
+		MIPS_REG_F28,
+		MIPS_REG_F29,
+		MIPS_REG_F30,
+		MIPS_REG_F31,
+		});
+
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips.operands[op_num]);
+        return isRegister() &&  fpu_regs.find((mips_reg)op.reg)!=end(fpu_regs);
+}
+
+bool DecodedOperandCapstoneMIPS32_t::isSseRegister() const
+{
+	return false;
+}
+
+bool DecodedOperandCapstoneMIPS32_t::isAvxRegister() const
+{
+	return false;
+}
+
+bool DecodedOperandCapstoneMIPS32_t::isZmmRegister() const
+{
+	return false;
+}
+
+bool DecodedOperandCapstoneMIPS32_t::isSpecialRegister() const
+{
+	const auto special_regs=set<mips_reg>({
+	        MIPS_REG_AC0,
+		MIPS_REG_AC1,
+		MIPS_REG_AC2,
+		MIPS_REG_AC3,
+		MIPS_REG_CC0,
+		MIPS_REG_CC1,
+		MIPS_REG_CC2,
+		MIPS_REG_CC3,
+		MIPS_REG_CC4,
+		MIPS_REG_CC5,
+		MIPS_REG_CC6,
+		MIPS_REG_CC7,
+
+	});
+
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips.operands[op_num]);
+        return isRegister() &&  special_regs.find((mips_reg)op.reg)!=end(special_regs);
+	return false;
+}
+
+bool DecodedOperandCapstoneMIPS32_t::isSegmentRegister() const
+{
+	return false;
+}
+
+
+
+uint32_t DecodedOperandCapstoneMIPS32_t::getRegNumber() const
+{
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips.operands[op_num]);
+	return op.reg;
+}
+
+bool DecodedOperandCapstoneMIPS32_t::isMemory() const
+{
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips.operands[op_num]);
+        return op.type==MIPS_OP_MEM;
+
+}
+
+bool DecodedOperandCapstoneMIPS32_t::hasBaseRegister() const
+{
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips.operands[op_num]);
+        return isMemory() && op.mem.base!=MIPS_REG_INVALID;
+
+}
+
+bool DecodedOperandCapstoneMIPS32_t::hasIndexRegister() const
+{
+	return false;
+}
+
+uint32_t DecodedOperandCapstoneMIPS32_t::getBaseRegister() const
+{
+	if(!isMemory()) throw logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips.operands[op_num]);
+        return op.mem.base;
+}
+
+uint32_t DecodedOperandCapstoneMIPS32_t::getIndexRegister() const
+{
+	throw logic_error(string("Cannot ")+__FUNCTION__+"  of operand with no index register");
+}
+
+uint32_t DecodedOperandCapstoneMIPS32_t::getScaleValue() const
+{
+	assert(0);
+}
+
+bool DecodedOperandCapstoneMIPS32_t::hasMemoryDisplacement() const
+{
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips.operands[op_num]);
+        return op.mem.disp!=0;
+
+} // end of DecodedOperandCapstoneMIPS32_t::hasMemoryDisplacement()
+
+virtual_offset_t DecodedOperandCapstoneMIPS32_t::getMemoryDisplacement() const
+{
+	if(!isMemory()) throw logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips.operands[op_num]);
+        return op.mem.disp;
+}
+
+bool DecodedOperandCapstoneMIPS32_t::isPcrel() const
+{
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips.operands[op_num]);
+
+	// covers ldr, ldrsw, prfm
+	// note: capstone's reports ldr, ldrsw, and prfm as using an imm, when they actually access memory.
+	// jdh fixed this in the IRDB's Disassemble routine
+	if(isMemory() && op.mem.base==MIPS_REG_PC)
+		return true;
+
+	return isRegister() && getRegNumber()==MIPS_REG_PC; // check to see if it's actually the pc
+
+}
+
+/* in bytes */
+uint32_t DecodedOperandCapstoneMIPS32_t::getMemoryDisplacementEncodingSize() const
+{
+	if(!isMemory()) throw logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
+	assert(0);
+}
+
+uint32_t DecodedOperandCapstoneMIPS32_t::getArgumentSizeInBytes() const
+{
+	return false;
+}
+
+uint32_t DecodedOperandCapstoneMIPS32_t::getArgumentSizeInBits() const
+{
+        return getArgumentSizeInBytes()*8;
+}
+
+bool DecodedOperandCapstoneMIPS32_t::hasSegmentRegister() const
+{
+	return false;
+}
+
+uint32_t DecodedOperandCapstoneMIPS32_t::getSegmentRegister() const
+{
+	throw logic_error(string("Cannot ")+__FUNCTION__+"  on MIPS architecture");
+}
+
+bool DecodedOperandCapstoneMIPS32_t::isRead() const
+{
+        //const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        // const auto &op = (the_insn->detail->mips.operands[op_num]);
+	// return (op.access & CS_AC_READ)!=0;
+	return op_num > 0;
+}
+
+bool DecodedOperandCapstoneMIPS32_t::isWritten() const
+{	
+	// default: use capstone's advice.
+        //const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        //const auto &op = (the_insn->detail->mips.operands[op_num]);
+	//return (op.access & CS_AC_WRITE)!=0;
+	return op_num == 0;
+}
diff --git a/irdb-libs/libIRDB-core/src/operand_csmips64.cpp b/irdb-libs/libIRDB-core/src/operand_csmips64.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8d4f0b8f3664c2167d898fa3b0d42bb2ab9f1448
--- /dev/null
+++ b/irdb-libs/libIRDB-core/src/operand_csmips64.cpp
@@ -0,0 +1,308 @@
+
+#include <libIRDB-core.hpp>
+#include <memory>
+#include <decode_base.hpp>
+#include <decode_csmips.hpp>
+#include <operand_base.hpp>
+#include <operand_csmips.hpp>
+
+
+using namespace std;
+using namespace libIRDB;
+
+#include <capstone.h>
+static const auto MIPS64_REG_PC=(mips64_reg)(MIPS64_REG_ENDING+1);
+
+
+DecodedOperandCapstoneMIPS64_t::DecodedOperandCapstoneMIPS64_t( const shared_ptr<void> & p_my_insn, uint8_t p_op_num)
+	: DecodedOperandCapstoneMIPS_t(p_my_insn,p_op_num)
+{
+	
+}
+
+DecodedOperandCapstoneMIPS64_t::~DecodedOperandCapstoneMIPS64_t()
+{
+}
+
+
+bool DecodedOperandCapstoneMIPS64_t::isConstant() const
+{
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+	return op.type==MIPS64_OP_IMM;
+}
+
+uint64_t DecodedOperandCapstoneMIPS64_t::getConstant() const
+{
+	if(!isConstant()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-constant operand");
+	
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+	return op.imm;
+}
+
+string DecodedOperandCapstoneMIPS64_t::getString() const
+{
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+        const auto handle=DecodedInstructionCapstoneMIPS64_t::cs_handle->getHandle();
+
+        switch(op.type)
+        {
+                case MIPS64_OP_REG:
+                        return string(cs_reg_name(handle, op.reg));
+                case MIPS64_OP_REG_MRS:
+                case MIPS64_OP_REG_MSR:
+                case MIPS64_OP_FP:
+			return string("fpcr");
+                case MIPS64_OP_IMM:
+                        return to_string(op.imm);
+                case MIPS64_OP_MEM:
+                {
+			string ret_val;
+			if (op.mem.base != MIPS64_REG_INVALID)
+				ret_val+=cs_reg_name(handle, op.mem.base);
+
+			if (op.mem.index != MIPS64_REG_INVALID)
+				ret_val+=string(" + ") +cs_reg_name(handle, op.mem.index);
+
+			if (op.mem.disp != 0)
+				ret_val+=" + "+ to_string(op.mem.disp);
+
+			if(ret_val=="")
+				return "0";
+
+			return ret_val;
+		}
+                default:
+                        assert(0);
+        }
+}
+
+bool DecodedOperandCapstoneMIPS64_t::isRegister() const
+{
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+	return op.type==MIPS64_OP_REG;
+}
+
+bool DecodedOperandCapstoneMIPS64_t::isGeneralPurposeRegister() const
+{
+	const auto gp_regs=set<mips64_reg>({
+		MIPS64_REG_X29, MIPS64_REG_X30, MIPS64_REG_SP,  MIPS64_REG_WSP, MIPS64_REG_WZR, MIPS64_REG_XZR,
+		MIPS64_REG_W0,  MIPS64_REG_W1,  MIPS64_REG_W2,  MIPS64_REG_W3,  MIPS64_REG_W4,  MIPS64_REG_W5,  MIPS64_REG_W6,  MIPS64_REG_W7,
+        	MIPS64_REG_W8,  MIPS64_REG_W9,  MIPS64_REG_W10, MIPS64_REG_W11, MIPS64_REG_W12, MIPS64_REG_W13, MIPS64_REG_W14, MIPS64_REG_W15,
+        	MIPS64_REG_W16, MIPS64_REG_W17, MIPS64_REG_W18, MIPS64_REG_W19, MIPS64_REG_W20, MIPS64_REG_W21, MIPS64_REG_W22, MIPS64_REG_W23, 
+		MIPS64_REG_W24, MIPS64_REG_W25, MIPS64_REG_W26, MIPS64_REG_W27, MIPS64_REG_W28, MIPS64_REG_W29, MIPS64_REG_W30, 
+		MIPS64_REG_X0,  MIPS64_REG_X1,  MIPS64_REG_X2,  MIPS64_REG_X3,  MIPS64_REG_X4,  MIPS64_REG_X5,  MIPS64_REG_X6,  MIPS64_REG_X7,
+		MIPS64_REG_X8,  MIPS64_REG_X9,  MIPS64_REG_X10, MIPS64_REG_X11, MIPS64_REG_X12, MIPS64_REG_X13, MIPS64_REG_X14, MIPS64_REG_X15,
+		MIPS64_REG_X16, MIPS64_REG_X17, MIPS64_REG_X18, MIPS64_REG_X19, MIPS64_REG_X20, MIPS64_REG_X21, MIPS64_REG_X22, MIPS64_REG_X23,
+		MIPS64_REG_X24, MIPS64_REG_X25, MIPS64_REG_X26, MIPS64_REG_X27, MIPS64_REG_X28,
+	});
+
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+        return isRegister() &&  gp_regs.find(op.reg)!=end(gp_regs);
+
+}
+
+bool DecodedOperandCapstoneMIPS64_t::isMmxRegister() const
+{
+	return false;
+}
+
+bool DecodedOperandCapstoneMIPS64_t::isFpuRegister() const
+{
+	const auto fpu_regs=set<mips64_reg>({
+		MIPS64_REG_B0,  MIPS64_REG_B1,  MIPS64_REG_B2,  MIPS64_REG_B3,  MIPS64_REG_B4,  MIPS64_REG_B5,  MIPS64_REG_B6,  MIPS64_REG_B7,
+        	MIPS64_REG_B8,  MIPS64_REG_B9,  MIPS64_REG_B10, MIPS64_REG_B11, MIPS64_REG_B12, MIPS64_REG_B13, MIPS64_REG_B14, MIPS64_REG_B15,
+        	MIPS64_REG_B16, MIPS64_REG_B17, MIPS64_REG_B18, MIPS64_REG_B19, MIPS64_REG_B20, MIPS64_REG_B21, MIPS64_REG_B22, MIPS64_REG_B23,
+        	MIPS64_REG_B24, MIPS64_REG_B25, MIPS64_REG_B26, MIPS64_REG_B27, MIPS64_REG_B28, MIPS64_REG_B29, MIPS64_REG_B30, MIPS64_REG_B31,
+		MIPS64_REG_H0,  MIPS64_REG_H1,  MIPS64_REG_H2,  MIPS64_REG_H3,  MIPS64_REG_H4,  MIPS64_REG_H5,  MIPS64_REG_H6,  MIPS64_REG_H7, 
+		MIPS64_REG_H8,  MIPS64_REG_H9,  MIPS64_REG_H10, MIPS64_REG_H11, MIPS64_REG_H12, MIPS64_REG_H13, MIPS64_REG_H14, MIPS64_REG_H15, 
+		MIPS64_REG_H16, MIPS64_REG_H17, MIPS64_REG_H18, MIPS64_REG_H19, MIPS64_REG_H20, MIPS64_REG_H21, MIPS64_REG_H22, MIPS64_REG_H23, 
+		MIPS64_REG_H24, MIPS64_REG_H25, MIPS64_REG_H26, MIPS64_REG_H27, MIPS64_REG_H28, MIPS64_REG_H29, MIPS64_REG_H30, MIPS64_REG_H31, 
+	        MIPS64_REG_D0,  MIPS64_REG_D1,  MIPS64_REG_D2,  MIPS64_REG_D3,  MIPS64_REG_D4,  MIPS64_REG_D5,  MIPS64_REG_D6,  MIPS64_REG_D7,
+        	MIPS64_REG_D8,  MIPS64_REG_D9,  MIPS64_REG_D10, MIPS64_REG_D11, MIPS64_REG_D12, MIPS64_REG_D13, MIPS64_REG_D14, MIPS64_REG_D15,
+		MIPS64_REG_D16, MIPS64_REG_D17, MIPS64_REG_D18, MIPS64_REG_D19, MIPS64_REG_D20, MIPS64_REG_D21, MIPS64_REG_D22, MIPS64_REG_D23,
+		MIPS64_REG_D24, MIPS64_REG_D25, MIPS64_REG_D26, MIPS64_REG_D27, MIPS64_REG_D28, MIPS64_REG_D29, MIPS64_REG_D30, MIPS64_REG_D31,
+	        MIPS64_REG_H0,  MIPS64_REG_H1,  MIPS64_REG_H2,  MIPS64_REG_H3,  MIPS64_REG_H4,  MIPS64_REG_H5,  MIPS64_REG_H6,  MIPS64_REG_H7,
+		MIPS64_REG_H8,  MIPS64_REG_H9,  MIPS64_REG_H10, MIPS64_REG_H11, MIPS64_REG_H12, MIPS64_REG_H13, MIPS64_REG_H14, MIPS64_REG_H15,
+		MIPS64_REG_H16, MIPS64_REG_H17, MIPS64_REG_H18, MIPS64_REG_H19, MIPS64_REG_H20, MIPS64_REG_H21, MIPS64_REG_H22, MIPS64_REG_H23,
+		MIPS64_REG_H24, MIPS64_REG_H25, MIPS64_REG_H26, MIPS64_REG_H27, MIPS64_REG_H28, MIPS64_REG_H29, MIPS64_REG_H30, MIPS64_REG_H31,
+	        MIPS64_REG_Q0,  MIPS64_REG_Q1,  MIPS64_REG_Q2,  MIPS64_REG_Q3,  MIPS64_REG_Q4,  MIPS64_REG_Q5,  MIPS64_REG_Q6,  MIPS64_REG_Q7,
+		MIPS64_REG_Q8,  MIPS64_REG_Q9,  MIPS64_REG_Q10, MIPS64_REG_Q11, MIPS64_REG_Q12, MIPS64_REG_Q13, MIPS64_REG_Q14, MIPS64_REG_Q15,
+		MIPS64_REG_Q16, MIPS64_REG_Q17, MIPS64_REG_Q18, MIPS64_REG_Q19, MIPS64_REG_Q20, MIPS64_REG_Q21, MIPS64_REG_Q22, MIPS64_REG_Q23,
+		MIPS64_REG_Q24, MIPS64_REG_Q25, MIPS64_REG_Q26, MIPS64_REG_Q27, MIPS64_REG_Q28, MIPS64_REG_Q29, MIPS64_REG_Q30, MIPS64_REG_Q31,
+		MIPS64_REG_S0,  MIPS64_REG_S1,  MIPS64_REG_S2,  MIPS64_REG_S3,  MIPS64_REG_S4,  MIPS64_REG_S5,  MIPS64_REG_S6,  MIPS64_REG_S7,
+		MIPS64_REG_S8,  MIPS64_REG_S9,  MIPS64_REG_S10, MIPS64_REG_S11, MIPS64_REG_S12, MIPS64_REG_S13, MIPS64_REG_S14, MIPS64_REG_S15,
+		MIPS64_REG_S16, MIPS64_REG_S17, MIPS64_REG_S18, MIPS64_REG_S19, MIPS64_REG_S20, MIPS64_REG_S21, MIPS64_REG_S22, MIPS64_REG_S23,
+		MIPS64_REG_S24, MIPS64_REG_S25, MIPS64_REG_S26, MIPS64_REG_S27, MIPS64_REG_S28, MIPS64_REG_S29, MIPS64_REG_S30, MIPS64_REG_S31,
+	});
+
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+        return isRegister() &&  fpu_regs.find(op.reg)!=end(fpu_regs);
+}
+
+bool DecodedOperandCapstoneMIPS64_t::isSseRegister() const
+{
+	return false;
+}
+
+bool DecodedOperandCapstoneMIPS64_t::isAvxRegister() const
+{
+	return false;
+}
+
+bool DecodedOperandCapstoneMIPS64_t::isZmmRegister() const
+{
+	return false;
+}
+
+bool DecodedOperandCapstoneMIPS64_t::isSpecialRegister() const
+{
+	const auto special_regs=set<mips64_reg>({
+		MIPS64_REG_NZCV,
+	});
+
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+        return isRegister() &&  special_regs.find(op.reg)!=end(special_regs);
+	return false;
+}
+
+bool DecodedOperandCapstoneMIPS64_t::isSegmentRegister() const
+{
+	return false;
+}
+
+
+
+uint32_t DecodedOperandCapstoneMIPS64_t::getRegNumber() const
+{
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+	return op.reg;
+}
+
+bool DecodedOperandCapstoneMIPS64_t::isMemory() const
+{
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+        return op.type==MIPS64_OP_MEM;
+
+}
+
+bool DecodedOperandCapstoneMIPS64_t::hasBaseRegister() const
+{
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+        return isMemory() && op.mem.base!=MIPS64_REG_INVALID;
+
+}
+
+bool DecodedOperandCapstoneMIPS64_t::hasIndexRegister() const
+{
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+        return isMemory() && op.mem.index!=MIPS64_REG_INVALID;
+}
+
+uint32_t DecodedOperandCapstoneMIPS64_t::getBaseRegister() const
+{
+	if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+        return op.mem.base;
+}
+
+uint32_t DecodedOperandCapstoneMIPS64_t::getIndexRegister() const
+{
+	if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+        return op.mem.index;
+}
+
+uint32_t DecodedOperandCapstoneMIPS64_t::getScaleValue() const
+{
+	assert(0);
+}
+
+bool DecodedOperandCapstoneMIPS64_t::hasMemoryDisplacement() const
+{
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+        return op.mem.disp!=0;
+
+} // end of DecodedOperandCapstoneMIPS64_t::hasMemoryDisplacement()
+
+virtual_offset_t DecodedOperandCapstoneMIPS64_t::getMemoryDisplacement() const
+{
+	if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+        return op.mem.disp;
+}
+
+bool DecodedOperandCapstoneMIPS64_t::isPcrel() const
+{
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+
+	// covers ldr, ldrsw, prfm
+	// note: capstone's reports ldr, ldrsw, and prfm as using an imm, when they actually access memory.
+	// jdh fixed this in the IRDB's Disassemble routine
+	if(isMemory() && op.mem.base==MIPS64_REG_PC)
+		return true;
+
+	const auto mnemonic=string(the_insn->mnemonic);
+	const auto is_adr_type= mnemonic=="adr"  || mnemonic=="adrp";
+	if(is_adr_type && op.type==MIPS64_OP_IMM)
+		return true;
+
+	return false;	 // no PC as general purpose reg.
+}
+
+/* in bytes */
+uint32_t DecodedOperandCapstoneMIPS64_t::getMemoryDisplacementEncodingSize() const
+{
+	if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
+	assert(0);
+}
+
+uint32_t DecodedOperandCapstoneMIPS64_t::getArgumentSizeInBytes() const
+{
+	return false;
+}
+
+uint32_t DecodedOperandCapstoneMIPS64_t::getArgumentSizeInBits() const
+{
+        return getArgumentSizeInBytes()*8;
+}
+
+bool DecodedOperandCapstoneMIPS64_t::hasSegmentRegister() const
+{
+	return false;
+}
+
+uint32_t DecodedOperandCapstoneMIPS64_t::getSegmentRegister() const
+{
+	throw std::logic_error(string("Cannot ")+__FUNCTION__+"  on MIPS architecture");
+}
+
+bool DecodedOperandCapstoneMIPS64_t::isRead() const
+{
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+	return (op.access & CS_AC_READ)!=0;
+}
+
+bool DecodedOperandCapstoneMIPS64_t::isWritten() const
+{	
+	// default: use capstone's advice.
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->mips64.operands[op_num]);
+	return (op.access & CS_AC_WRITE)!=0;
+}
diff --git a/irdb-libs/meds2pdb/elfreader.cpp b/irdb-libs/meds2pdb/elfreader.cpp
index 7c5f8ae323275eb59e5075fc687a2aedac26aa55..a284cfa7367a36f733f2b48b515791aa29142b8c 100644
--- a/irdb-libs/meds2pdb/elfreader.cpp
+++ b/irdb-libs/meds2pdb/elfreader.cpp
@@ -31,45 +31,12 @@ using namespace EXEIO;
 
 ElfReader::ElfReader(char *p_elfFile)
 {
-//    m_reader=new elfio;
 	m_reader=new EXEIO::exeio(p_elfFile);
 	assert(m_reader);
 
 	EXEIO::dump::header(cout, *m_reader);
 	EXEIO::dump::section_headers(cout, *m_reader);
 
-    // Initialize it
-/*
-    bool ok = m_reader->load( p_elfFile );
-    if ( ! ok ) {
-        std::cerr << "Can't open file:" << p_elfFile << std::endl;
-	assert(0);
-	exit(-1);
-    }
-
-
-    if(m_reader->get_class() == ELFCLASS32)
-	std::cout << "Input file is ELF32" << std::endl;
-    else
-	std::cout << "Input file is ELF64" << std::endl;
-
-
-    // List all sections of the file
-    int i;
-    ELFIO::Elf_Half nSecNo = m_reader->sections.size();
-    for ( i = 0; i < nSecNo; ++i ) 
-    {    // For all sections
-	section* psec = m_reader->sections[i];
-	m_sections.push_back(psec);
-        std::cout << "  [" << i << "] "
-                  << psec->get_name()
-                  << "\t"
-                  << psec->get_size()
-                  << std::endl;
-
-    }
-    std::cout << std::endl;
-*/
 }
 
 ElfReader::~ElfReader()
@@ -151,6 +118,8 @@ void ElfReader::SetArchitecture()
 			m_reader->getMachineType() == EXEIO::mtX86_64  ? IRDB_SDK::admtX86_64  :
 			m_reader->getMachineType() == EXEIO::mtAarch64 ? IRDB_SDK::admtAarch64 :
 			m_reader->getMachineType() == EXEIO::mtArm32   ? IRDB_SDK::admtArm32   :
+			m_reader->getMachineType() == EXEIO::mtMips32  ? IRDB_SDK::admtMips32  :
+			m_reader->getMachineType() == EXEIO::mtMips64  ? IRDB_SDK::admtMips64  :
 			throw std::invalid_argument("Unknown architecture.");
 
 	libIRDB::FileIR_t::setArchitecture(width,mt);