diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp index d3fc77eaa4dcb1935007e408ec8324a00e382b2b..5822d43d3286d6102c229f7d4ad39542bdb2e4f7 100644 --- a/src/base/SMPFunction.cpp +++ b/src/base/SMPFunction.cpp @@ -10228,8 +10228,19 @@ void SMPFunction::MarkFunctionSafe() { bool MakesTailCall = false; // problem for Fast Returns, not for return address safety bool HasNoCallers = this->AllCallSources.empty(); - this->SetReturnAddressStatus(FUNC_SAFE); - this->SetFuncSafe(true); + if (this->HasGoodRTLs()) { + this->SetReturnAddressStatus(FUNC_SAFE); + this->SetFuncSafe(true); + } + else { // don't process instructions if we have any bad RTLs + this->SetReturnAddressStatus(FUNC_UNSAFE); + this->SetUnsafeForFastReturns(true, UNSAFE_RETURN_ADDRESS); + this->SetFuncSafe(false); + this->SetSpecFuncSafe(false); + this->SetNeedsFrame(true); + this->SetSpecNeedsFrame(true); + return; + } if (!this->AllCallTargets.empty()) { HasCallTargets = true; diff --git a/src/base/SMPInstr.cpp b/src/base/SMPInstr.cpp index 8fccd61499fde8148e9d26cd59ab4534d22dc9ce..bf7ac8e83e1108407d5b076e984f12db2efecddc 100644 --- a/src/base/SMPInstr.cpp +++ b/src/base/SMPInstr.cpp @@ -3890,6 +3890,9 @@ bool SMPInstr::MDUsesCalleeSavedReg(void) { // into a general purpose register (which mmStrata will now need to track as a stack // relative pointer)? bool SMPInstr::MDIsStackPointerCopy(bool UseFP) { + if (!this->HasGoodRTL()) + return false; + // OptType 3 indicates a move instruction // The lea instruction can perform three operand arithmetic, e.g. // lea ebx,[esp+12] is just ebx:=esp+12, so it is a stack pointer copy. @@ -11102,6 +11105,9 @@ void SMPInstr::EmitCallReturnStatus(SMPProgram *CurrProg) { // Emit all annotations for the instruction in the absence of RTL type inference. void SMPInstr::EmitAnnotations(bool UseFP, bool AllocSeen, bool NeedsFrame, FILE *AnnotFile, FILE *InfoAnnotFile, SMPProgram *CurrProg) { + if (!this->HasGoodRTL()) + return; + STARS_ea_t addr = this->GetAddr(); SMPitype DataFlowType = this->GetDataFlowType(); #if 0 // wait on INDIR_CALL until we have good targets and sound analysis @@ -18173,8 +18179,13 @@ bool SMPInstr::BuildRTL(void) { case STARS_NN_ud2: // Undefined Instruction - return false; - break; + // Should be unreachable, so make it a nop so the whole func can be analyzed + NopRT = new SMPRegTransfer; + NopRT->SetParentInst(this); + NopRT->SetOperator(SMP_NULL_OPERATOR); + this->RTL.push_back(NopRT); + NopRT = NULL; + return true; // Added with x86-64 @@ -18344,7 +18355,7 @@ bool SMPInstr::BuildRTL(void) { case STARS_NN_pmuldq: // Multiply Packed Signed Dword Integers case STARS_NN_pmulld: // Multiply Packed Signed Dword Integers and Store Low Result - return false; + return this->BuildBinaryRTL(SMP_FLOATING_MULTIPLY); break; case STARS_NN_ptest: // Logical Compare @@ -18370,10 +18381,12 @@ bool SMPInstr::BuildRTL(void) { break; case STARS_NN_pcmpgtq: // Compare Packed Data for Greater Than - case STARS_NN_popcnt: // Return the Count of Number of Bits Set to 1 return false; break; + case STARS_NN_popcnt: // Return the Count of Number of Bits Set to 1 + return this->BuildUnary2OpndRTL(SMP_UNARY_NUMERIC_OPERATION); + // AMD SSE4a instructions case STARS_NN_extrq: // Extract Field From Register @@ -18425,8 +18438,7 @@ bool SMPInstr::BuildRTL(void) { // Intel Atom instructions case STARS_NN_movbe: // Move Data After Swapping Bytes - return false; - break; + return this->BuildUnary2OpndRTL(SMP_UNARY_NUMERIC_OPERATION); // Intel AES instructions @@ -18564,24 +18576,61 @@ bool SMPInstr::BuildRTL(void) { case STARS_NN_vcmpss: // Scalar Single-FP Compare case STARS_NN_vcomisd: // Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS case STARS_NN_vcomiss: // Scalar Ordered Single-FP Compare and Set EFLAGS + return false; + break; + case STARS_NN_vcvtdq2pd: // Convert Packed Doubleword Integers to Packed Single-Precision Floating-Point Values case STARS_NN_vcvtdq2ps: // Convert Packed Doubleword Integers to Packed Double-Precision Floating-Point Values + return this->BuildBinaryRTL(SMP_CONVERT_INT_TO_FP); + break; + case STARS_NN_vcvtpd2dq: // Convert Packed Double-Precision Floating-Point Values to Packed Doubleword Integers + return this->BuildBinaryRTL(SMP_CONVERT_FP_TO_INT); + break; + case STARS_NN_vcvtpd2ps: // Convert Packed Double-Precision Floating-Point Values to Packed Single-Precision Floating-Point Values case STARS_NN_vcvtph2ps: // Convert 16-bit FP Values to Single-Precision FP Values + return false; + break; + case STARS_NN_vcvtps2dq: // Convert Packed Single-Precision Floating-Point Values to Packed Doubleword Integers + return this->BuildBinaryRTL(SMP_CONVERT_FP_TO_INT); + break; + case STARS_NN_vcvtps2pd: // Convert Packed Single-Precision Floating-Point Values to Packed Double-Precision Floating-Point Values case STARS_NN_vcvtps2ph: // Convert Single-Precision FP value to 16-bit FP value + return false; + break; + case STARS_NN_vcvtsd2si: // Convert Scalar Double-Precision Floating-Point Value to Doubleword Integer + return this->BuildBinaryRTL(SMP_CONVERT_FP_TO_INT); + break; + case STARS_NN_vcvtsd2ss: // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value + return false; + break; + case STARS_NN_vcvtsi2sd: // Convert Doubleword Integer to Scalar Double-Precision Floating-Point Value case STARS_NN_vcvtsi2ss: // Scalar signed INT32 to Single-FP conversion + return this->BuildBinaryRTL(SMP_CONVERT_INT_TO_FP); + break; + case STARS_NN_vcvtss2sd: // Convert Scalar Single-Precision Floating-Point Value to Scalar Double-Precision Floating-Point Value + return false; + break; + case STARS_NN_vcvtss2si: // Scalar Single-FP to signed INT32 conversion + return this->BuildBinaryRTL(SMP_CONVERT_FP_TO_INT); + break; + case STARS_NN_vcvttpd2dq: // Convert With Truncation Packed Double-Precision Floating-Point Values to Packed Doubleword Integers case STARS_NN_vcvttps2dq: // Convert With Truncation Packed Single-Precision Floating-Point Values to Packed Doubleword Integers case STARS_NN_vcvttsd2si: // Convert with Truncation Scalar Double-Precision Floating-Point Value to Doubleword Integer case STARS_NN_vcvttss2si: // Scalar Single-FP to signed INT32 conversion (truncate) + return this->BuildBinaryRTL(SMP_CONVERT_FP_TO_INT); + break; + + case STARS_NN_vdivpd: // Divide Packed Double-Precision Floating-Point Values case STARS_NN_vdivps: // Packed Single-FP Divide case STARS_NN_vdivsd: // Divide Scalar Double-Precision Floating-Point Values