diff --git a/SMPStaticAnalyzer b/SMPStaticAnalyzer
index e535bd49786493fa14b47697f82ba04583f1de4c..4e8f14c902fce2ceb7b3d2790a508fcb59b782d7 160000
--- a/SMPStaticAnalyzer
+++ b/SMPStaticAnalyzer
@@ -1 +1 @@
-Subproject commit e535bd49786493fa14b47697f82ba04583f1de4c
+Subproject commit 4e8f14c902fce2ceb7b3d2790a508fcb59b782d7
diff --git a/irdb-libs/ir_builders/fill_in_cfg.cpp b/irdb-libs/ir_builders/fill_in_cfg.cpp
index 91f520ab203b2afe4120094becf7f433aa734d3b..122be1ed6ed96f2b837f5fccb1140ee7acf14684 100644
--- a/irdb-libs/ir_builders/fill_in_cfg.cpp
+++ b/irdb-libs/ir_builders/fill_in_cfg.cpp
@@ -497,8 +497,11 @@ void PopulateCFG::detect_scoops_in_code(FileIR_t *firp)
 	// data for this function
 	auto already_scoopified=set<VirtualOffset_t>();
 
+	const auto is_arm64 = firp->getArchitecture()->getMachineType() == admtAarch64;
+	const auto is_arm32 = firp->getArchitecture()->getMachineType() == admtArm32;
+
 	// only valid for arm64
-	if(firp->getArchitecture()->getMachineType() != admtAarch64) return;
+	if(!is_arm64 && !is_arm32) return;
 
 	// check each insn for an ldr with a pcrel operand.
 	for(auto insn : firp->getInstructions())
@@ -512,20 +515,25 @@ void PopulateCFG::detect_scoops_in_code(FileIR_t *firp)
 
 		// sanity check that it's a memory operation, and extract fields
 		assert(op1->isMemory());
-		const auto referenced_address=op1->getMemoryDisplacement();
-		const auto op0_str=op0->getString();
-		const auto referenced_size=  // could use API call?
-			op0_str[0]=='w' ? 4  : 
-			op0_str[0]=='x' ? 8  : 
-			op0_str[0]=='s' ? 4  : 
-			op0_str[0]=='d' ? 8  : 
-			op0_str[0]=='q' ? 16 : 
+		const auto referenced_address = op1->getMemoryDisplacement() + (is_arm32 ? insn->getAddress()->getVirtualOffset() + 8 : 0); 
+		const auto op0_str            = op0->getString();
+		const auto referenced_size    =  // could use API call?
+			is_arm64 && op0_str[0]=='w' ? 4  : 
+			is_arm64 && op0_str[0]=='x' ? 8  : 
+			is_arm64 && op0_str[0]=='s' ? 4  : 
+			is_arm64 && op0_str[0]=='d' ? 8  : 
+			is_arm64 && op0_str[0]=='q' ? 16 : 
+			is_arm32 && op0_str[0]=='r' ? 4  : 
+			is_arm32 && op0_str   =="lr"? 4  : 
+			is_arm32 && op0_str   =="fp"? 4  : 
+			is_arm32 && op0_str   =="sp"? 4  : 
+			is_arm32 && op0_str   =="ip"? 4  : 
 			throw domain_error("Cannot decode instruction size");
 			;
 
 		// check if we've seen this address already
-		const auto already_seen_it=already_scoopified.find(referenced_address);
-		if(already_seen_it!=end(already_scoopified)) continue;
+		const auto already_seen_it = already_scoopified.find(referenced_address);
+		if(already_seen_it != end(already_scoopified)) continue;
 
 		// not seen, add it
 		already_scoopified.insert(referenced_address);
diff --git a/irdb-libs/ir_builders/fill_in_indtargs.cpp b/irdb-libs/ir_builders/fill_in_indtargs.cpp
index 426c667a34043f50c935d6adafb9f764a5cd59db..7a0b80cffea56191da617ceebe96c6ba5b00123c 100644
--- a/irdb-libs/ir_builders/fill_in_indtargs.cpp
+++ b/irdb-libs/ir_builders/fill_in_indtargs.cpp
@@ -350,7 +350,11 @@ void get_instruction_targets(FileIR_t *firp, EXEIO::exeio* exeiop, const set<Vir
 		}
 		else if(mt==admtAarch64)
 		{
-			check_for_arm_switch_type1(firp,insn,  *disasm, exeiop);
+			check_for_arm64_switch_type1(firp,insn,  *disasm, exeiop);
+		}
+		else if(mt==admtArm32)
+		{
+			check_for_arm32_switch_type1(firp,insn,  *disasm, exeiop);
 		}
 		else
 			throw invalid_argument("Cannot determine machine type");
@@ -644,8 +648,16 @@ bool backup_until(const string &insn_type_regex_str,
 }
 
 
+void check_for_arm32_switch_type1(
+		FileIR_t *firp, 
+		Instruction_t* i10, 
+		const DecodedInstruction_t &d10, 
+		EXEIO::exeio* exeiop)
+{
+	return;
+}
 
-void check_for_arm_switch_type1(
+void check_for_arm64_switch_type1(
 		FileIR_t *firp, 
 		Instruction_t* i10, 
 		const DecodedInstruction_t &d10, 
diff --git a/irdb-libs/ir_builders/fix_calls.cpp b/irdb-libs/ir_builders/fix_calls.cpp
index 13b645d18f0900deab35448d855284e80078513f..d871e1b482100d10d88c7af7141f332b6563e306 100644
--- a/irdb-libs/ir_builders/fix_calls.cpp
+++ b/irdb-libs/ir_builders/fix_calls.cpp
@@ -777,24 +777,27 @@ class FixCalls_t : public TransformStep_t
 		//
 		void fix_other_pcrel(FileIR_t* firp, Instruction_t *insn, uintptr_t virt_offset)
 		{
-			auto disasm=DecodedInstruction_t::factory(insn);
-			const auto &operands=disasm->getOperands();
-			const auto relop_it=find_if(ALLOF(operands),[](const shared_ptr<DecodedOperand_t>& op)
-				{ return op->isPcrel() ; } );
-			const bool is_rel= relop_it!=operands.end(); 
+			const auto disasm    = DecodedInstruction_t::factory(insn);
+			const auto &operands = disasm->getOperands();
+			const auto relop_it  = find_if(ALLOF(operands),[](const shared_ptr<DecodedOperand_t>& op) { return op->isPcrel() ; } );
+			const auto is_rel    = relop_it!=operands.end(); 
+			const auto is_read   = is_rel ? (*relop_it)->isRead() : false;
 
 			/* if this has already been fixed, we can skip it */
-			if(virt_offset==0 || virt_offset==(uintptr_t)-1)
+			if(virt_offset == 0 || virt_offset == (uintptr_t)-1)
 				return;
 
-			if(is_rel)
+			if(is_rel && is_read)
 			{
-				const auto &the_arg=*(relop_it->get());	
-				const auto mt=firp->getArchitecture()->getMachineType();
-				if(mt==admtAarch64)
+				const auto &the_arg = *(relop_it->get());	
+				const auto mt       = firp->getArchitecture()->getMachineType();
+				if(mt==admtAarch64 || mt==admtArm32)
 				{
 					// figure out how to rewrite pcrel arm insns, then change the virt addr
 					// insn->getAddress()->setVirtualOffset(0);	
+					// for now, we aren't doing this... we may need to for doing xforms.
+					if(getenv("VERBOSE_FIX_CALLS"))
+						cout << "Detected arm32/64 pc-rel operand in " << disasm->getDisassembly()  << endl;
 				}
 				else if(mt==admtX86_64 ||  mt==admtI386)
 				{
@@ -848,13 +851,14 @@ class FixCalls_t : public TransformStep_t
 
 					other_fixes++;
 
-					disasm=DecodedInstruction_t::factory(insn);
 					if(getenv("VERBOSE_FIX_CALLS"))
-						cout<<" Converted to: "<<disasm->getDisassembly() << endl;
+						cout << " Converted to: " << insn->getDisassembly() << endl;
 
 					// and it's important to set the VO to 0, so that the pcrel-ness is calculated correctly.
 					insn->getAddress()->setVirtualOffset(0);	
 				}
+				else
+					throw std::invalid_argument("Unknown architecture in fix_other_pcrel");
 
 				// now that we've done the rewriting, go ahead and add the reloc.
 				auto reloc=firp->addNewRelocation(insn,0,"pcrel");
diff --git a/irdb-libs/libIRDB-core/include/decode_csarm.hpp b/irdb-libs/libIRDB-core/include/decode_csarm.hpp
index b517d7d04b0708e317ee4a3809680866ff67bfff..c283b150334facf518c4b6a50a708c7ebae4db19 100644
--- a/irdb-libs/libIRDB-core/include/decode_csarm.hpp
+++ b/irdb-libs/libIRDB-core/include/decode_csarm.hpp
@@ -2,71 +2,142 @@
 namespace libIRDB
 {
 
-using namespace libIRDB;
-using namespace std;
-
-class DecodedOperandCapstoneARM64_t;
-class DecodedInstructionCapstoneARM64_t : virtual public IRDB_SDK::DecodedInstruction_t
-{
-	public:
-		DecodedInstructionCapstoneARM64_t()=delete;
-		DecodedInstructionCapstoneARM64_t& operator=(const DecodedInstructionCapstoneARM64_t& copy);
-
-		virtual ~DecodedInstructionCapstoneARM64_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;
-
-	private:
-
-		void Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len);
-
-		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 DecodedOperandCapstoneARM64_t;
-
-		DecodedInstructionCapstoneARM64_t(const shared_ptr<void> &my_insn);
-		DecodedInstructionCapstoneARM64_t(const Instruction_t*);
-		DecodedInstructionCapstoneARM64_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len);
-		DecodedInstructionCapstoneARM64_t(const virtual_offset_t start_addr, const void *data, const void* endptr);
-		DecodedInstructionCapstoneARM64_t(const DecodedInstructionCapstoneARM64_t& copy);
-};
+	using namespace libIRDB;
+	using namespace std;
+
+	class DecodedOperandCapstoneARM_t;
+	class DecodedInstructionCapstoneARM_t : virtual public IRDB_SDK::DecodedInstruction_t
+	{
+		public:
+			DecodedInstructionCapstoneARM_t& operator=(const DecodedInstructionCapstoneARM_t& copy)
+			{
+				my_insn = copy.my_insn;
+				return *this;
+			}
+
+			virtual ~DecodedInstructionCapstoneARM_t() { } 
+
+		protected:
+			DecodedInstructionCapstoneARM_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 DecodedOperandCapstoneARM_t;
+	};
+
+	class DecodedOperandCapstoneARM32_t;
+	class DecodedInstructionCapstoneARM32_t : public DecodedInstructionCapstoneARM_t
+	{
+		public:
+			DecodedInstructionCapstoneARM32_t()=delete;
+			DecodedInstructionCapstoneARM32_t& operator=(const DecodedInstructionCapstoneARM32_t& copy);
+
+			virtual ~DecodedInstructionCapstoneARM32_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:
+			DecodedInstructionCapstoneARM32_t(const shared_ptr<void> &my_insn) ;
+			DecodedInstructionCapstoneARM32_t(const Instruction_t* my_insn) ;
+			DecodedInstructionCapstoneARM32_t(const virtual_offset_t sa, const void *data, uint32_t max_len  ) ;
+			DecodedInstructionCapstoneARM32_t(const virtual_offset_t sa, const void *data, const void* endptr) ;
+			DecodedInstructionCapstoneARM32_t(const DecodedInstructionCapstoneARM32_t& copy) ;
+
+			friend class IRDB_SDK::DecodedInstruction_t;
+			friend class DecodedOperandCapstoneARM32_t;
+	};
+
+	class DecodedOperandCapstoneARM64_t;
+	class DecodedInstructionCapstoneARM64_t : public DecodedInstructionCapstoneARM_t
+	{
+		public:
+			DecodedInstructionCapstoneARM64_t()=delete;
+			DecodedInstructionCapstoneARM64_t& operator=(const DecodedInstructionCapstoneARM64_t& copy);
+
+			virtual ~DecodedInstructionCapstoneARM64_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:
+			DecodedInstructionCapstoneARM64_t(const shared_ptr<void> &my_insn) ;
+			DecodedInstructionCapstoneARM64_t(const Instruction_t*) ;
+			DecodedInstructionCapstoneARM64_t(const virtual_offset_t sa, const void *data, uint32_t max_len  ) ;
+			DecodedInstructionCapstoneARM64_t(const virtual_offset_t sa, const void *data, const void* endptr) ;
+			DecodedInstructionCapstoneARM64_t(const DecodedInstructionCapstoneARM64_t& copy) ;
+
+			friend class IRDB_SDK::DecodedInstruction_t;
+			friend class DecodedOperandCapstoneARM64_t;
+	};
 
 }
 
diff --git a/irdb-libs/libIRDB-core/include/operand_csarm.hpp b/irdb-libs/libIRDB-core/include/operand_csarm.hpp
index da26a2105ca45719f9262f9e0a9912939195e7fa..10968d122ea45f19081930ad1952372ebe5d47d3 100644
--- a/irdb-libs/libIRDB-core/include/operand_csarm.hpp
+++ b/irdb-libs/libIRDB-core/include/operand_csarm.hpp
@@ -2,56 +2,106 @@
 namespace libIRDB
 {
 
-using namespace std;
-using namespace libIRDB;
+	using namespace std;
+	using namespace libIRDB;
 
-class DecodedOperandCapstoneARM64_t;
+	class DecodedOperandCapstoneARM_t : virtual public IRDB_SDK::DecodedOperand_t
+	{
+		public:
+			DecodedOperandCapstoneARM_t() =delete;
+			virtual ~DecodedOperandCapstoneARM_t() { }
 
-class DecodedOperandCapstoneARM64_t : virtual public IRDB_SDK::DecodedOperand_t
-{
-	public:
-		DecodedOperandCapstoneARM64_t() =delete;
-		virtual ~DecodedOperandCapstoneARM64_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:
-
-		DecodedOperandCapstoneARM64_t( const shared_ptr<void> &my_insn, uint8_t op_num);
-
-		shared_ptr<void> my_insn;
-		uint8_t op_num;
-
-		friend class DecodedInstructionCapstoneARM64_t;
-};
+		protected:
+
+			DecodedOperandCapstoneARM_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 DecodedInstructionCapstoneARM_t;
+	};
+
+	class DecodedOperandCapstoneARM32_t : public DecodedOperandCapstoneARM_t
+	{
+		public:
+			DecodedOperandCapstoneARM32_t() =delete;
+			virtual ~DecodedOperandCapstoneARM32_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:
+			DecodedOperandCapstoneARM32_t( const shared_ptr<void> &p_my_insn, uint8_t p_op_num);
+			friend class DecodedInstructionCapstoneARM32_t;
+
+
+	};
+
+	class DecodedOperandCapstoneARM64_t : public DecodedOperandCapstoneARM_t
+	{
+		public:
+			DecodedOperandCapstoneARM64_t() =delete;
+			virtual ~DecodedOperandCapstoneARM64_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:
+			DecodedOperandCapstoneARM64_t( const shared_ptr<void> &p_my_insn, uint8_t p_op_num);
+			friend class DecodedInstructionCapstoneARM64_t;
+	};
 }
diff --git a/irdb-libs/libIRDB-core/src/SConscript b/irdb-libs/libIRDB-core/src/SConscript
index 77ad98291c709b369b1fd1aad6de9c1dec1d5b12..8e67fe4f1c16b57fd27ecbb2c931535b5b98d458 100644
--- a/irdb-libs/libIRDB-core/src/SConscript
+++ b/irdb-libs/libIRDB-core/src/SConscript
@@ -25,8 +25,10 @@ files=  '''
 	reloc.cpp
 	decode_csx86.cpp
 	operand_csx86.cpp
-	decode_csarm.cpp
-	operand_csarm.cpp
+	decode_csarm32.cpp
+	decode_csarm64.cpp
+	operand_csarm32.cpp
+	operand_csarm64.cpp
 	IRDB_Objects.cpp
 	decode_base.cpp
 	transform_step.cpp
diff --git a/irdb-libs/libIRDB-core/src/decode_base.cpp b/irdb-libs/libIRDB-core/src/decode_base.cpp
index 25e996b556c895ec1755e67804667818d5d279c3..3790cc0e12245c9111455a5931127507bc593422 100644
--- a/irdb-libs/libIRDB-core/src/decode_base.cpp
+++ b/irdb-libs/libIRDB-core/src/decode_base.cpp
@@ -16,28 +16,31 @@ 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::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");
+	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) : 
+	          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::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");
+	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) : 
+	          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::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");
+	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) : 
+	          throw invalid_argument("Unknown machine type");
 	return unique_ptr<DecodedInstruction_t>(op);
 }
 
diff --git a/irdb-libs/libIRDB-core/src/decode_csarm32.cpp b/irdb-libs/libIRDB-core/src/decode_csarm32.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..90a5f2d16643fa1b922337f5c5b2d36985eca7b8
--- /dev/null
+++ b/irdb-libs/libIRDB-core/src/decode_csarm32.cpp
@@ -0,0 +1,338 @@
+
+#include <libIRDB-core.hpp>
+#include <decode_base.hpp>
+#include <decode_csarm.hpp>
+#include <operand_base.hpp>
+#include <operand_csarm.hpp>
+
+
+#include <capstone.h>
+#include <arm.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 arm_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 isArm32Jmp(cs_insn* the_insn) 
+{
+	return isPartOfGroup(the_insn,ARM_GRP_JUMP);
+}
+
+
+template<class type>
+static inline type arm32InsnToImmedHelper(cs_insn* the_insn, csh handle)
+{
+        const auto count = cs_op_count(handle, the_insn, ARM_OP_IMM);
+	const auto arm = &(the_insn->detail->arm);
+
+        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, ARM_OP_IMM, 1);
+		return arm->operands[index].imm;
+	}
+	else
+		throw std::logic_error(string("Called ")+__FUNCTION__+" with number of immedaites not equal 1");
+}
+
+
+
+// shared code 
+// constructors, destructors, operators.
+
+void DecodedInstructionCapstoneARM32_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->arm.operands[0]); // might change these.
+        auto &op1 = (insn->detail->arm.operands[1]);
+
+	const auto mnemonic=string(insn->mnemonic);
+	const auto is_ldr_type = mnemonic=="ldr"  || mnemonic=="ldrsw" ;
+	if(is_ldr_type && op1.type==ARM_OP_IMM)
+	{
+		// no, this is a pcrel load.
+		const auto imm=op1.imm;
+		op1.type=ARM_OP_MEM;
+		op1.mem.base=ARM_REG_PC;
+		op1.mem.index=ARM_REG_INVALID;
+		op1.mem.disp=imm;
+	}
+	if(mnemonic=="prfm" && op0.type==ARM_OP_IMM)
+	{
+		// no, this is a pcrel load.
+		const auto imm=op0.imm;
+		op0.type=ARM_OP_MEM;
+		op0.mem.base=ARM_REG_PC;
+		op0.mem.index=ARM_REG_INVALID;
+		op0.mem.disp=imm;
+	}
+
+
+	const auto cs_freer=[](cs_insn * insn) -> void 
+		{  
+			cs_free(insn,1); 
+		} ; 
+	my_insn.reset(insn,cs_freer);
+}
+
+DecodedInstructionCapstoneARM32_t::DecodedInstructionCapstoneARM32_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.");
+}
+
+DecodedInstructionCapstoneARM32_t::DecodedInstructionCapstoneARM32_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len)
+{
+        Disassemble(start_addr, data, max_len);
+}
+
+DecodedInstructionCapstoneARM32_t::DecodedInstructionCapstoneARM32_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);
+}
+
+DecodedInstructionCapstoneARM32_t::DecodedInstructionCapstoneARM32_t(const DecodedInstructionCapstoneARM32_t& copy)
+{
+	*this=copy;
+}
+
+DecodedInstructionCapstoneARM32_t::DecodedInstructionCapstoneARM32_t(const shared_ptr<void> &p_my_insn)
+{
+	my_insn = p_my_insn;
+}
+
+DecodedInstructionCapstoneARM32_t::~DecodedInstructionCapstoneARM32_t()
+{
+	// no need to cs_free(my_insn) because shared pointer will do that for us!
+}
+
+DecodedInstructionCapstoneARM32_t& DecodedInstructionCapstoneARM32_t::operator=(const DecodedInstructionCapstoneARM32_t& copy)
+{
+	my_insn=copy.my_insn;
+	return *this;
+}
+
+// public methods
+
+string DecodedInstructionCapstoneARM32_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 DecodedInstructionCapstoneARM32_t::valid() const
+{
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	return the_insn->size!=0;
+}
+
+uint32_t DecodedInstructionCapstoneARM32_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 DecodedInstructionCapstoneARM32_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() || isArm32Jmp(the_insn);
+}
+
+bool DecodedInstructionCapstoneARM32_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 DecodedInstructionCapstoneARM32_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 isArm32Jmp(the_insn) && 
+		(getMnemonic()=="b" || getMnemonic()=="br");
+}
+
+bool DecodedInstructionCapstoneARM32_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 isArm32Jmp(the_insn) && !isUnconditionalBranch();
+}
+
+bool DecodedInstructionCapstoneARM32_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);
+	const auto &arm      = the_insn->detail->arm;
+	const auto is_pop_pc = getMnemonic()=="pop" && arm.operands[arm.op_count-1].reg==ARM_REG_PC;
+
+	return is_pop_pc; // || other things?
+}
+
+bool DecodedInstructionCapstoneARM32_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 &arm = (the_insn->detail->arm);
+	return 0 <= op_num  && op_num < arm.op_count;
+}
+
+// 0-based.  first operand is numbered 0.
+shared_ptr<DecodedOperand_t> DecodedInstructionCapstoneARM32_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 DecodedOperandCapstoneARM32_t(my_insn,(uint8_t)op_num));
+	
+}
+
+DecodedOperandVector_t DecodedInstructionCapstoneARM32_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 &arm = (the_insn->detail->arm);
+	const auto opcount=arm.op_count;
+
+	auto ret_val=DecodedOperandVector_t();
+	
+	for(auto i=0;i<opcount;i++)
+		ret_val.push_back(getOperand(i));
+
+	return ret_val;
+}
+
+string DecodedInstructionCapstoneARM32_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 DecodedInstructionCapstoneARM32_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() || isArm32Jmp(the_insn))
+		return 0;
+
+	return arm32InsnToImmedHelper<int64_t>(the_insn, cs_handle->getHandle());
+}
+
+
+virtual_offset_t DecodedInstructionCapstoneARM32_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() || isArm32Jmp(the_insn))
+	{
+		const auto mnemonic=getMnemonic();
+		if( mnemonic=="tbnz" || mnemonic=="tbz")
+			return getOperand(2)->getConstant();
+		return arm32InsnToImmedHelper<int64_t>(the_insn, cs_handle->getHandle());
+	}
+	assert(0);
+
+}
+
+
+bool DecodedInstructionCapstoneARM32_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 &arm = (the_insn->detail->arm);
+	return (arm.operands[0].type==ARM_OP_REG && arm.operands[0].reg==ARM_REG_SP);
+}
+
+uint32_t DecodedInstructionCapstoneARM32_t::getPrefixCount() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	return 0;
+}
+
+IRDB_SDK::VirtualOffset_t DecodedInstructionCapstoneARM32_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 DecodedInstructionCapstoneARM32_t::hasRelevantRepPrefix() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	return false;
+}
+
+bool DecodedInstructionCapstoneARM32_t::hasRelevantRepnePrefix() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	return false;
+}
+
+bool DecodedInstructionCapstoneARM32_t::hasRelevantOperandSizePrefix() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	return false;
+}
+
+bool DecodedInstructionCapstoneARM32_t::hasRexWPrefix() const
+{
+	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	return false;
+}
+
+bool DecodedInstructionCapstoneARM32_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/decode_csarm.cpp b/irdb-libs/libIRDB-core/src/decode_csarm64.cpp
similarity index 91%
rename from irdb-libs/libIRDB-core/src/decode_csarm.cpp
rename to irdb-libs/libIRDB-core/src/decode_csarm64.cpp
index 497d92b2abdfc0f5d903baac223fc2e388b1253a..6cc43adc80b49ec128c01de5b949b41f24eb1894 100644
--- a/irdb-libs/libIRDB-core/src/decode_csarm.cpp
+++ b/irdb-libs/libIRDB-core/src/decode_csarm64.cpp
@@ -21,14 +21,18 @@ using namespace std;
 static const auto ARM64_REG_PC=(arm64_reg)(ARM64_REG_ENDING+1);
 
 
-DecodedInstructionCapstoneARM64_t::CapstoneHandle_t* DecodedInstructionCapstoneARM64_t::cs_handle=NULL ;
+DecodedInstructionCapstoneARM_t::CapstoneHandle_t* DecodedInstructionCapstoneARM_t::cs_handle=nullptr;
 
-DecodedInstructionCapstoneARM64_t::CapstoneHandle_t::CapstoneHandle_t(FileIR_t* firp)
+DecodedInstructionCapstoneARM_t::CapstoneHandle_t::CapstoneHandle_t(FileIR_t* firp)
 {
-	const auto mode = CS_MODE_LITTLE_ENDIAN;
 	static_assert(sizeof(csh)==sizeof(handle), "Capstone handle size is unexpected.  Has CS changed?");
-	auto err = cs_open(CS_ARCH_ARM64, mode,  (csh*)&handle);
 
+	const auto mode = CS_MODE_LITTLE_ENDIAN;
+	const auto arch = 
+		firp->getArchitectureBitWidth() == 64 ? CS_ARCH_ARM64 : 
+		firp->getArchitectureBitWidth() == 32 ? CS_ARCH_ARM   : 
+		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";
@@ -36,28 +40,21 @@ DecodedInstructionCapstoneARM64_t::CapstoneHandle_t::CapstoneHandle_t(FileIR_t*
 	}
 	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 arm64_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 isJmp(cs_insn* the_insn) 
+static bool isArm64Jmp(cs_insn* the_insn) 
 {
 	return isPartOfGroup(the_insn,ARM64_GRP_JUMP);
 }
 
-
 template<class type>
-static inline type insnToImmedHelper(cs_insn* the_insn, csh handle)
+static inline type arm64InsnToImmedHelper(cs_insn* the_insn, csh handle)
 {
         const auto count = cs_op_count(handle, the_insn, ARM64_OP_IMM);
 	const auto arm = &(the_insn->detail->arm64);
@@ -74,7 +71,6 @@ static inline type insnToImmedHelper(cs_insn* the_insn, csh handle)
 }
 
 
-
 // shared code 
 // constructors, destructors, operators.
 
@@ -123,7 +119,6 @@ void DecodedInstructionCapstoneARM64_t::Disassemble(const virtual_offset_t start
 
 DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const Instruction_t* i)
 {
-	if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL);
 	if(!i) throw std::invalid_argument("No instruction given to DecodedInstruction_t(Instruction_t*)");
 
         const auto length=i->getDataBits().size();
@@ -137,13 +132,11 @@ DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const Instr
 
 DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len)
 {
-	if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL);
         Disassemble(start_addr, data, max_len);
 }
 
 DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const virtual_offset_t start_addr, const void *data, const void* endptr)
 {
-	if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL);
         const auto length=(char*)endptr-(char*)data;
         Disassemble(start_addr,data,length);
 }
@@ -154,8 +147,8 @@ DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const Decod
 }
 
 DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const shared_ptr<void> &p_my_insn)
-	: my_insn(p_my_insn)
 {
+	my_insn = p_my_insn;
 }
 
 DecodedInstructionCapstoneARM64_t::~DecodedInstructionCapstoneARM64_t()
@@ -198,7 +191,7 @@ bool DecodedInstructionCapstoneARM64_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() || isJmp(the_insn);
+	return isCall() || isReturn() || isArm64Jmp(the_insn);
 }
 
 bool DecodedInstructionCapstoneARM64_t::isCall() const
@@ -214,7 +207,7 @@ bool DecodedInstructionCapstoneARM64_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 isJmp(the_insn) && 
+	return isArm64Jmp(the_insn) && 
 		(getMnemonic()=="b" || getMnemonic()=="br");
 }
 
@@ -222,7 +215,7 @@ bool DecodedInstructionCapstoneARM64_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 isJmp(the_insn) && !isUnconditionalBranch();
+	return isArm64Jmp(the_insn) && !isUnconditionalBranch();
 }
 
 bool DecodedInstructionCapstoneARM64_t::isReturn() const
@@ -284,10 +277,10 @@ int64_t DecodedInstructionCapstoneARM64_t::getImmediate() const
 	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() || isJmp(the_insn))
+	if(isCall() || isArm64Jmp(the_insn))
 		return 0;
 
-	return insnToImmedHelper<int64_t>(the_insn, cs_handle->getHandle());
+	return arm64InsnToImmedHelper<int64_t>(the_insn, cs_handle->getHandle());
 }
 
 
@@ -295,12 +288,12 @@ virtual_offset_t DecodedInstructionCapstoneARM64_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() || isJmp(the_insn))
+	if(isCall() || isArm64Jmp(the_insn))
 	{
 		const auto mnemonic=getMnemonic();
 		if( mnemonic=="tbnz" || mnemonic=="tbz")
 			return getOperand(2)->getConstant();
-		return insnToImmedHelper<int64_t>(the_insn, cs_handle->getHandle());
+		return arm64InsnToImmedHelper<int64_t>(the_insn, cs_handle->getHandle());
 	}
 	assert(0);
 
@@ -330,8 +323,6 @@ IRDB_SDK::VirtualOffset_t DecodedInstructionCapstoneARM64_t::getMemoryDisplaceme
 	assert(0);
 }
 
-
-
 bool DecodedInstructionCapstoneARM64_t::hasRelevantRepPrefix() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
diff --git a/irdb-libs/libIRDB-core/src/fileir.cpp b/irdb-libs/libIRDB-core/src/fileir.cpp
index 1921b8886e045239d9365ac71bf76564d8b5a0c4..1c15bd5895072a269dccf30cbb22ff4b3f47cd85 100644
--- a/irdb-libs/libIRDB-core/src/fileir.cpp
+++ b/irdb-libs/libIRDB-core/src/fileir.cpp
@@ -1109,39 +1109,26 @@ void FileIR_t::setArchitecture()
 	}
 	else if(is_elf)
 	{
-		switch(e_ident[4])
-		{
-			case ELFCLASS32:
-			{
-
-				if(hdr_union.ehdr32.e_type == ET_DYN)
-					libIRDB::FileIR_t::archdesc->setFileType(IRDB_SDK::adftELFSO);
-				else
-					libIRDB::FileIR_t::archdesc->setFileType(IRDB_SDK::adftELFEXE);
-				libIRDB::FileIR_t::archdesc->setBitWidth(32);
-				if(hdr_union.ehdr32.e_machine!=EM_386)
-					throw std::invalid_argument("Arch not supported.  32-bit archs supported:  I386");
-				libIRDB::FileIR_t::archdesc->setMachineType(IRDB_SDK::admtI386);
-				break;
-			}
-			case ELFCLASS64:
-			{
-				if(hdr_union.ehdr64.e_type == ET_DYN)
-					libIRDB::FileIR_t::archdesc->setFileType(IRDB_SDK::adftELFSO);
-				else
-					libIRDB::FileIR_t::archdesc->setFileType(IRDB_SDK::adftELFEXE);
-				libIRDB::FileIR_t::archdesc->setBitWidth(64);
-				const auto mt= 
-					hdr_union.ehdr64.e_machine==EM_AARCH64 ? IRDB_SDK::admtAarch64 : 
-					hdr_union.ehdr64.e_machine==EM_X86_64  ? IRDB_SDK::admtX86_64 : 
-					throw std::invalid_argument("Arch not supported.  64-bit archs supported:  Aarch64, X86-64");
-				libIRDB::FileIR_t::archdesc->setMachineType(mt);
-				break;
-			}
-			default:
-				cerr << "Unknown ELF class " <<endl;
-				exit(-1);
-		}
+		const auto bits = 
+			e_ident[4] == ELFCLASS32 ? 32 :
+			e_ident[4] == ELFCLASS64 ? 64 :
+			throw std::invalid_argument("Unknown ELF class");
+
+		const auto ft = 
+			hdr_union.ehdr32.e_type == ET_DYN  ?  IRDB_SDK::adftELFSO  :
+			hdr_union.ehdr32.e_type == ET_EXEC ?  IRDB_SDK::adftELFEXE :
+			throw std::invalid_argument("Unknown file type");
+
+		const auto mt = 
+			hdr_union.ehdr32.e_machine == EM_386     ? IRDB_SDK::admtI386    : 
+			hdr_union.ehdr32.e_machine == EM_ARM     ? IRDB_SDK::admtArm32   : 
+			hdr_union.ehdr64.e_machine == EM_AARCH64 ? IRDB_SDK::admtAarch64 : 
+			hdr_union.ehdr64.e_machine == EM_X86_64  ? IRDB_SDK::admtX86_64  : 
+			throw std::invalid_argument("Arch not supported.");
+
+		libIRDB::FileIR_t::archdesc->setFileType(ft);
+		libIRDB::FileIR_t::archdesc->setMachineType(mt);
+		libIRDB::FileIR_t::archdesc->setBitWidth(bits);
 	}
 }
 
diff --git a/irdb-libs/libIRDB-core/src/operand_csarm32.cpp b/irdb-libs/libIRDB-core/src/operand_csarm32.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..060e653a0c84f8845f5cc5ece969ca4249d76048
--- /dev/null
+++ b/irdb-libs/libIRDB-core/src/operand_csarm32.cpp
@@ -0,0 +1,376 @@
+
+#include <libIRDB-core.hpp>
+#include <memory>
+#include <decode_base.hpp>
+#include <decode_csarm.hpp>
+#include <operand_base.hpp>
+#include <operand_csarm.hpp>
+
+
+using namespace std;
+using namespace libIRDB;
+
+#include <capstone.h>
+
+DecodedOperandCapstoneARM32_t::DecodedOperandCapstoneARM32_t( const shared_ptr<void> & p_my_insn, uint8_t p_op_num)
+	: DecodedOperandCapstoneARM_t(p_my_insn,p_op_num)
+{
+	
+}
+
+DecodedOperandCapstoneARM32_t::~DecodedOperandCapstoneARM32_t()
+{
+}
+
+
+bool DecodedOperandCapstoneARM32_t::isConstant() const
+{
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm.operands[op_num]);
+	return op.type==ARM_OP_IMM;
+}
+
+uint64_t DecodedOperandCapstoneARM32_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->arm.operands[op_num]);
+	return op.imm;
+}
+
+string DecodedOperandCapstoneARM32_t::getString() const
+{
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm.operands[op_num]);
+        const auto handle=DecodedInstructionCapstoneARM32_t::cs_handle->getHandle();
+
+        switch(op.type)
+        {
+                case ARM_OP_REG:
+                        return string(cs_reg_name(handle, op.reg));
+                case ARM_OP_IMM:
+                        return to_string(op.imm);
+#if 0
+                case ARM_OP_MEM:
+                {
+			string ret_val;
+			if (op.mem.base != ARM_REG_INVALID)
+				ret_val+=cs_reg_name(handle, op.mem.base);
+
+			if (op.mem.index != ARM_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;
+		}
+#endif
+                default:
+                        assert(0);
+        }
+}
+
+bool DecodedOperandCapstoneARM32_t::isRegister() const
+{
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm.operands[op_num]);
+	return op.type==ARM_OP_REG;
+}
+
+bool DecodedOperandCapstoneARM32_t::isGeneralPurposeRegister() const
+{
+	const auto gp_regs=set<arm_reg>({
+		ARM_REG_R0,
+		ARM_REG_R1,
+		ARM_REG_R2,
+		ARM_REG_R3,
+		ARM_REG_R4,
+		ARM_REG_R5,
+		ARM_REG_R6,
+		ARM_REG_R7,
+		ARM_REG_R8,
+		ARM_REG_R9,
+		ARM_REG_R10,
+		ARM_REG_R11,
+		ARM_REG_R12,
+		ARM_REG_R13,
+		ARM_REG_R14,
+		ARM_REG_R15,
+		});
+
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm.operands[op_num]);
+        return isRegister() &&  gp_regs.find((arm_reg)op.reg)!=end(gp_regs);
+
+}
+
+bool DecodedOperandCapstoneARM32_t::isMmxRegister() const
+{
+	return false;
+}
+
+bool DecodedOperandCapstoneARM32_t::isFpuRegister() const
+{
+	const auto fpu_regs=set<arm_reg>({
+		ARM_REG_D0,
+		ARM_REG_D1,
+		ARM_REG_D2,
+		ARM_REG_D3,
+		ARM_REG_D4,
+		ARM_REG_D5,
+		ARM_REG_D6,
+		ARM_REG_D7,
+		ARM_REG_D8,
+		ARM_REG_D9,
+		ARM_REG_D10,
+		ARM_REG_D11,
+		ARM_REG_D12,
+		ARM_REG_D13,
+		ARM_REG_D14,
+		ARM_REG_D15,
+		ARM_REG_D16,
+		ARM_REG_D17,
+		ARM_REG_D18,
+		ARM_REG_D19,
+		ARM_REG_D20,
+		ARM_REG_D21,
+		ARM_REG_D22,
+		ARM_REG_D23,
+		ARM_REG_D24,
+		ARM_REG_D25,
+		ARM_REG_D26,
+		ARM_REG_D27,
+		ARM_REG_D28,
+		ARM_REG_D29,
+		ARM_REG_D30,
+		ARM_REG_D31,
+		ARM_REG_Q0,
+		ARM_REG_Q1,
+		ARM_REG_Q2,
+		ARM_REG_Q3,
+		ARM_REG_Q4,
+		ARM_REG_Q5,
+		ARM_REG_Q6,
+		ARM_REG_Q7,
+		ARM_REG_Q8,
+		ARM_REG_Q9,
+		ARM_REG_Q10,
+		ARM_REG_Q11,
+		ARM_REG_Q12,
+		ARM_REG_Q13,
+		ARM_REG_Q14,
+		ARM_REG_Q15,
+		ARM_REG_S1,
+		ARM_REG_S2,
+		ARM_REG_S3,
+		ARM_REG_S4,
+		ARM_REG_S5,
+		ARM_REG_S6,
+		ARM_REG_S7,
+		ARM_REG_S8,
+		ARM_REG_S9,
+		ARM_REG_S10,
+		ARM_REG_S11,
+		ARM_REG_S12,
+		ARM_REG_S13,
+		ARM_REG_S14,
+		ARM_REG_S15,
+		ARM_REG_S16,
+		ARM_REG_S17,
+		ARM_REG_S18,
+		ARM_REG_S19,
+		ARM_REG_S20,
+		ARM_REG_S21,
+		ARM_REG_S22,
+		ARM_REG_S23,
+		ARM_REG_S24,
+		ARM_REG_S25,
+		ARM_REG_S26,
+		ARM_REG_S27,
+		ARM_REG_S28,
+		ARM_REG_S29,
+		ARM_REG_S30,
+		ARM_REG_S31,
+		});
+
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm.operands[op_num]);
+        return isRegister() &&  fpu_regs.find((arm_reg)op.reg)!=end(fpu_regs);
+}
+
+bool DecodedOperandCapstoneARM32_t::isSseRegister() const
+{
+	return false;
+}
+
+bool DecodedOperandCapstoneARM32_t::isAvxRegister() const
+{
+	return false;
+}
+
+bool DecodedOperandCapstoneARM32_t::isZmmRegister() const
+{
+	return false;
+}
+
+bool DecodedOperandCapstoneARM32_t::isSpecialRegister() const
+{
+	const auto special_regs=set<arm_reg>({
+		ARM_REG_APSR,
+		ARM_REG_APSR_NZCV,
+		ARM_REG_CPSR,
+		ARM_REG_FPEXC,
+		ARM_REG_FPINST,
+		ARM_REG_FPSCR,
+		ARM_REG_FPSCR_NZCV,
+		ARM_REG_FPSID,
+		ARM_REG_ITSTATE,
+		ARM_REG_PC,
+		ARM_REG_SPSR,
+		ARM_REG_FPINST2,
+		ARM_REG_MVFR0,
+		ARM_REG_MVFR1,
+		ARM_REG_MVFR2,
+	});
+
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm.operands[op_num]);
+        return isRegister() &&  special_regs.find((arm_reg)op.reg)!=end(special_regs);
+	return false;
+}
+
+bool DecodedOperandCapstoneARM32_t::isSegmentRegister() const
+{
+	return false;
+}
+
+
+
+uint32_t DecodedOperandCapstoneARM32_t::getRegNumber() const
+{
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm.operands[op_num]);
+	return op.reg;
+}
+
+bool DecodedOperandCapstoneARM32_t::isMemory() const
+{
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm.operands[op_num]);
+        return op.type==ARM_OP_MEM;
+
+}
+
+bool DecodedOperandCapstoneARM32_t::hasBaseRegister() const
+{
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm.operands[op_num]);
+        return isMemory() && op.mem.base!=ARM_REG_INVALID;
+
+}
+
+bool DecodedOperandCapstoneARM32_t::hasIndexRegister() const
+{
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm.operands[op_num]);
+        return isMemory() && op.mem.index!=ARM_REG_INVALID;
+}
+
+uint32_t DecodedOperandCapstoneARM32_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->arm.operands[op_num]);
+        return op.mem.base;
+}
+
+uint32_t DecodedOperandCapstoneARM32_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->arm.operands[op_num]);
+        return op.mem.index;
+}
+
+uint32_t DecodedOperandCapstoneARM32_t::getScaleValue() const
+{
+	assert(0);
+}
+
+bool DecodedOperandCapstoneARM32_t::hasMemoryDisplacement() const
+{
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm.operands[op_num]);
+        return op.mem.disp!=0;
+
+} // end of DecodedOperandCapstoneARM32_t::hasMemoryDisplacement()
+
+virtual_offset_t DecodedOperandCapstoneARM32_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->arm.operands[op_num]);
+        return op.mem.disp;
+}
+
+bool DecodedOperandCapstoneARM32_t::isPcrel() const
+{
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm.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==ARM_REG_PC)
+		return true;
+
+	return isRegister() && getRegNumber()==ARM_REG_PC; // check to see if it's actually the pc
+
+}
+
+/* in bytes */
+uint32_t DecodedOperandCapstoneARM32_t::getMemoryDisplacementEncodingSize() const
+{
+	if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
+	assert(0);
+}
+
+uint32_t DecodedOperandCapstoneARM32_t::getArgumentSizeInBytes() const
+{
+	return false;
+}
+
+uint32_t DecodedOperandCapstoneARM32_t::getArgumentSizeInBits() const
+{
+        return getArgumentSizeInBytes()*8;
+}
+
+bool DecodedOperandCapstoneARM32_t::hasSegmentRegister() const
+{
+	return false;
+}
+
+uint32_t DecodedOperandCapstoneARM32_t::getSegmentRegister() const
+{
+	throw std::logic_error(string("Cannot ")+__FUNCTION__+"  on ARM architecture");
+}
+
+bool DecodedOperandCapstoneARM32_t::isRead() const
+{
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm.operands[op_num]);
+	return (op.access & CS_AC_READ)!=0;
+}
+
+bool DecodedOperandCapstoneARM32_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->arm.operands[op_num]);
+	return (op.access & CS_AC_WRITE)!=0;
+}
diff --git a/irdb-libs/libIRDB-core/src/operand_csarm.cpp b/irdb-libs/libIRDB-core/src/operand_csarm64.cpp
similarity index 82%
rename from irdb-libs/libIRDB-core/src/operand_csarm.cpp
rename to irdb-libs/libIRDB-core/src/operand_csarm64.cpp
index 01a20a17d5061ca3ed15f602c074ed6b06caeea2..d62c06645cee6abf4e101995c9398a508c35d41b 100644
--- a/irdb-libs/libIRDB-core/src/operand_csarm.cpp
+++ b/irdb-libs/libIRDB-core/src/operand_csarm64.cpp
@@ -15,9 +15,7 @@ static const auto ARM64_REG_PC=(arm64_reg)(ARM64_REG_ENDING+1);
 
 
 DecodedOperandCapstoneARM64_t::DecodedOperandCapstoneARM64_t( const shared_ptr<void> & p_my_insn, uint8_t p_op_num)
-	:
-	my_insn(p_my_insn),
-	op_num(p_op_num)
+	: DecodedOperandCapstoneARM_t(p_my_insn,p_op_num)
 {
 	
 }
@@ -91,13 +89,13 @@ bool DecodedOperandCapstoneARM64_t::isRegister() const
 bool DecodedOperandCapstoneARM64_t::isGeneralPurposeRegister() const
 {
 	const auto gp_regs=set<arm64_reg>({
-		ARM64_REG_X29, ARM64_REG_X30, ARM64_REG_SP, ARM64_REG_WSP, ARM64_REG_WZR, ARM64_REG_XZR,
-		ARM64_REG_W0, ARM64_REG_W1, ARM64_REG_W2, ARM64_REG_W3, ARM64_REG_W4, ARM64_REG_W5, ARM64_REG_W6, ARM64_REG_W7,
-        	ARM64_REG_W8, ARM64_REG_W9, ARM64_REG_W10, ARM64_REG_W11, ARM64_REG_W12, ARM64_REG_W13, ARM64_REG_W14, ARM64_REG_W15,
+		ARM64_REG_X29, ARM64_REG_X30, ARM64_REG_SP,  ARM64_REG_WSP, ARM64_REG_WZR, ARM64_REG_XZR,
+		ARM64_REG_W0,  ARM64_REG_W1,  ARM64_REG_W2,  ARM64_REG_W3,  ARM64_REG_W4,  ARM64_REG_W5,  ARM64_REG_W6,  ARM64_REG_W7,
+        	ARM64_REG_W8,  ARM64_REG_W9,  ARM64_REG_W10, ARM64_REG_W11, ARM64_REG_W12, ARM64_REG_W13, ARM64_REG_W14, ARM64_REG_W15,
         	ARM64_REG_W16, ARM64_REG_W17, ARM64_REG_W18, ARM64_REG_W19, ARM64_REG_W20, ARM64_REG_W21, ARM64_REG_W22, ARM64_REG_W23, 
 		ARM64_REG_W24, ARM64_REG_W25, ARM64_REG_W26, ARM64_REG_W27, ARM64_REG_W28, ARM64_REG_W29, ARM64_REG_W30, 
-		ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X4, ARM64_REG_X5, ARM64_REG_X6, ARM64_REG_X7,
-		ARM64_REG_X8, ARM64_REG_X9, ARM64_REG_X10, ARM64_REG_X11, ARM64_REG_X12, ARM64_REG_X13, ARM64_REG_X14, ARM64_REG_X15,
+		ARM64_REG_X0,  ARM64_REG_X1,  ARM64_REG_X2,  ARM64_REG_X3,  ARM64_REG_X4,  ARM64_REG_X5,  ARM64_REG_X6,  ARM64_REG_X7,
+		ARM64_REG_X8,  ARM64_REG_X9,  ARM64_REG_X10, ARM64_REG_X11, ARM64_REG_X12, ARM64_REG_X13, ARM64_REG_X14, ARM64_REG_X15,
 		ARM64_REG_X16, ARM64_REG_X17, ARM64_REG_X18, ARM64_REG_X19, ARM64_REG_X20, ARM64_REG_X21, ARM64_REG_X22, ARM64_REG_X23,
 		ARM64_REG_X24, ARM64_REG_X25, ARM64_REG_X26, ARM64_REG_X27, ARM64_REG_X28,
 	});
@@ -116,28 +114,28 @@ bool DecodedOperandCapstoneARM64_t::isMmxRegister() const
 bool DecodedOperandCapstoneARM64_t::isFpuRegister() const
 {
 	const auto fpu_regs=set<arm64_reg>({
-		ARM64_REG_B0, ARM64_REG_B1, ARM64_REG_B2, ARM64_REG_B3, ARM64_REG_B4, ARM64_REG_B5, ARM64_REG_B6, ARM64_REG_B7,
-        	ARM64_REG_B8, ARM64_REG_B9, ARM64_REG_B10, ARM64_REG_B11, ARM64_REG_B12, ARM64_REG_B13, ARM64_REG_B14, ARM64_REG_B15,
+		ARM64_REG_B0,  ARM64_REG_B1,  ARM64_REG_B2,  ARM64_REG_B3,  ARM64_REG_B4,  ARM64_REG_B5,  ARM64_REG_B6,  ARM64_REG_B7,
+        	ARM64_REG_B8,  ARM64_REG_B9,  ARM64_REG_B10, ARM64_REG_B11, ARM64_REG_B12, ARM64_REG_B13, ARM64_REG_B14, ARM64_REG_B15,
         	ARM64_REG_B16, ARM64_REG_B17, ARM64_REG_B18, ARM64_REG_B19, ARM64_REG_B20, ARM64_REG_B21, ARM64_REG_B22, ARM64_REG_B23,
         	ARM64_REG_B24, ARM64_REG_B25, ARM64_REG_B26, ARM64_REG_B27, ARM64_REG_B28, ARM64_REG_B29, ARM64_REG_B30, ARM64_REG_B31,
-		ARM64_REG_H0, ARM64_REG_H1, ARM64_REG_H2, ARM64_REG_H3, ARM64_REG_H4, ARM64_REG_H5, ARM64_REG_H6, ARM64_REG_H7, 
-		ARM64_REG_H8, ARM64_REG_H9, ARM64_REG_H10, ARM64_REG_H11, ARM64_REG_H12, ARM64_REG_H13, ARM64_REG_H14, ARM64_REG_H15, 
+		ARM64_REG_H0,  ARM64_REG_H1,  ARM64_REG_H2,  ARM64_REG_H3,  ARM64_REG_H4,  ARM64_REG_H5,  ARM64_REG_H6,  ARM64_REG_H7, 
+		ARM64_REG_H8,  ARM64_REG_H9,  ARM64_REG_H10, ARM64_REG_H11, ARM64_REG_H12, ARM64_REG_H13, ARM64_REG_H14, ARM64_REG_H15, 
 		ARM64_REG_H16, ARM64_REG_H17, ARM64_REG_H18, ARM64_REG_H19, ARM64_REG_H20, ARM64_REG_H21, ARM64_REG_H22, ARM64_REG_H23, 
 		ARM64_REG_H24, ARM64_REG_H25, ARM64_REG_H26, ARM64_REG_H27, ARM64_REG_H28, ARM64_REG_H29, ARM64_REG_H30, ARM64_REG_H31, 
-	        ARM64_REG_D0, ARM64_REG_D1, ARM64_REG_D2, ARM64_REG_D3, ARM64_REG_D4, ARM64_REG_D5, ARM64_REG_D6, ARM64_REG_D7,
-        	ARM64_REG_D8, ARM64_REG_D9, ARM64_REG_D10, ARM64_REG_D11, ARM64_REG_D12, ARM64_REG_D13, ARM64_REG_D14, ARM64_REG_D15,
+	        ARM64_REG_D0,  ARM64_REG_D1,  ARM64_REG_D2,  ARM64_REG_D3,  ARM64_REG_D4,  ARM64_REG_D5,  ARM64_REG_D6,  ARM64_REG_D7,
+        	ARM64_REG_D8,  ARM64_REG_D9,  ARM64_REG_D10, ARM64_REG_D11, ARM64_REG_D12, ARM64_REG_D13, ARM64_REG_D14, ARM64_REG_D15,
 		ARM64_REG_D16, ARM64_REG_D17, ARM64_REG_D18, ARM64_REG_D19, ARM64_REG_D20, ARM64_REG_D21, ARM64_REG_D22, ARM64_REG_D23,
 		ARM64_REG_D24, ARM64_REG_D25, ARM64_REG_D26, ARM64_REG_D27, ARM64_REG_D28, ARM64_REG_D29, ARM64_REG_D30, ARM64_REG_D31,
-	        ARM64_REG_H0, ARM64_REG_H1, ARM64_REG_H2, ARM64_REG_H3, ARM64_REG_H4, ARM64_REG_H5, ARM64_REG_H6, ARM64_REG_H7,
-		ARM64_REG_H8, ARM64_REG_H9, ARM64_REG_H10, ARM64_REG_H11, ARM64_REG_H12, ARM64_REG_H13, ARM64_REG_H14, ARM64_REG_H15,
+	        ARM64_REG_H0,  ARM64_REG_H1,  ARM64_REG_H2,  ARM64_REG_H3,  ARM64_REG_H4,  ARM64_REG_H5,  ARM64_REG_H6,  ARM64_REG_H7,
+		ARM64_REG_H8,  ARM64_REG_H9,  ARM64_REG_H10, ARM64_REG_H11, ARM64_REG_H12, ARM64_REG_H13, ARM64_REG_H14, ARM64_REG_H15,
 		ARM64_REG_H16, ARM64_REG_H17, ARM64_REG_H18, ARM64_REG_H19, ARM64_REG_H20, ARM64_REG_H21, ARM64_REG_H22, ARM64_REG_H23,
 		ARM64_REG_H24, ARM64_REG_H25, ARM64_REG_H26, ARM64_REG_H27, ARM64_REG_H28, ARM64_REG_H29, ARM64_REG_H30, ARM64_REG_H31,
-	        ARM64_REG_Q0, ARM64_REG_Q1, ARM64_REG_Q2, ARM64_REG_Q3, ARM64_REG_Q4, ARM64_REG_Q5, ARM64_REG_Q6, ARM64_REG_Q7,
-		ARM64_REG_Q8, ARM64_REG_Q9, ARM64_REG_Q10, ARM64_REG_Q11, ARM64_REG_Q12, ARM64_REG_Q13, ARM64_REG_Q14, ARM64_REG_Q15,
+	        ARM64_REG_Q0,  ARM64_REG_Q1,  ARM64_REG_Q2,  ARM64_REG_Q3,  ARM64_REG_Q4,  ARM64_REG_Q5,  ARM64_REG_Q6,  ARM64_REG_Q7,
+		ARM64_REG_Q8,  ARM64_REG_Q9,  ARM64_REG_Q10, ARM64_REG_Q11, ARM64_REG_Q12, ARM64_REG_Q13, ARM64_REG_Q14, ARM64_REG_Q15,
 		ARM64_REG_Q16, ARM64_REG_Q17, ARM64_REG_Q18, ARM64_REG_Q19, ARM64_REG_Q20, ARM64_REG_Q21, ARM64_REG_Q22, ARM64_REG_Q23,
 		ARM64_REG_Q24, ARM64_REG_Q25, ARM64_REG_Q26, ARM64_REG_Q27, ARM64_REG_Q28, ARM64_REG_Q29, ARM64_REG_Q30, ARM64_REG_Q31,
-		ARM64_REG_S0, ARM64_REG_S1, ARM64_REG_S2, ARM64_REG_S3, ARM64_REG_S4, ARM64_REG_S5, ARM64_REG_S6, ARM64_REG_S7,
-		ARM64_REG_S8, ARM64_REG_S9, ARM64_REG_S10, ARM64_REG_S11, ARM64_REG_S12, ARM64_REG_S13, ARM64_REG_S14, ARM64_REG_S15,
+		ARM64_REG_S0,  ARM64_REG_S1,  ARM64_REG_S2,  ARM64_REG_S3,  ARM64_REG_S4,  ARM64_REG_S5,  ARM64_REG_S6,  ARM64_REG_S7,
+		ARM64_REG_S8,  ARM64_REG_S9,  ARM64_REG_S10, ARM64_REG_S11, ARM64_REG_S12, ARM64_REG_S13, ARM64_REG_S14, ARM64_REG_S15,
 		ARM64_REG_S16, ARM64_REG_S17, ARM64_REG_S18, ARM64_REG_S19, ARM64_REG_S20, ARM64_REG_S21, ARM64_REG_S22, ARM64_REG_S23,
 		ARM64_REG_S24, ARM64_REG_S25, ARM64_REG_S26, ARM64_REG_S27, ARM64_REG_S28, ARM64_REG_S29, ARM64_REG_S30, ARM64_REG_S31,
 	});
diff --git a/irdb-libs/meds2pdb/elfreader.cpp b/irdb-libs/meds2pdb/elfreader.cpp
index 51f10cecea32d236fba283975abc44cf1b47f029..7c5f8ae323275eb59e5075fc687a2aedac26aa55 100644
--- a/irdb-libs/meds2pdb/elfreader.cpp
+++ b/irdb-libs/meds2pdb/elfreader.cpp
@@ -147,9 +147,10 @@ void ElfReader::SetArchitecture()
 		(isElf32() || isPe32()) ? 32 :
 		(isElf64() || isPe64()) ? 64 :
 		throw std::invalid_argument("Unknown architecture.");
-	const auto mt = m_reader->getMachineType() == EXEIO::mtI386 ? IRDB_SDK::admtI386 :
-			m_reader->getMachineType() == EXEIO::mtX86_64 ? IRDB_SDK::admtX86_64 :
+	const auto mt = m_reader->getMachineType() == EXEIO::mtI386    ? IRDB_SDK::admtI386    :
+			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   :
 			throw std::invalid_argument("Unknown architecture.");
 
 	libIRDB::FileIR_t::setArchitecture(width,mt);
diff --git a/irdb-libs/meds2pdb/elfreader.h b/irdb-libs/meds2pdb/elfreader.h
index 87b4ac4a71b303008e96b265d1885f5828c49804..57dc8dcdee8cb82075695c2d4d83459dacd869c9 100644
--- a/irdb-libs/meds2pdb/elfreader.h
+++ b/irdb-libs/meds2pdb/elfreader.h
@@ -26,8 +26,8 @@ class ElfReader
 
 	bool isElf32() const { assert(m_reader); return m_reader->get_class()==EXEIO::ELF32; }
 	bool isElf64() const { assert(m_reader); return m_reader->get_class()==EXEIO::ELF64; }
-	bool isPe32() const { assert(m_reader); return m_reader->get_class()==EXEIO::PE32; }
-	bool isPe64() const { assert(m_reader); return m_reader->get_class()==EXEIO::PE64; }
+	bool isPe32()  const { assert(m_reader); return m_reader->get_class()==EXEIO::PE32 ; }
+	bool isPe64()  const { assert(m_reader); return m_reader->get_class()==EXEIO::PE64 ; }
 	void SetArchitecture() ;
 
   	private:
diff --git a/irdb-sdk b/irdb-sdk
index def6b85b0854879bd6ed47483f86bfe701b53513..51477757faf6117452a9965d524481652a0a1651 160000
--- a/irdb-sdk
+++ b/irdb-sdk
@@ -1 +1 @@
-Subproject commit def6b85b0854879bd6ed47483f86bfe701b53513
+Subproject commit 51477757faf6117452a9965d524481652a0a1651
diff --git a/zipr b/zipr
index 7dd13a74121ee1c44b6fa35d639b8ff2e3a6a2ae..3e3fe7626e861f3e01ed4f56e35ef1a8c4ce5a3d 160000
--- a/zipr
+++ b/zipr
@@ -1 +1 @@
-Subproject commit 7dd13a74121ee1c44b6fa35d639b8ff2e3a6a2ae
+Subproject commit 3e3fe7626e861f3e01ed4f56e35ef1a8c4ce5a3d
diff --git a/zipr_unpin_plugin b/zipr_unpin_plugin
index 59b7b90668bda12f5af1e302df4e8c906aaa2188..8fab1d723980c174a72d9eacdb6e9592a658d4d8 160000
--- a/zipr_unpin_plugin
+++ b/zipr_unpin_plugin
@@ -1 +1 @@
-Subproject commit 59b7b90668bda12f5af1e302df4e8c906aaa2188
+Subproject commit 8fab1d723980c174a72d9eacdb6e9592a658d4d8