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