From d0026690bae4882e187d7993f6e4dfe45c388c4e Mon Sep 17 00:00:00 2001
From: jdh8d <jdh8d@git.zephyr-software.com>
Date: Thu, 30 Jul 2015 15:11:07 +0000
Subject: [PATCH] Former-commit-id: 6c33a4a79c51108d10ffccf1b0986e8fcd14a020

---
 include/interfaces/irdb/STARSOp.h | 138 +++++++++++++++++++++---------
 src/base/SMPFunction.cpp          |   2 +-
 2 files changed, 98 insertions(+), 42 deletions(-)

diff --git a/include/interfaces/irdb/STARSOp.h b/include/interfaces/irdb/STARSOp.h
index dc698107..b685b09e 100644
--- a/include/interfaces/irdb/STARSOp.h
+++ b/include/interfaces/irdb/STARSOp.h
@@ -19,19 +19,25 @@ class STARS_IRDB_op_t : public STARS_op_t
 	public:
 		
 		// Constructors
-		STARS_IRDB_op_t() { assert(0); }
-		STARS_IRDB_op_t(const DISASM &d, int indx, const ARGTYPE &the_arg) 
-			: disasm(d), index(indx), arg(the_arg) {  }
+		STARS_IRDB_op_t() { Init(); }
+		STARS_IRDB_op_t(const DISASM &d, int indx, const ARGTYPE &the_arg);
+	
+
 
 		// Clone method (deep copy).
 		virtual STARSOpndTypePtr clone(void) const 
 		{ 
-			STARSOpndTypePtr p=std::make_shared<STARS_IRDB_op_t>(disasm,0,arg);
+			std::shared_ptr<STARS_IRDB_op_t> p=std::make_shared<STARS_IRDB_op_t>();
+			p->SegReg=SegReg;
+			p->byteWidth=byteWidth;
+			p->OpType=OpType;
+			p->operand=operand;
+			p->visible=visible;
 			return p;
 		}
 
 		// Operators
-		virtual bool operator<(const STARS_op_t &rOp) const { assert(0); } // Less-than operator for use in STL ordered containers, e.g. sets.
+		virtual bool operator<(const STARS_op_t &rOp) const;  // Less-than operator for use in STL ordered containers, e.g. sets.
 
 		// Get methods
 
@@ -65,7 +71,7 @@ class STARS_IRDB_op_t : public STARS_op_t
 		// mov xmm0, [mem]	==> return STARS_o_xmmreg, STARS_o_phrase
 		// mov ymm0, [mem]	==> return o_ymmreg, o_phrase
 		// also see intel.hpp:56 for o_trreg, o_crreg, o_dbreg, o_fpreg.
-		virtual unsigned char GetOpType(void) const { assert(0); } // Get type o_reg, o_displ, etc.
+		virtual unsigned char GetOpType(void) const { return OpType; } // Get type o_reg, o_displ, etc.
 
 		
 		// STARS_x86_R_al
@@ -92,61 +98,70 @@ class STARS_IRDB_op_t : public STARS_op_t
 		// clc to investigate removing need for this function in base class
 		// probably will still use in STARS_IDA_Op_t.
 		virtual char GetSpecFlag4(void) const { assert(0); } // Get specflag4 byte, used to hold a copy of the auxpref byte in x86-64 programs.
-		virtual STARS_uval_t GetImmedValue(void) const { assert(0); } // Get value field for immediate operands; uint32 for x86-32, uint64 for x86-64
+
+		// Get value field for immediate operands; uint32 for x86-32, uint64 for x86-64
+		virtual STARS_uval_t GetImmedValue(void) const { assert(OpType==op_Imm);  return operand.imm.imm; } 
 
 		// return STARS_dt_byte, etc.
 		// see STARSTypes.h:112
 		// probably don't need it.
-		virtual char GetOpDtyp(void) const { assert(0); }  // Get field that determines byte width
+		virtual char GetOpDtyp(void) const { return OpType; }  // Get field that determines byte width
 
 		// return 1, 2, 4, 8, 16, etc.
-		virtual uint16_t GetByteWidth(void) const { assert(0); }
+		virtual uint16_t GetByteWidth(void) const { assert(OpType!=op_Void); return byteWidth; }
 
 		// Set methods
-		virtual void SetByteWidth(uint16_t ByteWidth) { assert(0); } // Change default byte width of opnd
-		virtual void DoubleRegWidth(void) { assert(0); } // Double the width of opnd if it is a subword register
+		virtual void SetByteWidth(uint16_t ByteWidth) { assert(OpType!=op_Void); byteWidth=ByteWidth; } // Change default byte width of opnd
+		virtual void DoubleRegWidth(void) { assert(OpType!=op_Void); byteWidth*=2; } // Double the width of opnd if it is a subword register
+
+		// where's this come from?
 		virtual void SetOpGlobalIndex(std::size_t index) { assert(0); } // Set STARS SSA name index.
-		virtual void SetReg(uint16_t NewReg) { assert(0); }
-		virtual void SetAddr(STARS_ea_t NewAddr) { assert(0); }
-		virtual void SetSIB(char value) { assert(0); }
+
+		virtual void SetReg(uint16_t NewReg) { assert(OpType==op_Reg); operand.reg.RegNum=(STARS_RegNo)NewReg; }
+		virtual void SetAddr(STARS_ea_t NewAddr) { assert(OpType==op_Mem); operand.mem.disp=NewAddr; }
+		virtual void SetSIB(char value) { assert(OpType==op_Mem); operand.mem.sib_byte=value;  operand.mem.hasSIB=true; }
+
+		// clc to review, going away?
 		virtual void SetSpecFlag4(char value) { assert(0); }
 		virtual void SetBitInSpecFlag4(char value) { assert(0); } // OR in the value to set a bit
-		virtual void SetNotVisible(void) { assert(0); } // Set operand to type that is implicit, not explicit in disasm
-		virtual void SetTypeToMemDisplacement(void) { assert(0); } // change type during stack normalization
+
+		
+		virtual void SetNotVisible(void) { assert(OpType!=op_Void); visible=0; } // Set operand to type that is implicit, not explicit in disasm
+		virtual void SetTypeToMemDisplacement(void) { Init(); OpType=op_Mem; } // change type during stack normalization
 
 		// Query methods
-		virtual bool IsVisible(void) const { assert(0); }  // Operand appears in disasm, vs. being implicit, e.g. "imul ecx" also has eax opnd
-		virtual bool IsRegOp(void) const { assert(0); }
-		virtual bool IsImmedOp(void) const { assert(0); }
-		virtual bool IsVoidOp(void) const { assert(0); }
-		virtual bool IsMemDisplacementOp(void) const { assert(0); }
-		virtual bool IsStaticMemOp(void) const { assert(0); }
-		virtual bool IsMemNoDisplacementOp(void) const { assert(0); }
-		virtual bool IsMemOp(void) const { assert(0); }  // any of the previous three types
-		virtual bool HasSIBByte(void) const { assert(0); }
-		virtual bool IsFloatingPointRegOp(void) const { assert(0); }
-		virtual bool IsMMXRegOp(void) const { assert(0); }
-		virtual bool IsXMMRegOp(void) const { assert(0); }
-		virtual bool IsYMMRegOp(void) const { assert(0); }
+		virtual bool IsVisible(void) const { assert(OpType!=op_Void); return visible; }
+		virtual bool IsRegOp(void) const { return OpType==op_Reg; }
+		virtual bool IsImmedOp(void) const { return OpType==op_Imm; }
+		virtual bool IsVoidOp(void) const { return OpType==op_Void; }
+		virtual bool IsMemDisplacementOp(void) const { return OpType==op_Mem && operand.mem.disp!=0; }
+		virtual bool IsStaticMemOp(void) const { return OpType==op_Mem && operand.mem.base==STARS_x86_R_none && operand.mem.index==STARS_x86_R_none; }
+		virtual bool IsMemNoDisplacementOp(void) const { return OpType==op_Mem && operand.mem.disp==0; }
+		virtual bool IsMemOp(void) const { return OpType==op_Mem; } 
+		virtual bool HasSIBByte(void) const { assert(OpType==op_Mem); return operand.mem.hasSIB; }
+		virtual bool IsFloatingPointRegOp(void) const { assert(OpType==op_Reg);  return STARS_x86_R_st0<= operand.reg.RegNum && operand.reg.RegNum<=STARS_x86_R_st7; }
+		virtual bool IsMMXRegOp(void) const { assert(OpType==op_Reg);  return STARS_x86_R_mm0<= operand.reg.RegNum && operand.reg.RegNum<=STARS_x86_R_mm7; }
+		virtual bool IsXMMRegOp(void) const { assert(OpType==op_Reg);  return STARS_x86_R_xmm0<= operand.reg.RegNum && operand.reg.RegNum<=STARS_x86_R_xmm15; }
+		virtual bool IsYMMRegOp(void) const { assert(OpType==op_Reg);  return STARS_x86_R_ymm0<= operand.reg.RegNum && operand.reg.RegNum<=STARS_x86_R_ymm15; }
 		virtual bool IsTestRegOp(void) const { assert(0); }
 		virtual bool IsDebugRegOp(void) const { assert(0); }
 		virtual bool IsControlRegOp(void) const { assert(0); }
-		virtual bool MDIsKnownOpType(void) const { assert(0); }
+		virtual bool MDIsKnownOpType(void) const { return OpType!=op_Void; }
 		virtual bool MDIsSpecialRegOpType(void) const { assert(0); }  // special debug reg, control or task reg, MMX/XMM/YMM registers
-		virtual bool MatchesReg(uint16_t RegNum) const { assert(0); }
+		virtual bool MatchesReg(uint16_t RegNum) const { assert(OpType==op_Reg); return RegNum == operand.reg.RegNum; }
 		virtual bool IsNearPointer(void) const { assert(0); }
 		virtual bool IsFarPointer(void) const { assert(0); }
 		virtual bool HasSegReg(void) const { assert(0); } // Has a segment register
 
 
 // conversion of op to new type
-                virtual void MakeVoidOpnd(void)  { memset(&arg,0,sizeof(arg)); }
-                virtual void MakeImmediateOpnd(STARS_uval_t value)  { assert(0); }
-                virtual void MakeRegOpnd(uint16_t RegNum)  { assert(0); }
-                virtual void MakeFloatingPointRegOpnd(uint16_t RegNum)  { assert(0); }
-                virtual void MakeMMXRegOpnd(uint16_t RegNum)  { assert(0); }
-                virtual void MakeXMMRegOpnd(uint16_t RegNum)  { assert(0); }
-                virtual void MakeYMMRegOpnd(uint16_t RegNum)  { assert(0); }
+                virtual void MakeVoidOpnd(void)  { Init(); }
+                virtual void MakeImmediateOpnd(STARS_uval_t value)  { Init(); OpType=op_Imm; operand.imm.imm=value; }
+                virtual void MakeRegOpnd(uint16_t RegNum)  { Init(); OpType=op_Reg; operand.reg.RegNum=(STARS_RegNo)RegNum; }
+                virtual void MakeFloatingPointRegOpnd(uint16_t RegNum)  { Init(); OpType=op_FPReg; operand.reg.RegNum=(STARS_RegNo)RegNum; }
+                virtual void MakeMMXRegOpnd(uint16_t RegNum)  { Init(); OpType=op_MMXReg; operand.reg.RegNum=(STARS_RegNo)RegNum; }
+                virtual void MakeXMMRegOpnd(uint16_t RegNum)  { Init(); OpType=op_XMMReg; operand.reg.RegNum=(STARS_RegNo)RegNum; }
+                virtual void MakeYMMRegOpnd(uint16_t RegNum)  { Init(); OpType=op_YMMReg; operand.reg.RegNum=(STARS_RegNo)RegNum; }
                 virtual void MakeMemDisplacementOpnd(uint16_t BaseRegNum, 
                         uint16_t IndexRegNum, uint16_t ScaleFactor, STARS_ea_t offset)  { assert(0); }
                 virtual void MakeMemPhraseOpnd(uint16_t BaseRegNum, 
@@ -154,9 +169,50 @@ class STARS_IRDB_op_t : public STARS_op_t
 
 
 	private:
-		DISASM disasm;
-		ARGTYPE arg;
-		int index;
+
+		STARS_RegNo SegReg;
+		int byteWidth;
+
+		enum OperandType_t { op_Reg, op_Mem, op_Imm, op_Void, op_CrReg, op_DrReg, op_Eflags, op_MMXReg, op_XMMReg, op_YMMReg, op_FPReg, op_Mxcsr, op_SegReg } OpType;
+		union 
+		{
+			struct 
+			{
+				STARS_RegNo RegNum;
+			} reg;
+			struct 
+			{
+				STARS_RegNo base;
+				STARS_RegNo index;
+				int scale:2;	
+				libIRDB::virtual_offset_t disp;	// may be 64-bit imm in some x86-64 instructions.
+				bool hasSIB:1;
+				unsigned char sib_byte;
+			} mem;
+			struct 
+			{
+				libIRDB::virtual_offset_t imm;	// may be 64-bit imm in some x86-64 instructions.
+				bool pc_rel;			// may be pcrel immediate in some cases.
+			} imm;
+	
+		
+		} operand;
+		bool visible;
+
+
+		void Init() 
+		{ 
+			SegReg=STARS_x86_R_none;
+			OpType=op_Void;
+
+			// init the operand to 0, because the it should have no semantically valid meaning in any sense anyhow if OpType==Void.
+			memset(&operand,0,sizeof(operand));
+
+			visible=0;
+			byteWidth=0;
+		}
+
+			
 
 };
 
diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp
index be965ce8..dc6d99c3 100644
--- a/src/base/SMPFunction.cpp
+++ b/src/base/SMPFunction.cpp
@@ -152,7 +152,7 @@ SMPFunction::SMPFunction(STARS_Function_t *Info, SMPProgram* pgm) {
 	this->IndirectJumps = false;
 	this->UnresolvedIndirectJumps = false;
 	this->DirectlyRecursive = false;
-	this->SetSharedChunks(false);
+//	this->SetSharedChunks(false);
 	this->UnsharedChunks = false;
 	this->MultipleEntryPoints = false;
 	this->CallsAlloca = false;
-- 
GitLab