コード例 #1
0
ファイル: handler.c プロジェクト: Aliandrana/snesdev
static void OneLine (const OpcDesc* D, const char* Arg, ...)
/* Output one line with the given mnemonic and argument */
{
    char Buf [256];
    va_list ap;

    /* Mnemonic */
    Mnemonic (D->Mnemo);

    /* Argument */
    va_start (ap, Arg);
    xvsprintf (Buf, sizeof (Buf), Arg, ap);
    va_end (ap);
    Indent (ACol);
    Output ("%s", Buf);

    /* Add the code stuff as comment */
    LineComment (PC, D->Size);

    /* End the line */
    LineFeed ();
}
コード例 #2
0
/**
 *  The algorithm finds conditional instruction (=condInst) first, then
 *  corresponding CMP instruction (=cmpInst) and arithmetic instruction (=inst)
 *  which affects flags in the same way as CMP. Combination is considered as
 *  available to be reduced if there are no instructions between CMP and
 *  arithmetic instruction which influence to flags or CMP operands.
 *
 *  Also it transforms some conditional instruction to make them more suitable
 *  for optimizations
 */
void
RCE::runImpl() 
{
    Inst * inst, * cmpInst, *condInst;
    Opnd * cmpOp = NULL; 
    cmpInst = condInst = NULL;
    const Nodes& nodes = irManager->getFlowGraph()->getNodesPostOrder();
    for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) {
        Node* node = *it;
        if (node->isBlockNode()) {
            if(node->isEmpty()) {
                continue;
            }
            cmpInst = NULL;
            Inst* prevInst = NULL;
            for(inst = (Inst*)node->getLastInst(); inst != NULL; inst = prevInst) {
                prevInst = inst->getPrevInst();
                //find conditional instruction
                Mnemonic baseMnem = getBaseConditionMnemonic(inst->getMnemonic());
                if (baseMnem != Mnemonic_NULL) {
                    condInst = condInst ? NULL : inst;
                    cmpInst = NULL;
                } else if (condInst) {
                    //find CMP instruction corresponds to conditional instruction
                    if(inst->getMnemonic() == Mnemonic_CMP || inst->getMnemonic() == Mnemonic_UCOMISD || inst->getMnemonic() == Mnemonic_UCOMISS) {
                        if (cmpInst) {
                            //this comparison is redundant because of overrided by cmpInst
                            inst->unlink();
                            continue;
                        }
                        cmpInst = inst;
                        U_32 defCount = inst->getOpndCount(Inst::OpndRole_InstLevel|Inst::OpndRole_Def);
                        if(inst->getOpnd(defCount+1)->isPlacedIn(OpndKind_Imm)) {
                            //try to change conditional instruction to make combination available to optimize
                            cmpOp = inst->getOpnd(defCount);
                            Inst * newCondInst = NULL; 
                            Mnemonic mnem;
                            int64 val = inst->getOpnd(defCount+1)->getImmValue();
                            
                            if (val == 0) {
                                continue;
                            } else if (val == 1 && ConditionMnemonic(condInst->getMnemonic()-getBaseConditionMnemonic(condInst->getMnemonic())) == ConditionMnemonic_L){
                                mnem = Mnemonic((condInst->getMnemonic() - Mnemonic(ConditionMnemonic_L)) + Mnemonic(ConditionMnemonic_LE));
                            } else if (val == -1 && ConditionMnemonic(condInst->getMnemonic()-getBaseConditionMnemonic(condInst->getMnemonic())) == ConditionMnemonic_G) {
                                mnem = Mnemonic((condInst->getMnemonic() - Mnemonic(ConditionMnemonic_G)) + Mnemonic(ConditionMnemonic_GE));
                            } else if (val == -1 && ConditionMnemonic(condInst->getMnemonic()-getBaseConditionMnemonic(condInst->getMnemonic())) == ConditionMnemonic_B) {
                                mnem = Mnemonic((condInst->getMnemonic() - Mnemonic(ConditionMnemonic_B)) + Mnemonic(ConditionMnemonic_BE));
                            } else {
                                continue;
                            }
                            //replace old conditional instruction
                            if (condInst->hasKind(Inst::Kind_BranchInst)) {
                                BranchInst* br = (BranchInst*)condInst;
                                newCondInst = irManager->newBranchInst(mnem,br->getTrueTarget(), br->getFalseTarget(), condInst->getOpnd(0));
                            } else {
                                Mnemonic condMnem = getBaseConditionMnemonic(condInst->getMnemonic());
                                Inst::Opnds defs(condInst,Inst::OpndRole_Def|Inst::OpndRole_Explicit);
                                if (condMnem == Mnemonic_CMOVcc) {
                                    Inst::Opnds uses(condInst,Inst::OpndRole_Use|Inst::OpndRole_Explicit);
                                    newCondInst = irManager->newInst(mnem, condInst->getOpnd(defs.begin()), inst->getOpnd(uses.begin()));
                                } else if (condMnem == Mnemonic_SETcc) {
                                    newCondInst = irManager->newInst(mnem, condInst->getOpnd(defs.begin()));
                                } else {
                                    assert(0);
                                    continue;
                                }
                            }
                            newCondInst->insertAfter(condInst);
                            condInst->unlink();
                            condInst = newCondInst;
                            inst->setOpnd(defCount+1, irManager->newImmOpnd(inst->getOpnd(defCount+1)->getType(),0));
                        } 
                    //find flags affected instruction precedes cmpInst
                    } else if (instAffectsFlagsAsCmpInst(inst, condInst)) {
                        if (cmpInst) {
                            if (isSuitableToRemove(inst, condInst, cmpInst, cmpOp))
                            {
                                cmpInst->unlink();
                            } 
                        }
                        condInst = NULL; // do not optimize cmpInst any more in this block
                    } else {
                        if (inst->getOpndCount(Inst::OpndRole_Implicit|Inst::OpndRole_Def) || inst->getMnemonic() == Mnemonic_CALL) {
                            // instruction affects flags, skip optimizing cmpInst
                            condInst = NULL;
                        } else {
                            //check for moving cmpInst operands 
                            if ((inst->getMnemonic() == Mnemonic_MOV) && (inst->getOpnd(0) == cmpOp)) {
                                cmpOp = inst->getOpnd(1);
                            }
                        }
                    } 
                }//end if/else by condInst
            }//end for() by Insts
        }//end if BasicBlock
    }//end for() by Nodes
}