From 63c3799ff7ffe1684970ddfd9d355bcbc73d7161 Mon Sep 17 00:00:00 2001
From: Clark Coleman <clc@zephyr-software.com>
Date: Thu, 21 Mar 2019 11:51:02 -0400
Subject: [PATCH] Corner case fix to support LAF; BinaryRTL() building cleanup.

---
 src/base/SMPFunction.cpp |  4 ++--
 src/base/SMPInstr.cpp    | 35 ++++++++++++++++++++++-------------
 2 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp
index 5164428f..d427ab17 100644
--- a/src/base/SMPFunction.cpp
+++ b/src/base/SMPFunction.cpp
@@ -4089,10 +4089,10 @@ bool SMPFunction::MDUpdateFGStackLocInfo(STARS_ea_t InstAddr, const STARSOpndTyp
 			this->PositiveOffsetFineGrainedStackTable[SignedOffset].SizeInfo |= NewFG.SizeInfo;
 		}
 	}
-	else if (this->OutgoingArgsComputed && (((std::size_t) SignedOffset) < this->OutgoingArgsSize)) {
+	else if (!this->DoesStackFrameExtendPastStackTop() && this->OutgoingArgsComputed && (((std::size_t) SignedOffset) < this->OutgoingArgsSize)) {
 		// We don't want to update the outgoing args region, as it will not be consistent
 		//  over multiple function calls. NOTE: We could fine tune this by seeing if we
-		//  call mutliple target functions or not; if only one, then outgoing args region
+		//  call multiple target functions or not; if only one, then outgoing args region
 		//  would be consistent in the absence of varargs targets.
 		return false;
 	}
diff --git a/src/base/SMPInstr.cpp b/src/base/SMPInstr.cpp
index ac33c3f8..f071b7d1 100644
--- a/src/base/SMPInstr.cpp
+++ b/src/base/SMPInstr.cpp
@@ -18714,10 +18714,9 @@ bool SMPInstr::BuildBinaryRTL(SMPoperator BinaryOp, bool HiddenFPStackOp) {
 	bool StackPointerModification = false; // SP := SP SMP_BITWISE_AND operand
 	bool NeedsGuard = ((STARS_NN_arpl == opcode) || (STARS_NN_bound == opcode));
 	bool BuildOnlySignalRT = (STARS_NN_bound == opcode);
-	SMPRegTransfer *TempRT = NULL;
-	SMPRegTransfer *RightRT = new SMPRegTransfer;
-	SMPGuard *Guard1 = NULL;
-	RightRT->SetParentInst(this);
+	SMPRegTransfer *TempRT = nullptr;
+	SMPRegTransfer *RightRT = nullptr;
+	SMPGuard *Guard1 = nullptr;
 
 	STARSOpndTypePtr VoidOp = this->STARSInstPtr->MakeVoidOpnd();
 
@@ -18737,6 +18736,8 @@ bool SMPInstr::BuildBinaryRTL(SMPoperator BinaryOp, bool HiddenFPStackOp) {
 		TempRT->SetParentInst(this);
 		TempRT->SetLeftOperand(FPRegOp);
 		TempRT->SetOperator(SMP_ASSIGN);
+		RightRT = new SMPRegTransfer;
+		RightRT->SetParentInst(this);
 		RightRT->SetLeftOperand(FPRegOp);
 		RightRT->SetOperator(BinaryOp);
 		RightRT->SetRightOperand(VoidOp);
@@ -18767,6 +18768,8 @@ bool SMPInstr::BuildBinaryRTL(SMPoperator BinaryOp, bool HiddenFPStackOp) {
 					}
 					else {
 						if (!BuildOnlySignalRT) {
+							RightRT = new SMPRegTransfer;
+							RightRT->SetParentInst(this);
 							RightRT->SetLeftOperand(TempOp);
 							RightRT->SetOperator(BinaryOp);
 							TempRT->SetRightTree(RightRT);
@@ -18808,9 +18811,15 @@ bool SMPInstr::BuildBinaryRTL(SMPoperator BinaryOp, bool HiddenFPStackOp) {
 				if (!MemSrc || MemDest || (IsMemOperand(TempOp))) {
 					SourceFound = true;
 					if (!BuildOnlySignalRT) {
-						RightRT->SetRightOperand(TempOp);
-						if (StackPointerModification && (TempOp->IsImmedOp())) {
-							this->SetStackAlignmentInst();
+						if (nullptr != RightRT) {
+							RightRT->SetRightOperand(TempOp);
+							if (StackPointerModification && (TempOp->IsImmedOp())) {
+								this->SetStackAlignmentInst();
+							}
+						}
+						else {
+							SourceFound = false; // take error exit
+							break;
 						}
 					}
 				}
@@ -18835,10 +18844,9 @@ bool SMPInstr::BuildBinaryRTL(SMPoperator BinaryOp, bool HiddenFPStackOp) {
 	} // end for (OpNum = 0; ...)
 
 	if (!DestFound || !SourceFound) {
-		assert(NULL != RightRT);
-		if (DestFound && (NULL != TempRT))
+		if (DestFound && (nullptr != TempRT))
 			delete TempRT;
-		else
+		else if (nullptr != RightRT)
 			delete RightRT;
 #if SMP_DEBUG_BUILD_RTL
 		if (!DestFound) {
@@ -18857,7 +18865,8 @@ bool SMPInstr::BuildBinaryRTL(SMPoperator BinaryOp, bool HiddenFPStackOp) {
 			TempRT->SetLeftOperand(VoidOp);
 			TempRT->SetRightOperand(VoidOp);
 			TempRT->SetOperator(SMP_SIGNAL);
-			delete RightRT;
+			if (nullptr != RightRT)
+				delete RightRT;
 		}
 		this->RTL.push_back(TempRT);
 		// The "p" at the end of the opcode indicates that the floating point
@@ -23447,7 +23456,7 @@ bool SMPInstr::BuildX86RTL(void)
 
 		case STARS_NN_fist:                // Store Integer
 		case STARS_NN_fistp:               // Store Integer and Pop
-			return this->BuildBinaryRTL(SMP_CONVERT_FP_TO_INT);
+			return this->BuildUnaryRTL(SMP_CONVERT_FP_TO_INT);
 
 		case STARS_NN_fbld:                // Load BCD
 		case STARS_NN_fbstp:               // Store BCD and Pop
@@ -24381,7 +24390,7 @@ bool SMPInstr::BuildX86RTL(void)
 			break;
 
 		case STARS_NN_fisttp:              // Store ST in intXX (chop) and pop
-			return this->BuildBinaryRTL(SMP_CONVERT_FP_TO_INT);
+			return this->BuildUnaryRTL(SMP_CONVERT_FP_TO_INT);
 			break;
 
 		case STARS_NN_lddqu:               // Load unaligned integer 128-bit
-- 
GitLab