void I8Lowerer::applyMnemonic()

in vm/jitrino/src/codegenerator/ia32/Ia32I8Lowerer.cpp [487:609]


void I8Lowerer::applyMnemonic(Inst* inst, Opnd* dst,  Opnd* dst_1,  Opnd* dst_2,
                                          Opnd* src1, Opnd* src1_1, Opnd* src1_2,
                                          Opnd* src2, Opnd* src2_1, Opnd* src2_2)
{
    Mnemonic mn = inst->getMnemonic();
    switch(mn) {
        case Mnemonic_ADD   :
            assert(dst_1 && src1_1 && src2_1);
            assert(dst_2 && src1_2 && src2_2);
            irManager->newInstEx(Mnemonic_ADD, 1, dst_1, src1_1, src2_1)->insertBefore(inst);
            irManager->newInstEx(Mnemonic_ADC, 1, dst_2, src1_2, src2_2)->insertBefore(inst);
            break;
        case Mnemonic_SUB   :
            assert(dst_1 && src1_1 && src2_1);
            assert(dst_2 && src1_2 && src2_2);
            irManager->newInstEx(Mnemonic_SUB, 1, dst_1, src1_1, src2_1)->insertBefore(inst);
            irManager->newInstEx(Mnemonic_SBB, 1, dst_2, src1_2, src2_2)->insertBefore(inst);
            break;
        case Mnemonic_AND   :
        case Mnemonic_OR    :
        case Mnemonic_XOR   :
            assert(dst_1 && src1_1 && src2_1);
            assert(dst_2 && src1_2 && src2_2);
        case Mnemonic_NOT   :
            assert(dst_1 && src1_1);
            assert(dst_2 && src1_2);
            irManager->newInstEx(mn, 1, dst_1, src1_1, src2_1)->insertBefore(inst);
            irManager->newInstEx(mn, 1, dst_2, src1_2, src2_2)->insertBefore(inst);
            break;
        case Mnemonic_MOV   :
            assert(dst_1 && src1_1);
            irManager->newCopyPseudoInst(Mnemonic_MOV, dst_1, src1_1)->insertBefore(inst);
            if (dst_2 && src1_2) {
                irManager->newCopyPseudoInst(Mnemonic_MOV, dst_2, src1_2)->insertBefore(inst);
            }
            break;
        case Mnemonic_MOVSX :
        case Mnemonic_MOVZX :
            assert(dst_1 && dst_2 && src1_1);
            assert(!src1_2);
            if (src1_1->getSize()<OpndSize_32){
                irManager->newInstEx(mn, 1, dst_1, src1_1)->insertBefore(inst);
            }else{
                assert(src1_1->getSize()==OpndSize_32);
                irManager->newInstEx(Mnemonic_MOV, 1, dst_1, src1_1)->insertBefore(inst);
            }
            if (mn==Mnemonic_MOVSX){
                // It's possible to substitute complex CDQ with a tight
                // constraints to the set of simpler instructions
                // with a wider constraints to let more freedom 
                // to regalloc and constraint resolver.
                // However, this seems does not change anything currently,
                // so leaving as-is.
                //test      low, low
                //setns     hi      ; if lo is positive, then load 1 into hi
                //sub       hi, 1   ; if lo is positive, then hi is now '0'. otherwise, it's -1
                irManager->newInstEx(Mnemonic_CDQ, 1, dst_2, dst_1)->insertBefore(inst);
            } else {
                //fill upper word with 0
                assert(mn == Mnemonic_MOVZX);
                Opnd* imm0=irManager->newImmOpnd(irManager->getTypeManager().getInt32Type(), 0);
                irManager->newInstEx(Mnemonic_MOV, 1, dst_2, imm0)->insertBefore(inst);
            }
            break;
        case Mnemonic_PUSH  :
            assert(src1_1);
            assert(src1_2);
            irManager->newInstEx(Mnemonic_PUSH, 0, src1_2)->insertBefore(inst);
            irManager->newInstEx(Mnemonic_PUSH, 0, src1_1)->insertBefore(inst);
            break;
        case Mnemonic_POP   :
            assert(dst_1);
            assert(dst_2);
            irManager->newInstEx(Mnemonic_POP, 1, dst_1)->insertBefore(inst);
            irManager->newInstEx(Mnemonic_POP, 1, dst_2)->insertBefore(inst);
            break;
        case Mnemonic_SHL   :
        {
            assert(dst && src1 && src2);
            buildShiftSubGraph(inst, src1_2, src1_1, src2, dst_2, dst_1, mn, Mnemonic_SHR);
            break;
        }
        case Mnemonic_SHR   :
        case Mnemonic_SAR   :
        {
            assert(dst && src1 && src2);
            buildShiftSubGraph(inst, src1_1, src1_2, src2, dst_1, dst_2, mn, Mnemonic_SHL);
            break;
        }
        case Mnemonic_CMP   :
        {
            assert(src1 && src2);
            Inst * condInst = inst->getNextInst();
            while (condInst && condInst->getMnemonic() == Mnemonic_MOV) {
                condInst = condInst->getNextInst();
            }
            Mnemonic mnem = condInst ? getBaseConditionMnemonic(condInst->getMnemonic()) : Mnemonic_NULL;
            if (mnem != Mnemonic_NULL) {
                        if(condInst->hasKind(Inst::Kind_BranchInst)) {
                            compareAndBranch(inst,src1_1,src1_2,src2_1,src2_2,condInst);
                        } else {
                            buildSetSubGraph(inst,src1_1,src1_2,src2_1,src2_2,condInst);
                        }
            } else {
                buildComplexSubGraph(inst,src1_1,src1_2,src2_1,src2_2);
            }
            break;
        }
        case Mnemonic_IMUL:
            lowerMul64(inst);
            break;
        case Mnemonic_IDIV:
            if (isI8RemInst(inst)) {
                lowerRem64(inst);
            }
            else {
                lowerDiv64(inst);
            }
            break;
        default :   
            assert(0);
    }
} // applyMnemonic