diff --git a/SMPDataFlowAnalysis.cpp b/SMPDataFlowAnalysis.cpp index 3142276a232d70bc5140aa6dc80665910109708a..929aa173b20848bfe5bf9dee44d743bcd86bf543 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 956444b91893f38e3e8d31abf121d7f10d578ff0..ec42e3a988b5550af54e6fcaa042a636b09da97f 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 8ebd06b9ecab8a57900c130497539debc93e37df..d07b5a1de0a8a76fa57529e8868568e8fc8d6e7d 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 8149c638858065e7a76de02bc47fb8450b37bc88..612a469d4aeb5db7e23f421636af3a8de5ce6c1a 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