From f8e2d3f8eaedf4947a36ad1cff104471eff1225b Mon Sep 17 00:00:00 2001
From: clc5q <clc5q@git.zephyr-software.com>
Date: Wed, 5 Mar 2008 02:16:22 +0000
Subject: [PATCH] Handle DEFs/USEs due to REP/REPNE prefixes.

---
 SMPInstr.cpp | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/SMPInstr.cpp b/SMPInstr.cpp
index b47df897..5e006be9 100644
--- a/SMPInstr.cpp
+++ b/SMPInstr.cpp
@@ -582,11 +582,34 @@ void SMPInstr::MDFixupDefUseLists(void) {
 		} // end if (o_phrase or o_displ operand)
 	} // end for (all operands)
 
-	// Next, handle repeat prefices in the instructions.
+	// Next, handle repeat prefices in the instructions. The Intel REPE/REPZ prefix
+	//  is just the text printed for SCAS/CMPS instructions that have a REP prefix.
+	//  Only two distinct prefix codes are actually defined: REP and REPNE/REPNZ, and
+	//  REPNE/REPNZ only applies to SCAS and CMPS instructions.
 	bool HasRepPrefix = (0 != (this->SMPcmd.auxpref & aux_rep));
 	bool HasRepnePrefix = (0 != (this->SMPcmd.auxpref & aux_repne));
 	if (HasRepPrefix && HasRepnePrefix)
 		msg("REP and REPNE both present at %x %s\n", this->GetAddr(), this->GetDisasm());
+	if (HasRepPrefix || HasRepnePrefix) {
+		// All repeating instructions use ECX as the countdown register.
+		op_t BaseOpnd;
+		BaseOpnd.type = o_reg; // Change type and reg fields
+		BaseOpnd.reg = R_cx;
+		BaseOpnd.hasSIB = 0;
+		BaseOpnd.clr_showed();
+		this->Defs.SetRef(BaseOpnd);
+		this->Uses.SetRef(BaseOpnd);
+	}
+	if (!this->DefsFlags && ((this->SMPcmd.itype == NN_cmps) || (this->SMPcmd.itype == NN_scas))) {
+		// REPE and REPNE define the flags in addition to ECX.
+		op_t BaseOpnd;
+		BaseOpnd.type = o_reg; // Change type and reg fields
+		BaseOpnd.reg = X86_FLAGS_REG;
+		BaseOpnd.hasSIB = 0;
+		BaseOpnd.clr_showed();
+		this->Defs.SetRef(BaseOpnd);
+		this->DefsFlags = true;
+	}
 
 	// Now, handle special instruction categories that have implicit operands.
 	if (NN_cmpxchg == this->SMPcmd.itype) {
@@ -640,11 +663,11 @@ void SMPInstr::MDFixupDefUseLists(void) {
 	if (this->type == COND_BRANCH) {
 		assert(SMPUsesFlags[this->SMPcmd.itype]);
 	}
-	if (SMPDefsFlags[this->SMPcmd.itype]) {
+	if (!this->DefsFlags && SMPDefsFlags[this->SMPcmd.itype]) {
 		this->MDAddRegDef(X86_FLAGS_REG, false);
 		this->DefsFlags = true;
 	}
-	if (SMPUsesFlags[this->SMPcmd.itype]) {
+	if (!this->UsesFlags && SMPUsesFlags[this->SMPcmd.itype]) {
 		this->MDAddRegUse(X86_FLAGS_REG, false);
 		this->UsesFlags = true;
 	}
-- 
GitLab