From 4451efbc7261226365f7a1bf58abe9c4466cf9cc Mon Sep 17 00:00:00 2001
From: clc5q <clc5q@git.zephyr-software.com>
Date: Sun, 4 Dec 2011 20:50:53 +0000
Subject: [PATCH] Infer that registers with MEDS type of data or code ptr must
 be unsigned, handle 10-byte FPU operands.

---
 SMPDataFlowAnalysis.cpp |  3 +++
 SMPFunction.cpp         |  8 +++++++
 SMPInstr.cpp            | 52 +++++++++++++++++++++++++++++++++++++++++
 SMPInstr.h              |  1 +
 4 files changed, 64 insertions(+)

diff --git a/SMPDataFlowAnalysis.cpp b/SMPDataFlowAnalysis.cpp
index 3142276a..929aa173 100644
--- a/SMPDataFlowAnalysis.cpp
+++ b/SMPDataFlowAnalysis.cpp
@@ -167,6 +167,9 @@ size_t GetOpDataSize(op_t DataOp) {
 		case dt_qword:
 			DataSize = 8;
 			break;
+		case dt_tbyte:
+			DataSize = 10;
+			break;
 		case dt_packreal:
 			DataSize = 12;
 			break;
diff --git a/SMPFunction.cpp b/SMPFunction.cpp
index 956444b9..ec42e3a9 100644
--- a/SMPFunction.cpp
+++ b/SMPFunction.cpp
@@ -4313,6 +4313,14 @@ void SMPFunction::InferTypes(bool FirstIter) {
 
 	} while (changed);
 
+	// With type inference finished, infer signedness from the types, e.g.
+	//  POINTER and CODEPOINTER types must be UNSIGNED.
+	if (FirstIter) { // Don't want profiler-dependent signedness in the system yet.
+		for (CurrInst = this->Instrs.begin(); CurrInst != this->Instrs.end(); ++CurrInst) {
+			CurrInst->InferSignednessFromSMPTypes(this->UsesFramePointer());
+		}
+	}
+
 	// Record the meet of all register types that reach RETURN instructions.
 	this->MDFindReturnTypes();
 	return;
diff --git a/SMPInstr.cpp b/SMPInstr.cpp
index 8ebd06b9..d07b5a1d 100644
--- a/SMPInstr.cpp
+++ b/SMPInstr.cpp
@@ -2244,6 +2244,58 @@ void SMPInstr::MDSetWidthSignInfo(bool UseFP) {
 	return;
 } // end of SMPInstr::MDSetWidthSignInfo()
 
+// Infer sign from the SMP types for USEs and DEFs.
+void SMPInstr::InferSignednessFromSMPTypes(bool UseFP) {
+	// Start with registers only, infer that all kids of pointers are UNSIGNED.
+	set<DefOrUse, LessDefUse>::iterator DefIter, UseIter;
+	op_t DefOp, UseOp;
+	int SSANum;
+	int DefHashValue, UseHashValue;
+	SMPOperandType DefType, UseType;
+	unsigned short DefSignMiscInfo = FG_MASK_UNSIGNED, UseSignMiscInfo = FG_MASK_UNSIGNED;
+	bool GlobalName;
+
+	for (DefIter = this->GetFirstDef(); DefIter != this->GetLastDef(); ++DefIter) {
+		DefOp = DefIter->GetOp();
+		if (MDIsGeneralPurposeReg(DefOp)) {
+			DefType = DefIter->GetType();
+			if (IsDataPtr(DefType) || (CODEPTR == DefType)) {
+				GlobalName = this->BasicBlock->GetFunc()->IsGlobalName(DefOp);
+				SSANum = DefIter->GetSSANum();
+				DefHashValue = HashGlobalNameAndSSA(DefOp, SSANum);
+				if (GlobalName) {
+					this->BasicBlock->GetFunc()->UpdateDefSignMiscInfo(DefHashValue, DefSignMiscInfo);
+				}
+				else {
+					this->BasicBlock->UpdateDefSignMiscInfo(DefHashValue, DefSignMiscInfo);
+				}
+			}
+		}
+	}
+
+	for (UseIter = this->GetFirstUse(); UseIter != this->GetLastUse(); ++UseIter) {
+		UseOp = UseIter->GetOp();
+		if (MDIsGeneralPurposeReg(UseOp)) {
+			UseType = UseIter->GetType();
+			if (IsDataPtr(UseType) || (CODEPTR == UseType)) {
+				GlobalName = this->BasicBlock->GetFunc()->IsGlobalName(UseOp);
+				SSANum = UseIter->GetSSANum();
+				UseHashValue = HashGlobalNameAndSSA(UseOp, SSANum);
+				if (GlobalName) {
+					this->BasicBlock->GetFunc()->UpdateUseSignMiscInfo(UseHashValue, UseSignMiscInfo);
+				}
+				else {
+					this->BasicBlock->UpdateUseSignMiscInfo(UseHashValue, UseSignMiscInfo);
+				}
+			}
+		}
+	}
+
+	return;
+} // end of SMPInstr::InferSignednessFromSMPTypes()
+
+
+
 // Helper to set width info for a UseOp from an RTL
 void SMPInstr::SetRTLUseOpRegWidthInfo(op_t UseOp) {
 	unsigned short WidthMask;
diff --git a/SMPInstr.h b/SMPInstr.h
index 8149c638..612a469d 100644
--- a/SMPInstr.h
+++ b/SMPInstr.h
@@ -364,6 +364,7 @@ public:
 	void SetImmedTypes(bool UseFP); // type all immediate operands as NUMERIC, CODEPTR, GLOBALPTR
 									//  and set other context-free types (ESP == STACKPTR, etc.)
 	void MDSetWidthSignInfo(bool UseFP); // Infer sign, bit width, etc. in simple cases within one instr
+	void InferSignednessFromSMPTypes(bool UseFP); // Infer sign from the SMP types for USEs and DEFs.
 
 	bool InferTypes(void); // return true if any DEF-USE or RTL operator types were updated.
 	bool InferFGInfo(unsigned short IterCount); // infer width on first pass, signedness on all passes
-- 
GitLab