123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- #include "xor_idioms.h"
- #include "dcc.h"
- #include "msvc_fixes.h"
- using namespace std;
- /*****************************************************************************
- * idiom21 - Assign long kte with high part zero
- * XOR regH, regH
- * MOV regL, kte
- * => regH:regL = kte
- * Eg: XOR dx, dx
- * MOV ax, 3
- * => dx:ax = 3
- * Note: only the following valid combinations are available:
- * dx:ax
- * cx:bx
- * Found in Borland Turbo C code.
- ****************************************************************************/
- bool Idiom21::match (iICODE picode)
- {
- LLOperand *dst, *src;
- if(distance(picode,m_end)<2)
- return false;
- m_icodes[0]=picode++;
- m_icodes[1]=picode++;
- if (not m_icodes[1]->ll()->testFlags(I))
- return false;
- dst = &m_icodes[0]->ll()->m_dst;
- src = &m_icodes[0]->ll()->src();
- if ((dst->regi == src->getReg2()) and (dst->getReg2() > 0) and (dst->getReg2() < INDEX_BX_SI))
- {
- if ((dst->getReg2() == rDX) and m_icodes[1]->ll()->match(rAX))
- return true;
- if ((dst->getReg2() == rCX) and m_icodes[1]->ll()->match(rBX))
- return true;
- }
- return false;
- }
- int Idiom21::action()
- {
- Expr *rhs;
- AstIdent *lhs;
- lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0],HIGH_FIRST, m_icodes[0], eDEF, *m_icodes[1]->ll());
- rhs = new Constant(m_icodes[1]->ll()->src().getImm2(), 4);
- m_icodes[0]->setAsgn(lhs, rhs);
- m_icodes[0]->du.use.reset(); /* clear register used in iXOR */
- m_icodes[1]->invalidate();
- return 2;
- }
- /*****************************************************************************
- * idiom7 - Assign zero
- * XOR reg/stackOff, reg/stackOff
- * Eg: XOR ax, ax
- * => ax = 0
- * Found in Borland Turbo C and Microsoft C code.
- ****************************************************************************/
- bool Idiom7::match(iICODE picode)
- {
- if(picode==m_end)
- return false;
- const LLOperand *dst, *src;
- m_icode=picode;
- dst = &picode->ll()->m_dst;
- src = &picode->ll()->src();
- if (dst->regi == 0) /* global variable */
- {
- if ((dst->segValue == src->segValue) and (dst->off == src->off))
- return true;
- }
- else if (dst->regi < INDEX_BX_SI) /* register */
- {
- if (dst->regi == src->regi)
- return true;
- }
- else if ((dst->off) and (dst->seg == rSS) and (dst->regi == INDEX_BP)) /* offset from BP */
- {
- if ((dst->off == src->off) and (dst->seg == src->seg) and (dst->regi == src->regi))
- return true;
- }
- return false;
- }
- int Idiom7::action()
- {
- Expr *lhs;
- lhs = AstIdent::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE);
- m_icode->setAsgn(dynamic_cast<AstIdent *>(lhs), new Constant(0, 2));
- m_icode->du.use.reset(); /* clear register used in iXOR */
- m_icode->ll()->setFlags(I);
- return 1;
- }
- /*****************************************************************************
- * idiom10 - Jump if not equal to 0
- * OR reg, reg
- * JNE labX
- * Eg: OR ax, ax
- * JNE labX
- * => CMP reg 0
- * JNE labX
- * This instruction is NOT converted into the equivalent high-level
- * instruction "HLI_JCOND (reg != 0) labX" because we do not know yet if
- * it forms part of a long register conditional test. It is therefore
- * modified to simplify the analysis.
- * Found in Borland Turbo C.
- ****************************************************************************/
- bool Idiom10::match(iICODE pIcode)
- {
- if(distance(pIcode,m_end)<2)
- return false;
- m_icodes[0]=pIcode++;
- m_icodes[1]=pIcode++;
- /* Check OR reg, reg */
- if (not m_icodes[0]->ll()->testFlags(I) and
- m_icodes[0]->ll()->src().isReg() and
- (m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->m_dst.getReg2()))
- if (m_icodes[1]->ll()->match(iJNE)) //.conditionalJump()
- {
- return true;
- }
- return false;
- }
- int Idiom10::action()
- {
- m_icodes[0]->ll()->set(iCMP,I);
- m_icodes[0]->ll()->replaceSrc(LLOperand::CreateImm2(0));
- m_icodes[0]->du.def.reset(); //TODO: this defines FLAGS
- m_icodes[0]->du1.clearAllDefs();
- //m_icodes[0]->du1.numRegsDef = 0;
- return 2;
- }
|