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