From fc4a9f030fc633c74d46d3822d7495ee20b9f0c2 Mon Sep 17 00:00:00 2001
From: clc5q <clc5q@git.zephyr-software.com>
Date: Fri, 18 Sep 2015 13:13:39 +0000
Subject: [PATCH] More SPARK Ada translation improvements.

Former-commit-id: 7cce2c3c80b7256ce696292b50b29aa4d8f86210
---
 include/base/SMPInstr.h                  |  1 +
 src/base/SMPFunction.cpp                 | 24 ++++++++++++++----
 src/base/SMPInstr.cpp                    | 31 +++++++++++++++++++++---
 src/base/SMPProgram.cpp                  |  4 +++
 src/drivers/idapro/SMPStaticAnalyzer.cpp |  2 +-
 5 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/include/base/SMPInstr.h b/include/base/SMPInstr.h
index 296174ce..490209fd 100644
--- a/include/base/SMPInstr.h
+++ b/include/base/SMPInstr.h
@@ -612,6 +612,7 @@ public:
 	void MDEmitSPARKAdaSetCondCodeIntoReg(FILE *OutFile); // emit SPARK Ada for moving a condition code value or expr into a register
 	void MDEmitSPARKAdaCondition(FILE *OutFile); // emit SPARK Ada for the current conditional branch
 	void MDEmitSPARKAdaInvertedCondition(FILE *OutFile); // Invert the condition of the current conditional branch and emit SPARK Ada equivalent.
+	void EmitSPARKAdaInvariantsForRetAddr(FILE *BodyFile) const;
 	void EmitSPARKAda(FILE *OutFile); // Emit SPARK-Ada translation of instruction
 
 	// Analysis methods
diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp
index 84bf0ba0..b3824a2f 100644
--- a/src/base/SMPFunction.cpp
+++ b/src/base/SMPFunction.cpp
@@ -39,6 +39,7 @@ using namespace std;
 #include <set>
 #include <vector>
 #include <algorithm>
+#include <iostream>
 
 #include <cstring>
 #include <cstdint>
@@ -8684,26 +8685,30 @@ void SMPFunction::EmitFuncSPARKAda(void) {
 	if (this->IsLinkerStub()) {
 		return;
 	}
+	string AdaFuncName(this->GetFuncName());
 #if STARS_EMIT_ADA_FOR_MAIN_ONLY
-	if (0 != strcmp("main", this->GetFuncName())) {
+	if (0 != strcmp("main", AdaFuncName.c_str())) {
 		return;
 	}
 #endif
 
+	// Convert dashes to underscores in the func name to suit Ada standards.
+	replace(AdaFuncName.begin(), AdaFuncName.end(), '-', '_');
+
 	FILE *BodyFile = global_STARS_program->GetSPARKSourceFile();
 	FILE *HeaderFile = global_STARS_program->GetSPARKHeaderFile();
 	size_t ByteWidth = global_STARS_program->GetSTARS_ISA_Bytewidth();
 
 	// Emit beginning of function body.
-	SMP_fprintf(BodyFile, "procedure %s\nis\n", this->GetFuncName());
+	SMP_fprintf(BodyFile, "procedure %s\nis\n", AdaFuncName.c_str());
 	SMP_fprintf(BodyFile, "\tra0 : Unsigned8 := X86.ReadMem8(X86.RSP);\n");
 	for (unsigned short i = 1; i < ByteWidth; ++i) {
 		SMP_fprintf(BodyFile, "\tra%u : Unsigned8 := X86.ReadMem8(X86.RSP + %u);\n", i, i);
 	}
-	SMP_fprintf(BodyFile, "\n");
+	SMP_fprintf(BodyFile, "\nbegin\n");
 
 	// Emit procedure specification.
-	SMP_fprintf(HeaderFile, "procedure %s with\n", this->GetFuncName());
+	SMP_fprintf(HeaderFile, "procedure %s with\n", AdaFuncName.c_str());
 	SMP_fprintf(HeaderFile, "\tGlobal => (In_Out => (X86.Memory, X86.Exit_Called, X86.CarryFlag,\n");
 	SMP_fprintf(HeaderFile, "\t\tX86.OverflowFlag, X86.SignFlag, X86.ZeroFlag,\n");
 	// Form union of regs killed, LiveOut, and LiveIn
@@ -8754,7 +8759,13 @@ void SMPFunction::EmitFuncSPARKAda(void) {
 		}
 	}
 	SMP_fprintf(HeaderFile, "\t\tInput => (X86.StackAddressSize, X86.FS, X86.GS)),\n");
-	SMP_fprintf(HeaderFile, "\tPre => (X86.RSP > 16#FFFFFFFF00000000# and X86.RSP < 16#FFFFFFFFFFFFFF00#),\n");
+	SMP_fprintf(HeaderFile, "\tPre => (X86.RSP > 16#FFFFFFFF00000000# and X86.RSP < 16#FFFFFFFFFFFFFF00#");
+	if (8 == ByteWidth) {
+		SMP_fprintf(HeaderFile, "\n\t\tand X86.EDI > 0),\n");  // argc > 0 for x86_64
+	}
+	else {
+		SMP_fprintf(HeaderFile, "),\n");
+	}
 	SMP_fprintf(HeaderFile, "\tPost => (X86.RSP = (X86.RSP'Old + 8)) and\n");
 	SMP_fprintf(HeaderFile, "\t\t(X86.Memory(X86.RSP'Old) = X86.Memory'Old(X86.RSP'Old)) and\n");
 	SMP_fprintf(HeaderFile, "\t\t(X86.Memory(X86.RSP'Old + 1) = X86.Memory'Old(X86.RSP'Old + 1)) and\n");
@@ -8777,6 +8788,9 @@ void SMPFunction::EmitFuncSPARKAda(void) {
 		++InstIter;
 	} // end while all instrs
 
+	SMP_fprintf(BodyFile, "\nend %s;\n", AdaFuncName.c_str());
+	STARS_SPARK_IndentCount = 0;
+
 	return;
 } // end of SMPFunction::EmitFuncSPARKAda()
 
diff --git a/src/base/SMPInstr.cpp b/src/base/SMPInstr.cpp
index 6067a3a0..33d0030f 100644
--- a/src/base/SMPInstr.cpp
+++ b/src/base/SMPInstr.cpp
@@ -1025,17 +1025,17 @@ bool SMPRegTransfer::OperandTransfersHelper(const STARSOpndTypePtr &UseOp) const
 // Does RTL show LeftOp has smaller bitwidth than the right hand side operands?
 bool SMPRegTransfer::IsTruncatedWidthRTL(std::size_t &LeftBitWidth) const {
 	bool TruncatedWidth = false;
-	STARSOpndTypePtr LeftOp = this->GetLeftOperand();
+	STARSOpndTypePtr LeftOp = this->GetLeftOperandNoNorm();
 	std::size_t LeftOpByteWidth = (std::size_t) LeftOp->GetByteWidth();
 	if (LeftOpByteWidth < global_STARS_program->GetSTARS_ISA_Bytewidth()) { // Forget it unless LeftOp is reduced width.
 		// Search right hand side for wider operands.
 		LeftBitWidth = 8 * LeftOpByteWidth;
 		STARSOpndTypePtr RightOp = nullptr;
 		if (this->HasRightSubTree()) {
-			RightOp = this->GetRightTree()->GetLeftOperand();
+			RightOp = this->GetRightTree()->GetLeftOperandNoNorm();
 		}
 		else {
-			RightOp = this->GetRightOperand();
+			RightOp = this->GetRightOperandNoNorm();
 		}
 		if (nullptr != RightOp) {
 			TruncatedWidth = ((RightOp->GetByteWidth() > LeftOpByteWidth) && (RightOp->IsRegOp() || RightOp->IsMemOp()));
@@ -2630,6 +2630,27 @@ void SMPInstr::MDEmitSPARKAdaInvertedCondition(FILE *OutFile) {
 	return;
 } // end of SMPInstr::MDEmitSPARKAdaInvertedCondition()
 
+void SMPInstr::EmitSPARKAdaInvariantsForRetAddr(FILE *BodyFile) const {
+	PrintSPARKIndentTabs(BodyFile);
+	SMP_fprintf(BodyFile, "pragma Loop_Invariant(X86.Memory(SaveStackPtr) = ra0);\n");
+	PrintSPARKIndentTabs(BodyFile);
+	SMP_fprintf(BodyFile, "pragma Loop_Invariant(X86.Memory(SaveStackPtr + 1) = ra1);\n");
+	PrintSPARKIndentTabs(BodyFile);
+	SMP_fprintf(BodyFile, "pragma Loop_Invariant(X86.Memory(SaveStackPtr + 2) = ra2);\n");
+	PrintSPARKIndentTabs(BodyFile);
+	SMP_fprintf(BodyFile, "pragma Loop_Invariant(X86.Memory(SaveStackPtr + 3) = ra3);\n");
+	PrintSPARKIndentTabs(BodyFile);
+	SMP_fprintf(BodyFile, "pragma Loop_Invariant(X86.Memory(SaveStackPtr + 4) = ra4);\n");
+	PrintSPARKIndentTabs(BodyFile);
+	SMP_fprintf(BodyFile, "pragma Loop_Invariant(X86.Memory(SaveStackPtr + 5) = ra5);\n");
+	PrintSPARKIndentTabs(BodyFile);
+	SMP_fprintf(BodyFile, "pragma Loop_Invariant(X86.Memory(SaveStackPtr + 6) = ra6);\n");
+	PrintSPARKIndentTabs(BodyFile);
+	SMP_fprintf(BodyFile, "pragma Loop_Invariant(X86.Memory(SaveStackPtr + 7) = ra7);\n");
+
+	return;
+}
+
 // Emit SPARK-Ada translation of instruction
 void SMPInstr::EmitSPARKAda(FILE *OutFile) {
 	// Print the disassembly as a comment before the SPARK translation.
@@ -2671,6 +2692,7 @@ void SMPInstr::EmitSPARKAda(FILE *OutFile) {
 			PrintSPARKIndentTabs(OutFile);
 			SMP_fprintf(OutFile, "loop \n");
 			++STARS_SPARK_IndentCount;
+			this->EmitSPARKAdaInvariantsForRetAddr(OutFile);
 		}
 	}
 
@@ -5103,6 +5125,7 @@ void SMPInstr::SetLeaMemUseOp(STARSOpndTypePtr NewLeaOperand) {
 // If DefReg is not already in the DEF list, add a DEF for it.
 void SMPInstr::MDAddRegDef(uint16_t DefReg, bool Shown, SMPOperandType Type) {
 	STARSOpndTypePtr TempDef = this->STARSInstPtr->MakeRegOpnd(DefReg);
+	CanonicalizeOpnd(TempDef);
 	if (!Shown)
 		TempDef->SetNotVisible();
 	this->Defs.SetRef(TempDef, Type);
@@ -7928,7 +7951,7 @@ void SMPInstr::SCCPFetchConstUseValue(const STARSOpndTypePtr &UseOp, STARS_SCCP_
 #if 1
 		int BaseReg = (int) UseOp->GetReg();
 		if (MD_STACK_POINTER_REG == BaseReg) {
-			// ESP BaseReg in SIB byte means no base reg for StaticMemOp
+			// ESP BaseReg in means no base reg for StaticMemOp
 			BaseReg = STARS_x86_R_none;
 		}
 		if (UseOp->HasSIBByte()) {
diff --git a/src/base/SMPProgram.cpp b/src/base/SMPProgram.cpp
index d4a4cc75..b343346a 100644
--- a/src/base/SMPProgram.cpp
+++ b/src/base/SMPProgram.cpp
@@ -798,6 +798,10 @@ bool SMPProgram::EmitProgramSPARKAda(void) {
 		return false;
 	}
 
+
+	// Convert dashes to underscores in the package name to suit Ada standards.
+	replace(PackageName.begin(), PackageName.end(), '-', '_');
+
 	// Emit the package body.
 	SMP_fprintf(BodyFile, "Package body %s\n", PackageName.c_str());
 	SMP_fprintf(BodyFile, "with SPARK_Mode \nis\n\n");
diff --git a/src/drivers/idapro/SMPStaticAnalyzer.cpp b/src/drivers/idapro/SMPStaticAnalyzer.cpp
index a8c55b1c..6e3bf2ff 100644
--- a/src/drivers/idapro/SMPStaticAnalyzer.cpp
+++ b/src/drivers/idapro/SMPStaticAnalyzer.cpp
@@ -62,7 +62,7 @@
 
 using namespace std;
 
-#define SMP_DEBUG_DELAY 0   // for setting an early breakpoint
+#define SMP_DEBUG_DELAY 1   // for setting an early breakpoint
 
 // Set to 1 for debugging output
 #define SMP_DEBUG 1
-- 
GitLab