From d3b22c2c9c0df0ce002e1ec7256739cf6078897b Mon Sep 17 00:00:00 2001
From: clc5q <clc5q@git.zephyr-software.com>
Date: Mon, 5 May 2008 23:42:48 +0000
Subject: [PATCH] Emit optimizing annotations for ADD/SUB instructions with
 NUMERIC source operand.

---
 SMPInstr.cpp   | 57 +++++++++++++++++++++++++++++++++++++++++++-------
 SMPInstr.h     |  2 ++
 SMPProgram.cpp |  2 +-
 3 files changed, 52 insertions(+), 9 deletions(-)

diff --git a/SMPInstr.cpp b/SMPInstr.cpp
index 8abcc4a8..b6a770c9 100644
--- a/SMPInstr.cpp
+++ b/SMPInstr.cpp
@@ -202,6 +202,7 @@ SMPInstr::SMPInstr(ea_t addr) {
 	this->UsesFlags = false;
 	this->TypeInferenceComplete = false;
 	this->CategoryInference = false;
+	this->AddSubSourceType = UNINIT;
 	this->BasicBlock = NULL;
 	return;
 }
@@ -261,6 +262,35 @@ bool SMPInstr::IsSecondSrcOperandNumeric(flags_t F) const {
 	return (SecondOpImm && IsImmedNumeric(TempImm));
 } // end of SMPInstr::IsSecondSrcOperandNumeric()
 
+// Determine the type of the USE-only operand for add and subtract
+//  instructions. If it is NUMERIC or PROF_NUMERIC, an optimizing
+//  annotation will result.
+void SMPInstr::SetAddSubSourceType(void) {
+	set<DefOrUse, LessDefUse>::iterator UseIter, DefIter;
+
+	// First, ensure that we are dealing with a register source.
+	if (this->HasSourceMemoryOperand()) {
+		this->AddSubSourceType = UNINIT;
+		return;
+	}
+
+	// The USE and DEF lists will have the flags and the destination
+	//  operand in common for adds and subtracts. The USE-only operand
+	//  is the one we are concerned with.
+	for (UseIter = this->GetFirstUse(); UseIter != this->GetLastUse(); ++UseIter) {
+		if (this->GetLastDef() == this->FindDef(UseIter->GetOp())) {
+			// Found the USE that is not a DEF
+			this->AddSubSourceType = UseIter->GetType();
+#if SMP_VERBOSE_DEBUG_INFER_TYPES
+			msg("Set AddSubSourceType to %d at %x: %s\n", UseIter->GetType(),
+				this->address, this->GetDisasm());
+#endif
+			break;
+		}
+	}
+	return;
+} // end of SMPInstr::SetAddSubSourceType()
+
 // Are all DEFs in the DEF set NUMERIC type?
 bool SMPInstr::AllDefsNumeric(void) {
 	bool AllNumeric = (this->Defs.GetSize() > 0);  // false if no DEFs, true otherwise
@@ -1391,8 +1421,6 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) {
 		case SMP_ROTATE_LEFT_CARRY: // rotate left through carry
 		case SMP_ROTATE_RIGHT:
 		case SMP_ROTATE_RIGHT_CARRY: // rotate right through carry
-		case SMP_ADD_CARRY:   // add with carry
-		case SMP_SUBTRACT_BORROW:  // subtract with borrow
 		case SMP_U_MULTIPLY:
 		case SMP_S_MULTIPLY:
 		case SMP_U_DIVIDE:
@@ -1491,6 +1519,7 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) {
 			break;
 
 		case SMP_ADD:
+		case SMP_ADD_CARRY:   // add with carry
 		case SMP_BITWISE_AND:
 		case SMP_BITWISE_OR:
 			// Extract the current types of right and left operands and the operator.
@@ -1548,12 +1577,14 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) {
 				else if (LeftNumeric || RightNumeric) {
 					// ADD of NUMERIC to non-NUMERIC preserves non-NUMERIC type.
 					// AND and OR operations should leave the operator UNINIT for now.
-					if (LeftNumeric && (UNINIT != RightType) && (SMP_ADD == CurrOp)) {
+					if (LeftNumeric && (UNINIT != RightType) 
+						&& ((SMP_ADD == CurrOp) || (SMP_ADD_CARRY == CurrOp))) {
 						CurrRT->SetOperatorType(RightType);
 						updated = true;
 						break;
 					}
-					else if (RightNumeric && (UNINIT != LeftType) && (SMP_ADD == CurrOp)) {
+					else if (RightNumeric && (UNINIT != LeftType) 
+						&& ((SMP_ADD == CurrOp) || (SMP_ADD_CARRY == CurrOp))) {
 						CurrRT->SetOperatorType(LeftType);
 						updated = true;
 						break;
@@ -1561,7 +1592,7 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) {
 				}
 				else if (LeftPointer && RightPointer) {
 					// Arithmetic on two pointers
-					if (SMP_ADD == CurrOp) {
+					if ((SMP_ADD == CurrOp) || (SMP_ADD_CARRY == CurrOp)) {
 						CurrRT->SetOperatorType(UNKNOWN);
 						updated = true;
 					}
@@ -1575,7 +1606,7 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) {
 				else if ((LeftPointer && IsEqType(RightType, PTROFFSET))
 					|| (RightPointer && IsEqType(LeftType, PTROFFSET))) {
 					// Arithmetic on PTR and PTROFFSET
-					if (SMP_ADD == CurrOp) {
+					if ((SMP_ADD == CurrOp) || (SMP_ADD_CARRY == CurrOp)) {
 						// We assume (A-B) is being added to B or vice versa **!!**
 						CurrRT->SetOperatorType(POINTER);
 						updated = true;
@@ -1617,6 +1648,7 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) {
 			break;
 
 		case SMP_SUBTRACT:
+		case SMP_SUBTRACT_BORROW:  // subtract with borrow
 			// Extract the current types of right and left operands and the operator.
 			OperType = CurrRT->GetOperatorType();
 			LeftOp = CurrRT->GetLeftOperand();
@@ -1662,6 +1694,7 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) {
 					msg("ERROR: SMP_SUBTRACT from NUMERIC should be NUMERIC operator.");
 					msg(" Operator type is %d in: %s\n", OperType, this->GetDisasm());
 				}
+#if 0
 				if (!RightNumeric) {
 					// Right operand is being used as a NUMERIC, so propagate NUMERIC to it.
 					if (CurrRT->HasRightSubTree()) {
@@ -1672,6 +1705,7 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) {
 					}
 					updated = true;
 				}
+#endif
 			} // end if LeftNumeric
 			else if (LeftPointer) {
 				if (UNINIT == OperType) {
@@ -2187,18 +2221,25 @@ void SMPInstr::EmitTypeAnnotations(bool UseFP, bool AllocSeen, FILE *AnnotFile)
 			++AnnotationCount[OptType];
 			break;
 
-		case 5: // ADD, etc.: If numeric 2nd src operand, no SDT work.	
+		case 5: // ADD, etc.: If numeric 2nd src operand, no SDT work.
 #if 1
-			if (MemDest || MemSrc) {
+			if (MemDest) {
 				SDTInstrumentation = true;
 				break;  // treat as category 0
 			}
 #endif
+			this->SetAddSubSourceType();
 			if (SecondSrcOperandNum && !this->MDIsFrameAllocInstr()) { // treat as category 1
 				qfprintf(AnnotFile, "%10x %6d INSTR LOCAL %s %s \n",
 						addr, -1, OptExplanation[OptType], disasm);
 				++AnnotationCount[OptType];
 			}
+			else if (IsEqType(NUMERIC, this->AddSubSourceType)
+				&& !this->MDIsFrameAllocInstr()) {
+				qfprintf(AnnotFile, "%10x %6d INSTR LOCAL 2ndSrcNumeric %s \n",
+						addr, -1, disasm);
+				++AnnotationCount[OptType];
+			}
 			else if (NumericDEFs) {
 				qfprintf(AnnotFile, "%10x %6d INSTR LOCAL n %s NumericDEFs %s \n",
 						addr, -2, this->DestString(OptType), disasm);
diff --git a/SMPInstr.h b/SMPInstr.h
index fdb913ac..3b920f42 100644
--- a/SMPInstr.h
+++ b/SMPInstr.h
@@ -242,6 +242,7 @@ private:
 	char DeadRegsString[MAXSTR]; // Registers that are dead at this instruction
 	bool DefsFlags;  // Instr DEFs the flags
 	bool UsesFlags;  // Instr USEs the flags
+	SMPOperandType AddSubSourceType;  // Source op (USE only) type for add/sub
 	bool TypeInferenceComplete;  // All types have been resolved
 	// For some type categories, inference just based on the category is done one time
 	//  only, so this is a variable that is set to true after the first inference
@@ -280,6 +281,7 @@ private:
 	bool BuildMultiplyDivideRTL(SMPoperator BinaryOp);  // helper for BuildRTL()
 	void SyncRTLDefUse(SMPRegTransfer *CurrRT); // Ensure that all RTL operands are in the DEF/USE lists
 	bool InferOperatorType(SMPRegTransfer *CurrRT); // return true if type updated
+	void SetAddSubSourceType(void);
 };  // end class SMPInstr
 
 #endif
diff --git a/SMPProgram.cpp b/SMPProgram.cpp
index 32793dbc..f4317017 100644
--- a/SMPProgram.cpp
+++ b/SMPProgram.cpp
@@ -301,7 +301,7 @@ void SMPProgram::Analyze(void) {
 				pair<ea_t, SMPFunction *> TempFunc(FuncInfo->startEA, CurrFunc);
 				this->FuncMap.insert(TempFunc);
 				CurrFunc->Analyze();
-				if (0 == strcmp("EvVar", CurrFunc->GetFuncName())) {
+				if (0 == strcmp("load_subblock_array", CurrFunc->GetFuncName())) {
 					DebugFlag = true;
 				}
 #if SMP_INFER_TYPES
-- 
GitLab