From 2db04f4efc7f0866906015d08b70855687878b7a Mon Sep 17 00:00:00 2001 From: clc5q <clc5q@git.zephyr-software.com> Date: Sat, 17 May 2008 03:12:12 +0000 Subject: [PATCH] Treat xor reg,reg as mov reg,0. --- SMPInstr.cpp | 61 ++++++++++++++++++++++++++++++++++++++++------------ SMPInstr.h | 7 ++++-- 2 files changed, 52 insertions(+), 16 deletions(-) diff --git a/SMPInstr.cpp b/SMPInstr.cpp index 6085406d..64bed3c2 100644 --- a/SMPInstr.cpp +++ b/SMPInstr.cpp @@ -198,6 +198,7 @@ SMPInstr::SMPInstr(ea_t addr) { this->BlockTerm = false; this->TailCall = false; this->Interrupt = false; + this->RegClearIdiom = false; this->DeadRegsString[0] = '\0'; this->DefsFlags = false; this->UsesFlags = false; @@ -710,6 +711,16 @@ void SMPInstr::Analyze(void) { this->Interrupt = ((NN_int == cmd.itype) || (NN_into == cmd.itype) || (NN_int3 == cmd.itype)); + // See if instruction is an ASM idiom for clearing a register. + if (NN_xor == this->SMPcmd.itype) { + ushort FirstReg; + if (o_reg == this->SMPcmd.Operands[0].type) { + FirstReg = this->SMPcmd.Operands[0].reg; + if (this->SMPcmd.Operands[1].is_reg(FirstReg)) + this->RegClearIdiom = true; + } + } + // Build the DEF and USE lists for the instruction. this->BuildSMPDefUseLists(); // Fix up machine dependent quirks in the def and use lists. @@ -781,6 +792,19 @@ void SMPInstr::BuildSMPDefUseLists(void) { } } // end for (OpNum = 0; ...) + if (this->RegClearIdiom) { + // Something like xor eax,eax clears eax but does not really + // use eax. It is the same as mov eax,0 and we don't want to + // extend the prior def-use chain for eax to this instruction + // by treating the instruction as xor eax,eax. Instead, we + // build the DEF and USE lists and RTL as if it were mov eax,0. + op_t ImmOp; + ImmOp.type = o_imm; + ImmOp.value = 0; + this->Uses.SetRef(ImmOp, NUMERIC); + return; + } + // Now, do the Uses. Uses have special case operations, because // any memory operand could have register uses in the addressing // expression, and we must create Uses for those registers. For @@ -816,7 +840,7 @@ void SMPInstr::BuildSMPDefUseLists(void) { } // end of SMPInstr::BuildSMPDefUseLists() // If DefReg is not already in the DEF list, add a DEF for it. -void SMPInstr::MDAddRegDef(ushort DefReg, bool Shown) { +void SMPInstr::MDAddRegDef(ushort DefReg, bool Shown, SMPOperandType Type) { op_t TempDef; TempDef.type = o_reg; TempDef.reg = DefReg; @@ -824,12 +848,12 @@ void SMPInstr::MDAddRegDef(ushort DefReg, bool Shown) { TempDef.set_showed(); else TempDef.clr_showed(); - this->Defs.SetRef(TempDef); + this->Defs.SetRef(TempDef, Type); return; } // end of SMPInstr::MDAddRegDef() // If UseReg is not already in the USE list, add a USE for it. -void SMPInstr::MDAddRegUse(ushort UseReg, bool Shown) { +void SMPInstr::MDAddRegUse(ushort UseReg, bool Shown, SMPOperandType Type) { op_t TempUse; TempUse.type = o_reg; TempUse.reg = UseReg; @@ -837,7 +861,7 @@ void SMPInstr::MDAddRegUse(ushort UseReg, bool Shown) { TempUse.set_showed(); else TempUse.clr_showed(); - this->Uses.SetRef(TempUse); + this->Uses.SetRef(TempUse, Type); return; } // end of SMPInstr::MDAddRegUse() @@ -948,8 +972,8 @@ void SMPInstr::MDFixupDefUseLists(void) { BaseOpnd.reg = R_cx; BaseOpnd.hasSIB = 0; BaseOpnd.clr_showed(); - this->Defs.SetRef(BaseOpnd); - this->Uses.SetRef(BaseOpnd); + this->Defs.SetRef(BaseOpnd, NUMERIC); + this->Uses.SetRef(BaseOpnd, NUMERIC); } if ((this->SMPcmd.itype == NN_cmps) || (this->SMPcmd.itype == NN_scas) || (this->SMPcmd.itype == NN_movs) || (this->SMPcmd.itype == NN_stos)) { @@ -961,12 +985,12 @@ void SMPInstr::MDFixupDefUseLists(void) { BaseOpnd.clr_showed(); if ((this->SMPcmd.itype == NN_cmps) || (this->SMPcmd.itype == NN_movs)) { BaseOpnd.reg = R_si; - this->Defs.SetRef(BaseOpnd); - this->Uses.SetRef(BaseOpnd); + this->Defs.SetRef(BaseOpnd, POINTER); + this->Uses.SetRef(BaseOpnd, POINTER); } BaseOpnd.reg = R_di; - this->Defs.SetRef(BaseOpnd); - this->Uses.SetRef(BaseOpnd); + this->Defs.SetRef(BaseOpnd, POINTER); + this->Uses.SetRef(BaseOpnd, POINTER); } // Now, handle special instruction categories that have implicit operands. @@ -1017,7 +1041,7 @@ void SMPInstr::MDFixupDefUseLists(void) { this->MDAddRegUse(R_bp, false); } else if (this->SMPcmd.itype == NN_maskmovq) { - this->MDAddRegUse(R_di, false); + this->MDAddRegUse(R_di, false, POINTER); } else if (8 == this->GetOptType()) { // This category implicitly writes to EDX:EAX. @@ -2753,9 +2777,18 @@ bool SMPInstr::BuildBinaryRTL(SMPoperator BinaryOp) { TempRT = new SMPRegTransfer; TempRT->SetLeftOperand(TempOp); TempRT->SetOperator(SMP_ASSIGN); - RightRT->SetLeftOperand(TempOp); - RightRT->SetOperator(BinaryOp); - TempRT->SetRightTree(RightRT); + if (this->RegClearIdiom) { + op_t ImmOp; + ImmOp.type = o_imm; + ImmOp.value = 0; + TempRT->SetRightOperand(ImmOp); + SourceFound = true; // cause loop exit + } + else { + RightRT->SetLeftOperand(TempOp); + RightRT->SetOperator(BinaryOp); + TempRT->SetRightTree(RightRT); + } } else { ; diff --git a/SMPInstr.h b/SMPInstr.h index ab661a2f..63e213ba 100644 --- a/SMPInstr.h +++ b/SMPInstr.h @@ -250,6 +250,7 @@ private: bool TailCall; // This instruction is a tail call (jump to far chunk with stack restored). bool CondTailCall; // Tail call is conditional branch. bool Interrupt; // Instruction is a software interrupt call. + bool RegClearIdiom; // ASM idiom for move zero into register? char DeadRegsString[MAXSTR]; // Registers that are dead at this instruction bool DefsFlags; // Instr DEFs the flags bool UsesFlags; // Instr USEs the flags @@ -264,8 +265,10 @@ private: bool AllDefsNumeric(void); // true if all DEFs are NUMERIC or CODEPTR void BuildSMPDefUseLists(void); // Build DEF and USE lists for instruction void MDFixupDefUseLists(void); // Machine-dependent ad hoc fixes - void MDAddRegDef(ushort, bool); // Add DEF of register if not already a DEF - void MDAddRegUse(ushort, bool); // Add USE of register if not already a USE + void MDAddRegDef(ushort DefReg, bool Shown, SMPOperandType Type = UNINIT); + // Add DEF of register if not already a DEF + void MDAddRegUse(ushort UseReg, bool Shown, SMPOperandType Type = UNINIT); + // Add USE of register if not already a USE void MDAnnotateSIBStackConstants(FILE *, op_t, ea_t, bool); // Handle x86 opcode SIB byte bool MDFindPointerUse(op_t MemOp, bool UseFP); // Set base reg to POINTER op_t MDGetMemUseOp(void); -- GitLab