You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by va...@apache.org on 2007/02/20 08:05:14 UTC

svn commit: r509441 [2/3] - in /harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer: CodeSelectors.cpp CodeSelectors.h

Added: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp?view=auto&rev=509441
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeSelectors.cpp Mon Feb 19 23:05:13 2007
@@ -0,0 +1,2325 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Intel, Pavel A. Ozhdikhin
+ */
+
+#include "CodeSelectors.h"
+
+namespace Jitrino {
+
+void _VarCodeSelector::genCode(Callback& callback) {
+    VarOpnd * v0 = varOpnds;
+    if (v0) {
+        VarOpnd * v = v0;
+        do {
+            if (!(v->isDead())) {  // currently need to check, though dead items should be removed in future
+                assert(!(v->isDead()));
+                varIdMap[v->getId()] = 
+                    callback.defVar(v->getType(),v->isAddrTaken(),
+                    v->isPinned());
+                if(Log::isEnabled()) {
+                    Log::out() << "Opt var ";
+                    v->print(Log::out());
+                    Log::out() << " is CG var " << (int) varIdMap[v->getId()] << ::std::endl;
+                }
+            }
+            v=v->getNextVarOpnd();
+        } while (v != v0);
+    }
+
+    GCBasePointerMap::iterator i;
+    for(i = gcMap.begin(); i != gcMap.end(); ++i) {
+        if(Log::isEnabled()) {
+            Log::out() << "Set GC base of ";
+            i->first->print(Log::out());
+            Log::out() << "(" << (int) varIdMap[i->first->getId()] << ") to ";
+            i->second->print(Log::out());
+            Log::out() << "(" << (int) varIdMap[i->second->getId()] << ")" << ::std::endl;
+        }
+        callback.setManagedPointerBase(varIdMap[i->first->getId()], varIdMap[i->second->getId()]);
+    }
+}
+
+uint32 _VarCodeSelector::getNumVarOpnds() {
+    VarOpnd* v0 = varOpnds;
+    uint32 numVars = 0;
+    if (v0) {
+        VarOpnd* v = v0;
+        do {
+            if (!(v->isDead())) { // currently need to check, though in future dead items should be removed
+                assert(!(v->isDead()));
+                numVars++;
+            }
+            v = v->getNextVarOpnd();
+        } while (v != v0);
+    }
+    return numVars;
+}
+
+//
+// maps type and overflow modifier to a ArithmeticOp::Types
+//
+ArithmeticOp::Types _BlockCodeSelector::mapToArithmOpType(Inst* inst) {
+    Type::Tag type = inst->getType();
+    OverflowModifier modifier = inst->getOverflowModifier();
+    ExceptionModifier excModifier = inst->getExceptionModifier();
+    switch (type) {
+        case Type::Int32:
+            if ((modifier == Overflow_None) || (excModifier == Exception_Never))
+                return ArithmeticOp::I4;
+            if (modifier == Overflow_Signed)
+                return ArithmeticOp::I4_Ovf;
+            return ArithmeticOp::U4_Ovf;
+        case Type::Int64:
+            if ((modifier == Overflow_None) || (excModifier == Exception_Never))
+                return ArithmeticOp::I8;
+            if (modifier == Overflow_Signed)
+                return ArithmeticOp::I8_Ovf;
+            return ArithmeticOp::U8_Ovf;
+        case Type::IntPtr:
+        case Type::UIntPtr:
+            if ((modifier == Overflow_None) || (excModifier == Exception_Never))
+                return ArithmeticOp::I;
+            if (modifier == Overflow_Signed)
+                return ArithmeticOp::I_Ovf;
+            return ArithmeticOp::U_Ovf;
+        case Type::Float:
+            return ArithmeticOp::F;
+        case Type::Single:
+            return ArithmeticOp::S;
+        case Type::Double:
+            return ArithmeticOp::D;
+        default: assert(0);
+    }
+    assert(0);
+    return ArithmeticOp::I;    // to keep the compiler quiet
+}
+ 
+//
+//  maps type and overflow modifier to a RefArithmeticOp::Type
+//
+RefArithmeticOp::Types _BlockCodeSelector::mapToRefArithmOpType(Inst* inst, Opnd *src) {
+    Type::Tag type = src->getType()->tag;
+    OverflowModifier modifier = inst->getOverflowModifier();
+    ExceptionModifier excModifier = inst->getExceptionModifier();
+    assert(modifier != Overflow_Signed);
+    switch (type) {
+        case Type::Int32:
+            if ((modifier == Overflow_None) || (excModifier == Exception_Never))
+                return RefArithmeticOp::I4;
+            return RefArithmeticOp::U4_Ovf;
+        case Type::IntPtr:
+            if ((modifier == Overflow_None) || (excModifier == Exception_Never))
+                return RefArithmeticOp::I;
+            return RefArithmeticOp::U_Ovf;
+        default: assert(0);
+    }
+    assert(0);
+    return RefArithmeticOp::I;    // to keep the compiler quiet
+}
+
+//
+//  checks if instruction has an overflow modifier
+//
+bool _BlockCodeSelector::isOverflow(Inst* inst) {
+    Modifier mod = inst->getModifier();
+    if (mod.hasOverflowModifier()) {
+        OverflowModifier modifier = mod.getOverflowModifier();
+        return modifier != Overflow_None;
+    } else
+        return false;
+}
+
+//
+//  checks if instruction has an exception modifier that can never except
+//
+bool _BlockCodeSelector::isExceptionNever(Inst* inst) {
+    Modifier mod = inst->getModifier();
+    if (mod.hasExceptionModifier()) {
+        ExceptionModifier modifier = mod.getExceptionModifier();
+        return modifier == Exception_Never;
+    } else
+        return false;
+}
+
+//
+//  checks if instruction is unsigned
+//
+bool _BlockCodeSelector::isUnsigned(Inst *inst) {
+    Modifier mod = inst->getModifier();
+    if (mod.hasSignedModifier()) {
+        SignedModifier modifier = mod.getSignedModifier();
+        return modifier == UnsignedOp;
+    } else {
+        assert(0);
+        return false;
+    }
+}
+
+//
+// checks if shift instruction needs shift mask
+//
+bool _BlockCodeSelector::isShiftMask(Inst *inst) {
+    assert(inst->getModifier().hasShiftMaskModifier());
+    ShiftMaskModifier modifier = inst->getModifier().getShiftMaskModifier();
+    return modifier == ShiftMask_Masked;
+}
+
+DivOp::Types _BlockCodeSelector::mapToDivOpType(Inst* inst) {
+    Type::Tag type = inst->getType();
+    SignedModifier modifier = inst->getSignedModifier();
+    bool unsignedDiv = (modifier == UnsignedOp);
+
+    switch (type) {
+        case Type::Int32: 
+            return unsignedDiv ? DivOp::U4 : DivOp::I4;
+        case Type::Int64:
+            return unsignedDiv ? DivOp::U8 : DivOp::I8;
+        case Type::IntPtr:
+            return unsignedDiv ? DivOp::U  : DivOp::I;
+        case Type::Float:
+            return DivOp::F;
+        case Type::Single:
+            return DivOp::S;
+        case Type::Double:
+            return DivOp::D;
+        default: assert(0);
+    }
+    assert(0);
+    return DivOp::I; // to keep compiler quiet
+}
+
+MulHiOp::Types _BlockCodeSelector::mapToMulHiOpType(Inst * inst) {
+    Type::Tag type = inst->getType();
+    SignedModifier modifier = inst->getSignedModifier();
+    bool unsignedMulhi = (modifier == UnsignedOp);
+
+    switch (type) {
+        case Type::Int32: 
+            return unsignedMulhi ? MulHiOp::U4 : MulHiOp::I4;
+        case Type::Int64:
+            return unsignedMulhi ? MulHiOp::U8 : MulHiOp::I8;
+        case Type::IntPtr:
+            return unsignedMulhi ? MulHiOp::U  : MulHiOp::I;
+        default: assert(0);
+    }
+    assert(0);
+    return MulHiOp::I; // to keep compiler quiet
+}
+    
+NegOp::Types _BlockCodeSelector::mapToNegOpType(Inst* inst) {
+    Type::Tag type = inst->getType();
+    switch(type) {
+        case Type::Int32:
+            return NegOp::I4;
+        case Type::Int64:
+            return NegOp::I8;
+        case Type::IntPtr:
+            return NegOp::I;
+        case Type::Float:
+            return NegOp::F;
+        case Type::Single:
+            return NegOp::S;
+        case Type::Double:
+            return NegOp::D;
+        default: assert(0);
+    }
+    assert(0);
+    return NegOp::I; // to keep compiler quiet
+}
+
+//
+//  Maps instruction type to IntegerOp::Types
+//
+IntegerOp::Types _BlockCodeSelector::mapToIntegerOpType(Inst* inst) {
+    Type::Tag type = inst->getType();
+    switch (type) {
+        case Type::Int32: 
+            return IntegerOp::I4;
+        case Type::Int64:
+            return IntegerOp::I8;
+        case Type::IntPtr:
+        case Type::UIntPtr:
+            return IntegerOp::I;
+        default: assert(0);
+    }
+    assert(0);
+    return IntegerOp::I; // to keep compiler quiet
+}
+
+//
+//  maps type to CompareOp::Types
+//
+CompareOp::Types _BlockCodeSelector::mapToCompareOpType(Inst* inst) {
+    Type::Tag type = inst->getType();
+    switch (type) {
+        case Type::Int32: 
+            return CompareOp::I4;
+        case Type::Int64:
+            return CompareOp::I8;
+        case Type::IntPtr:
+        case Type::UIntPtr:
+            return CompareOp::I;
+        case Type::Float:
+            return CompareOp::F;
+        case Type::Single:
+            return CompareOp::S;
+        case Type::Double:
+            return CompareOp::D;
+        default: 
+
+            assert(Type::isReference(type));
+            return CompareOp::Ref;
+    }
+}
+
+//
+//  maps type to CompareZeroOp::Types
+//
+CompareZeroOp::Types _BlockCodeSelector::mapToCompareZeroOpType(Inst *inst) {
+    Type::Tag type = inst->getType();
+    switch (type) {
+        case Type::Int32:
+            return CompareZeroOp::I4;
+        case Type::Int64:
+            return CompareZeroOp::I8;
+        case Type::IntPtr:
+            return CompareZeroOp::I;
+        default:
+            assert(Type::isReference(type));
+            return CompareZeroOp::Ref;
+    }
+}
+
+//
+//  Maps compare inst to the CompareOp::Operator
+//
+CompareOp::Operators _BlockCodeSelector::mapToComparisonOp(Inst* inst) {
+    ComparisonModifier modifier = inst->getComparisonModifier();
+    switch (modifier) {
+        case    Cmp_EQ:     return CompareOp::Eq;
+        case    Cmp_NE_Un:    return CompareOp::Ne;
+        case    Cmp_GT:        return CompareOp::Gt;
+        case    Cmp_GT_Un:    return CompareOp::Gtu;
+        case    Cmp_GTE:    return CompareOp::Ge;
+        case    Cmp_GTE_Un:    return CompareOp::Geu;
+            // unary boolean comparisons
+        case    Cmp_Zero:
+        case    Cmp_NonZero:
+        default:
+            assert(0);
+    }
+    return CompareOp::Eq;    // to keep compiler quiet
+}
+
+//
+//  Maps instruction to ConvertToFpOp::Types
+//
+ConvertToFpOp::Types _BlockCodeSelector::mapToFpConvertOpType(Inst *inst) {
+    Type::Tag type = inst->getType();
+    switch (type) {
+        case Type::Single: return ConvertToFpOp::Single;
+        case Type::Double: return ConvertToFpOp::Double;
+        case Type::Float:  return ConvertToFpOp::FloatFromUnsigned;
+        default: assert(0);
+    }
+    assert(0);
+    return ConvertToFpOp::Single;   // to keep the compiler quiet
+}
+
+//
+//  Maps instruction to ConvertToIntOp::Types
+//
+ConvertToIntOp::Types _BlockCodeSelector::mapToIntConvertOpType(Inst *inst) {
+    Type::Tag type = inst->getType();
+    switch (type) {
+        case Type::Int8: 
+        case Type::UInt8: 
+            return ConvertToIntOp::I1;
+        case Type::Int16: 
+        case Type::UInt16: 
+            return ConvertToIntOp::I2;
+        case Type::Int32: 
+        case Type::UInt32: 
+            return ConvertToIntOp::I4;
+        case Type::Int64: 
+        case Type::UInt64: 
+            return ConvertToIntOp::I8;
+        case Type::IntPtr: 
+        case Type::UIntPtr: 
+            return ConvertToIntOp::I;
+        default: assert(0);
+    }
+    assert(0);
+    return ConvertToIntOp::I;    // to keep the compiler quiet
+}
+
+//
+//  Maps instruction to ConvertToIntOp::OverflowMod
+//  
+ConvertToIntOp::OverflowMod _BlockCodeSelector::mapToIntConvertOvfMod(Inst *inst) {
+    if (isExceptionNever(inst)) { return ConvertToIntOp::NoOvf; };
+    OverflowModifier modifier = inst->getOverflowModifier();
+    switch (modifier) {
+    case Overflow_None:
+        return ConvertToIntOp::NoOvf;
+    case Overflow_Signed:
+        return ConvertToIntOp::SignedOvf;
+    case Overflow_Unsigned:
+        return ConvertToIntOp::UnsignedOvf;
+default: assert(0);
+    }
+    return ConvertToIntOp::NoOvf;    // to keep the compiler quiet
+}
+
+//
+//  Maps intrinsic id
+//
+IntrinsicCallOp::Id _BlockCodeSelector::convertIntrinsicId(IntrinsicCallId callId) {
+    switch(callId) {
+    case CharArrayCopy:      return IntrinsicCallOp::CharArrayCopy;
+    case ArrayCopyDirect:    return IntrinsicCallOp::ArrayCopyDirect;
+    case ArrayCopyReverse:   return IntrinsicCallOp::ArrayCopyReverse;
+    }
+    assert(0);
+    return IntrinsicCallOp::CharArrayCopy; // to keep compiler quiet
+}
+
+JitHelperCallOp::Id _BlockCodeSelector::convertJitHelperId(JitHelperCallId callId) {
+    switch(callId) {
+    case InitializeArray: return JitHelperCallOp::InitializeArray;
+    case PseudoCanThrow: return JitHelperCallOp::PseudoCanThrow;
+    case SaveThisState: return JitHelperCallOp::SaveThisState;
+    case ReadThisState: return JitHelperCallOp::ReadThisState;
+    case LockedCompareAndExchange: return JitHelperCallOp::LockedCompareAndExchange;
+    case AddValueProfileValue: return JitHelperCallOp::AddValueProfileValue;
+    }
+    assert(0);
+    return JitHelperCallOp::InitializeArray; // to keep compiler quiet
+}
+    
+CG_OpndHandle ** _BlockCodeSelector::genCallArgs(Inst * call, uint32 arg0Pos) {
+    uint32 nSrc = call->getNumSrcOperands();
+    CG_OpndHandle ** args = new(memManager) CG_OpndHandle*[nSrc - arg0Pos];
+    for (uint32 i = arg0Pos; i < nSrc; i++)
+        args[i - arg0Pos] = getCGInst(call->getSrc(i));
+    return args;
+}
+    
+CG_OpndHandle ** _BlockCodeSelector::genCallArgs(Opnd *extraArg, Inst * call, uint32 arg0Pos) {
+    uint32 nSrc = call->getNumSrcOperands();
+    CG_OpndHandle ** args = new(memManager) CG_OpndHandle*[nSrc - arg0Pos + 1];
+    args[0] = getCGInst(extraArg);
+    for (uint32 i = arg0Pos; i < nSrc; i++)
+        args[i - arg0Pos + 1] = getCGInst(call->getSrc(i));
+    return args;
+}
+
+void _BlockCodeSelector::genInstCode(InstructionCallback& instructionCallback,
+                                     Inst *inst, bool genConsts)
+{
+    if(Log::isEnabled()) {
+        Log::out() << "genInstCode ";
+        inst->print(Log::out());
+        if (genConsts) {
+            Log::out() << "; genConsts=true" << ::std::endl;
+        } else {
+            Log::out() << "; genConsts=false" << ::std::endl;
+        }
+    }
+
+    CG_OpndHandle* cgInst = NULL;
+    Opnd *dst = inst->getDst();
+    bool isConstant = false;
+    switch(inst->getOpcode()) {
+        case Op_Add:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                Opnd* src1 = inst->getSrc(0);
+                Opnd* src2 = inst->getSrc(1);
+                CG_OpndHandle* src1CGInst = getCGInst(src1);
+                CG_OpndHandle* src2CGInst = getCGInst(src2);
+                if (src1->getType()->isReference()) {
+                    cgInst = instructionCallback.addRef(mapToRefArithmOpType(inst,src2),
+                        src1CGInst,src2CGInst);
+                } else {
+                    cgInst = instructionCallback.add(mapToArithmOpType(inst),
+                        src1CGInst,src2CGInst);
+                }
+            }
+            break;
+        case Op_Mul:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.mul(mapToArithmOpType(inst),
+                    getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
+        case Op_Sub:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                Opnd *src1 = inst->getSrc(0);
+                Opnd *src2 = inst->getSrc(1);
+                CG_OpndHandle* src1CGInst = getCGInst(src1);
+                CG_OpndHandle* src2CGInst = getCGInst(src2);
+
+                if (src1->getType()->isReference()) {
+                    if (src2->getType()->isReference()) {
+                        cgInst = instructionCallback.diffRef(isOverflow(inst) && !isExceptionNever(inst),
+                            src1CGInst,
+                            src2CGInst);
+                    }
+                    else {
+                        cgInst = instructionCallback.subRef(mapToRefArithmOpType(inst,src2),
+                            src1CGInst,
+                            src2CGInst);
+                    }
+                }
+                else {
+                    cgInst = instructionCallback.sub(mapToArithmOpType(inst),
+                        src1CGInst,
+                        src2CGInst);
+                }
+            }
+            break;
+        case Op_TauDiv:
+            {
+                assert(inst->getNumSrcOperands() == 3);
+                Opnd *tauOpnd = inst->getSrc(2);
+                assert(tauOpnd->getType()->tag == Type::Tau);
+                cgInst = instructionCallback.tau_div(mapToDivOpType(inst),
+                    getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)),
+                    getCGInst(tauOpnd));
+            }
+            break;
+        case Op_TauRem:
+            {
+                assert(inst->getNumSrcOperands() == 3);
+                Opnd *tauOpnd = inst->getSrc(2);
+                assert(tauOpnd->getType()->tag == Type::Tau);
+
+                cgInst = instructionCallback.tau_rem(mapToDivOpType(inst),
+                    getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)),
+                    getCGInst(tauOpnd));
+            }
+            break;
+        case Op_Neg:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                cgInst = instructionCallback.neg(mapToNegOpType(inst),
+                    getCGInst(inst->getSrc(0)));
+            }
+            break;
+        case Op_MulHi:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.mulhi(mapToMulHiOpType(inst),
+                    getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
+        case Op_Min:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.min_op(mapToNegOpType(inst),
+                    getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
+        case Op_Max:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.max_op(mapToNegOpType(inst),
+                    getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
+        case Op_Abs:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                cgInst = instructionCallback.abs_op(mapToNegOpType(inst),
+                    getCGInst(inst->getSrc(0)));
+            }
+            break;
+        case Op_TauCheckFinite:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                cgInst = instructionCallback.tau_ckfinite(getCGInst(inst->getSrc(0)));
+            }
+            break;
+        case Op_And:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.and_(mapToIntegerOpType(inst),
+                    getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
+        case Op_Or:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.or_(mapToIntegerOpType(inst),
+                    getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
+        case Op_Xor:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.xor_(mapToIntegerOpType(inst),
+                    getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
+        case Op_Not:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                cgInst = instructionCallback.not_(mapToIntegerOpType(inst),
+                    getCGInst(inst->getSrc(0)));
+            }
+            break;
+        case Op_Select:
+            {
+                assert(inst->getNumSrcOperands() == 3);
+                cgInst = instructionCallback.select(mapToCompareOpType(inst),
+                    getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)),
+                    getCGInst(inst->getSrc(2)));
+            }
+            break;
+        case Op_Conv:
+        case Op_ConvUnmanaged:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                Type * dstType = inst->getDst()->getType();
+                if (dstType->isFP()) {
+                    cgInst = instructionCallback.convToFp(mapToFpConvertOpType(inst),
+                        dstType,
+                        getCGInst(inst->getSrc(0)));
+                } else if (dstType->isObject()){
+                    cgInst = instructionCallback.convUPtrToObject(dstType->asObjectType(), getCGInst(inst->getSrc(0)));
+                } else if (dstType->isUnmanagedPtr()) {
+                    cgInst = instructionCallback.convToUPtr(dstType->asPtrType(), getCGInst(inst->getSrc(0)));
+                } else {
+                    bool isSigned = Type::isSignedInteger(inst->getType());
+                    cgInst = instructionCallback.convToInt(mapToIntConvertOpType(inst),
+                        isSigned, 
+                        mapToIntConvertOvfMod(inst), 
+                        dstType,
+                        getCGInst(inst->getSrc(0)));
+                }
+            }
+            break;    
+        case Op_Shladd:
+            {
+                assert(inst->getNumSrcOperands() == 3);
+                Opnd *op1 = inst->getSrc(1);
+                ConstInst *op1ci = op1->getInst()->asConstInst();
+                assert(op1ci);
+                assert(op1ci->getType() == Type::Int32);
+                int32 shiftby = op1ci->getValue().i4;
+                cgInst = instructionCallback.shladd(mapToIntegerOpType(inst),
+                    getCGInst(inst->getSrc(0)),
+                    shiftby,
+                    getCGInst(inst->getSrc(2)));
+            }
+            break;
+        case Op_Shl:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.shl(mapToIntegerOpType(inst),
+                    getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
+        case Op_Shr:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                IntegerOp::Types opType = mapToIntegerOpType(inst);
+                CG_OpndHandle* src1CGInst = getCGInst(inst->getSrc(0));
+                CG_OpndHandle* src2CGInst = getCGInst(inst->getSrc(1));
+
+                if (isUnsigned(inst))
+                    cgInst = instructionCallback.shru(opType,src1CGInst,src2CGInst);
+                else
+                    cgInst = instructionCallback.shr(opType,src1CGInst,src2CGInst); 
+            }
+            break;
+        case Op_Cmp:
+            {
+                if (inst->getNumSrcOperands() == 2) {
+                    // binary comparison
+                    CompareOp::Operators cmpOp = mapToComparisonOp(inst);
+                    CompareOp::Types opType = mapToCompareOpType(inst);
+                    cgInst = instructionCallback.cmp(cmpOp, opType,
+                        getCGInst(inst->getSrc(0)),
+                        getCGInst(inst->getSrc(1)));
+                } else {
+                    assert(inst->getNumSrcOperands() == 1);
+                    // unary comparison against zero
+                    if (inst->getComparisonModifier() == Cmp_Zero) {
+                        cgInst = instructionCallback.czero(mapToCompareZeroOpType(inst),
+                            getCGInst(inst->getSrc(0)));
+                    } else {
+                        // Nonzero
+                        cgInst = instructionCallback.cnzero(mapToCompareZeroOpType(inst),
+                            getCGInst(inst->getSrc(0)));
+                    }
+                }
+            }
+            break;
+        case Op_Cmp3:
+            {
+#ifndef BACKEND_HAS_CMP3                
+
+                // always binary comparison
+                CompareOp::Types opType = mapToCompareOpType(inst);
+                CompareOp::Operators cmpOp = mapToComparisonOp(inst);
+                CompareOp::Operators cmpOp2 = cmpOp;
+
+                int ifNaNResult = -1;
+                if (cmpOp == CompareOp::Gtu || cmpOp == CompareOp::Geu)
+                    ifNaNResult = 1;
+
+                CG_OpndHandle* cgInst1 = 
+                    instructionCallback.cmp(cmpOp, opType,
+                    getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)), ifNaNResult);
+
+                // second operator has opposite NaN behavior for Floats
+                if ((opType==CompareOp::F) ||
+                    (opType==CompareOp::S) ||
+                    (opType==CompareOp::D)) {
+                        switch (cmpOp) {
+        case CompareOp::Gt: cmpOp2 = CompareOp::Gtu; ifNaNResult = 1; break;
+        case CompareOp::Gtu: cmpOp2 = CompareOp::Gt; ifNaNResult = -1; break;
+        case CompareOp::Ge: cmpOp2 = CompareOp::Geu; ifNaNResult = 1; break;
+        case CompareOp::Geu: cmpOp2 = CompareOp::Ge; ifNaNResult = -1; break;
+        default: break;
+                        };
+                    }
+
+                    CG_OpndHandle* cgInst2 = 
+                        instructionCallback.cmp(cmpOp2, opType, 
+                        getCGInst(inst->getSrc(1)),
+                        getCGInst(inst->getSrc(0)), ifNaNResult);
+                    cgInst = 
+                        instructionCallback.sub(ArithmeticOp::I4,
+                        cgInst1,
+                        cgInst2);
+#else
+                // always binary comparison
+                CompareOp::Operators cmpOp = mapToComparisonOp(inst);
+                CompareOp::Types opType = mapToCompareOpType(inst);
+                cgInst = instructionCallback.cmp3(cmpOp, opType,
+                    getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+#endif
+            }
+            break;
+        case Op_Branch:
+            {
+                if (inst->getNumSrcOperands() == 2) {
+                    // binary comparison
+                    instructionCallback.branch(mapToComparisonOp(inst),
+                        mapToCompareOpType(inst),
+                        getCGInst(inst->getSrc(0)),
+                        getCGInst(inst->getSrc(1)));
+                } else {
+                    assert(inst->getNumSrcOperands() == 1);
+                    // unary comparison against zero
+                    if (inst->getComparisonModifier() == Cmp_Zero) {
+                        instructionCallback.bzero(mapToCompareZeroOpType(inst),
+                            getCGInst(inst->getSrc(0)));
+                    } else {
+                        // Nonzero
+                        instructionCallback.bnzero(mapToCompareZeroOpType(inst),
+                            getCGInst(inst->getSrc(0)));
+                    }
+                }
+            }
+            break;
+        case Op_Jump: 
+            {    
+                instructionCallback.jump();
+            }
+            break; 
+        case Op_Switch: 
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                SwitchInst *swInst = (SwitchInst *)inst;
+                instructionCallback.tableSwitch(getCGInst(inst->getSrc(0)),
+                    swInst->getNumTargets());
+            }
+            break; 
+        case Op_DirectCall:
+            {
+                assert(inst->getNumSrcOperands() >= 2);
+                Opnd *tauNullChecked = inst->getSrc(0);
+                assert(tauNullChecked->getType()->tag == Type::Tau);
+                Opnd *tauTypesChecked = inst->getSrc(1);
+                assert(tauTypesChecked->getType()->tag == Type::Tau);
+
+                MethodCallInst * call = (MethodCallInst *)inst;
+                MethodDesc * methodDesc = call->getMethodDesc();
+                CG_OpndHandle ** args = genCallArgs(call,2); // omit tau operands
+                uint32 numArgs = inst->getNumSrcOperands()-2; // also omit from count
+                cgInst = 
+                    instructionCallback.tau_call(numArgs,
+                    args,
+                    inst->getDst()->getType(),
+                    methodDesc,
+                    getCGInst(tauNullChecked),
+                    getCGInst(tauTypesChecked),
+                    call->getInlineInfoPtr());
+            }
+            break;
+        case Op_TauVirtualCall:
+            {
+                assert(inst->getNumSrcOperands() >= 3);
+                Opnd *tauNullChecked = inst->getSrc(0);
+                Opnd *tauTypesChecked = inst->getSrc(1);
+                assert(tauNullChecked->getType()->tag == Type::Tau);
+                assert(tauTypesChecked->getType()->tag == Type::Tau);
+
+                MethodCallInst * call = (MethodCallInst *)inst;
+                MethodDesc * methodDesc = call->getMethodDesc();
+                cgInst = 
+                    instructionCallback.tau_callvirt(inst->getNumSrcOperands()-2, // omit taus
+                    genCallArgs(call, 2), // omit taus
+                    inst->getDst()->getType(),
+                    methodDesc,
+                    getCGInst(tauNullChecked),
+                    getCGInst(tauTypesChecked),
+                    call->getInlineInfoPtr());
+            }
+            break;
+        case Op_IndirectCall:
+            {
+                assert(inst->getNumSrcOperands() >= 3);
+                Opnd *fnAddr = inst->getSrc(0);
+                Opnd *tauNullChecked = inst->getSrc(1);
+                Opnd *tauTypesChecked = inst->getSrc(2);
+                assert(tauNullChecked->getType()->tag == Type::Tau);
+                assert(tauTypesChecked->getType()->tag == Type::Tau);
+                assert(inst->isCall());
+                CallInst * call = inst->asCallInst();
+                cgInst = 
+                    instructionCallback.tau_calli(inst->getNumSrcOperands() - 3, // omit taus and fnAddr
+                    genCallArgs(inst, 3), // omit taus and fnAddr
+                    inst->getDst()->getType(),
+                    getCGInst(fnAddr),
+                    getCGInst(tauNullChecked),
+                    getCGInst(tauTypesChecked),
+                    call->getInlineInfoPtr());
+            }
+            break;
+        case Op_IndirectMemoryCall:
+            {
+                assert(inst->getNumSrcOperands() >= 3);
+                Opnd *fnAddr = inst->getSrc(0);
+                Opnd *tauNullChecked = inst->getSrc(1);
+                Opnd *tauTypesChecked = inst->getSrc(2);
+                assert(tauNullChecked->getType()->tag == Type::Tau);
+                assert(tauTypesChecked->getType()->tag == Type::Tau);
+                assert(inst->isCall());
+                CallInst * call = inst->asCallInst();
+                cgInst = 
+                    instructionCallback.tau_calli(inst->getNumSrcOperands() - 3, // omit taus andfnAddr
+                    genCallArgs(inst, 3), // omit taus and fnAddr
+                    inst->getDst()->getType(),
+                    getCGInst(fnAddr),
+                    getCGInst(tauNullChecked),
+                    getCGInst(tauTypesChecked),
+                    call->getInlineInfoPtr());
+            }
+            break;
+        case Op_IntrinsicCall:
+            {
+                assert(inst->getNumSrcOperands() >= 2);
+                Opnd *tauNullChecked = inst->getSrc(0);
+                Opnd *tauTypesChecked = inst->getSrc(1);
+                assert(tauNullChecked->getType()->tag == Type::Tau);
+                assert(tauTypesChecked->getType()->tag == Type::Tau);
+
+                IntrinsicCallInst * call = (IntrinsicCallInst *)inst;
+                IntrinsicCallId callId = call->getIntrinsicId();
+
+                if (callId == ArrayCopyDirect)
+                {
+                    cgInst = 
+                        instructionCallback.arraycopy(inst->getNumSrcOperands()-2, // omit taus
+                        genCallArgs(call,2) // omit taus
+                        );
+                } else if (callId == ArrayCopyReverse)
+                {
+                    cgInst = 
+                        instructionCallback.arraycopyReverse(inst->getNumSrcOperands()-2, // omit taus
+                        genCallArgs(call,2) // omit taus
+                        );
+                } else {
+
+                    cgInst = 
+                        instructionCallback.tau_callintr(inst->getNumSrcOperands()-2, // omit taus
+                        genCallArgs(call,2), // omit taus
+                        inst->getDst()->getType(),
+                        convertIntrinsicId(callId),
+                        getCGInst(tauNullChecked),
+                        getCGInst(tauTypesChecked));
+                }
+
+            }
+            break;
+        case Op_JitHelperCall:
+            {
+                JitHelperCallInst* call = inst->asJitHelperCallInst();
+                JitHelperCallId callId = call->getJitHelperId();
+
+                if( callId == PseudoCanThrow ){
+                    instructionCallback.pseudoInst();
+
+                } else {
+                    cgInst = 
+                        instructionCallback.callhelper(inst->getNumSrcOperands(),
+                        genCallArgs(call,0),
+                        inst->getDst()->getType(),
+                        convertJitHelperId(callId));
+                }
+            }
+            break;
+        case Op_VMHelperCall:
+            {
+                VMHelperCallInst* call = inst->asVMHelperCallInst();
+                CompilationInterface::RuntimeHelperId callId = call->getVMHelperId();
+                cgInst = 
+                    instructionCallback.callvmhelper(inst->getNumSrcOperands(),
+                    genCallArgs(call,0),
+                    inst->getDst()->getType(),
+                    callId);
+            }
+            break;
+        case Op_Return:
+            {
+                if (inst->getType() == Type::Void) {
+                    instructionCallback.ret();
+                } else {
+                    instructionCallback.ret(getCGInst(inst->getSrc(0)));
+                }
+            }
+            break;
+        case Op_Leave:
+            {
+                assert(0);
+                instructionCallback.jump(); 
+            }
+            break;
+        case Op_Throw:
+            {
+                instructionCallback.throwException(getCGInst(inst->getSrc(0)), inst->getThrowModifier() == Throw_CreateStackTrace);
+            }
+            break;
+        case Op_ThrowSystemException:
+            {
+                TokenInst *tokenInst = (TokenInst *)inst;
+                uint32 token = tokenInst->getToken();
+                CompilationInterface::SystemExceptionId id 
+                    = (CompilationInterface::SystemExceptionId)token;
+                instructionCallback.throwSystemException(id);
+            }
+            break;
+        case Op_ThrowLinkingException:
+            {
+                LinkingExcInst *linkExcInst = (LinkingExcInst *)inst;
+                Class_Handle encClass = linkExcInst->getEnclosingClass();
+                uint32 constPoolIndex = linkExcInst->getCPIndex();
+                uint32 opcode = linkExcInst->getOperation();
+                instructionCallback.throwLinkingException(encClass, constPoolIndex, opcode);
+            }
+            break;
+        case Op_Catch:
+            cgInst = instructionCallback.catchException(inst->getDst()->getType());
+            break;
+        case Op_EndFinally:
+            assert(0); 
+            break;
+        case Op_EndFilter:
+            assert(0); 
+            break;
+        case Op_EndCatch:
+            instructionCallback.endCatch();
+            break;
+        case Op_Copy:
+            {
+                cgInst = instructionCallback.copy(getCGInst(inst->getSrc(0)));
+            }
+            break;
+        case Op_DefArg:
+            {
+                cgInst = instructionCallback.defArg(argCount,
+                    inst->getDst()->getType());
+                argCount += 1;
+            }
+            break;
+        case Op_LdConstant:
+            {
+                if (!genConsts) break;
+                ConstInst* constInst = (ConstInst*)inst;
+                switch (inst->getType()) {
+        case Type::UIntPtr://mfursov todo!
+        case Type::IntPtr://mfursov todo!
+        case Type::UnmanagedPtr://mfursov todo!
+        case Type::Int32:
+            cgInst = instructionCallback.ldc_i4(constInst->getValue().i4);
+            break;
+        case Type::Int64:
+            cgInst = instructionCallback.ldc_i8(constInst->getValue().i8);
+            break;
+        case Type::Single:
+            cgInst = instructionCallback.ldc_s(constInst->getValue().s);
+            break;
+        case Type::Double:
+            cgInst = instructionCallback.ldc_d(constInst->getValue().d);
+            break;
+        case Type::NullObject:
+            cgInst = instructionCallback.ldnull(false);
+            break;
+        case Type::CompressedNullObject:
+            cgInst = instructionCallback.ldnull(true);
+            break;
+        default: assert(0);
+                }
+                isConstant = true;
+            }
+            break;
+        case Op_LdRef:
+            {
+                if (!genConsts) break;
+
+                AutoCompressModifier acmod = inst->getAutoCompressModifier();
+
+                TokenInst *tokenInst = (TokenInst *)inst;
+                uint32 token = tokenInst->getToken();
+                cgInst = instructionCallback.ldRef(inst->getDst()->getType(),
+                    tokenInst->getEnclosingMethod(),
+                    token, acmod==AutoCompress_Yes);
+                isConstant = true;
+            }
+            break;
+        case Op_LdVar:
+            {
+                VarAccessInst * varInst = (VarAccessInst *)inst;
+                cgInst = instructionCallback.ldVar(inst->getDst()->getType(),
+                    getVarHandle(varInst->getVar()));
+            }
+            break;
+        case Op_LdVarAddr:
+            {
+                if (!genConsts) break;
+                VarAccessInst * varInst = (VarAccessInst *)inst;
+                cgInst = instructionCallback.ldVarAddr(getVarHandle(varInst->getVar()));
+                isConstant = true;
+            }
+            break;
+        case Op_TauLdInd:
+            {
+                assert(inst->getNumSrcOperands() == 3);
+                AutoCompressModifier acmod = inst->getAutoCompressModifier();
+                SpeculativeModifier   smod = inst->getSpeculativeModifier();
+
+                instructionCallback.setCurrentPersistentId(inst->getPersistentInstructionId());
+                Opnd *ptr = inst->getSrc(0);
+                Opnd *tauNonNullBase = inst->getSrc(1);
+                Opnd *tauAddressInRange = inst->getSrc(2);
+
+                assert(tauNonNullBase->getType()->tag == Type::Tau);
+                assert(tauAddressInRange->getType()->tag == Type::Tau);
+
+                cgInst = instructionCallback.tau_ldInd(inst->getDst()->getType(),
+                    getCGInst(ptr),
+                    inst->getType(),
+                    acmod == AutoCompress_Yes,
+                    smod == Speculative_Yes,
+                    getCGInst(tauNonNullBase),
+                    getCGInst(tauAddressInRange));
+                instructionCallback.clearCurrentPersistentId();
+            }
+            break;
+        case Op_TauLdField:
+            {
+                assert(inst->getNumSrcOperands() == 3);
+                AutoCompressModifier acmod = inst->getAutoCompressModifier();
+
+                FieldAccessInst* fieldInst = (FieldAccessInst*)inst;
+                FieldDesc* fieldDesc = fieldInst->getFieldDesc();
+                Opnd *base = inst->getSrc(0);
+                Opnd *tauNonNullBase = inst->getSrc(1);
+                Opnd *tauObjectTypeChecked = inst->getSrc(2);
+
+                assert(tauNonNullBase->getType()->tag == Type::Tau);
+                assert(tauObjectTypeChecked->getType()->tag == Type::Tau);
+
+                cgInst = instructionCallback.tau_ldField(inst->getDst()->getType(),
+                    getCGInst(base),
+                    inst->getType(),
+                    fieldDesc,
+                    acmod == AutoCompress_Yes,
+                    getCGInst(tauNonNullBase),
+                    getCGInst(tauObjectTypeChecked));
+            }
+            break;
+        case Op_LdStatic:
+            {
+                AutoCompressModifier acmod = inst->getAutoCompressModifier();
+
+                FieldAccessInst* fieldInst = (FieldAccessInst *)inst;
+                FieldDesc* fieldDesc = fieldInst->getFieldDesc();
+                cgInst = instructionCallback.ldStatic(inst->getDst()->getType(),
+                    fieldDesc,
+                    inst->getType(),
+                    acmod == AutoCompress_Yes);
+            }
+            break;
+        case Op_TauLdElem:
+            {
+                assert(inst->getNumSrcOperands() == 4);
+                AutoCompressModifier acmod = inst->getAutoCompressModifier();
+
+                Opnd *array = inst->getSrc(0);
+                Opnd *index = inst->getSrc(1);
+                Opnd *tauNonNullBase = inst->getSrc(2);
+                Opnd *tauAddressInRange = inst->getSrc(3);
+
+                assert(tauNonNullBase->getType()->tag == Type::Tau);
+                assert(tauAddressInRange->getType()->tag == Type::Tau);
+
+                cgInst = instructionCallback.tau_ldElem(inst->getDst()->getType(),
+                    getCGInst(array),
+                    getCGInst(index),
+                    acmod == AutoCompress_Yes,
+                    getCGInst(tauNonNullBase),
+                    getCGInst(tauAddressInRange));
+            }
+            break;
+        case Op_LdFieldAddr:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                FieldAccessInst* fieldInst = (FieldAccessInst*)inst;
+                FieldDesc* fieldDesc = fieldInst->getFieldDesc();
+                cgInst = instructionCallback.ldFieldAddr(inst->getDst()->getType(),
+                    getCGInst(inst->getSrc(0)),
+                    fieldDesc);
+            }
+            break;
+        case Op_LdStaticAddr:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                FieldAccessInst* fieldInst = (FieldAccessInst *)inst;
+                FieldDesc* fieldDesc = fieldInst->getFieldDesc();
+                cgInst = instructionCallback.ldStaticAddr(inst->getDst()->getType(),
+                    fieldDesc);
+            }
+            break;
+        case Op_LdElemAddr:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.ldElemAddr(getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
+        case Op_LdFunAddr:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                MethodInst * methodInst = (MethodInst *)inst;
+                MethodDesc * methodDesc = methodInst->getMethodDesc();
+                cgInst = 
+                    instructionCallback.ldFunAddr(inst->getDst()->getType(),
+                    methodDesc);
+            }
+            break;
+        case Op_TauLdVirtFunAddr:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                MethodInst * methodInst = (MethodInst *)inst;
+                MethodDesc * methodDesc = methodInst->getMethodDesc();
+                Opnd *vtable = inst->getSrc(0);
+                Opnd *tauBaseHasMethod = inst->getSrc(1);
+
+                assert(tauBaseHasMethod->getType()->tag == Type::Tau);
+
+                cgInst = 
+                    instructionCallback.tau_ldVirtFunAddr(inst->getDst()->getType(),
+                    getCGInst(vtable),
+                    methodDesc,
+                    getCGInst(tauBaseHasMethod));
+            }
+            break;
+        case Op_LdFunAddrSlot:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                MethodInst * methodInst = (MethodInst *)inst;
+                MethodDesc * methodDesc = methodInst->getMethodDesc();
+                cgInst = 
+                    instructionCallback.ldFunAddr(inst->getDst()->getType(),
+                    methodDesc);
+            }
+            break;
+        case Op_TauLdVirtFunAddrSlot:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                MethodInst * methodInst = (MethodInst *)inst;
+                MethodDesc * methodDesc = methodInst->getMethodDesc();
+                Opnd *vtable = inst->getSrc(0);
+                Opnd *tauBaseHasMethod = inst->getSrc(1);
+
+                assert(tauBaseHasMethod->getType()->tag == Type::Tau);
+
+                cgInst = 
+                    instructionCallback.tau_ldVirtFunAddr(inst->getDst()->getType(),
+                    getCGInst(vtable),
+                    methodDesc,
+                    getCGInst(tauBaseHasMethod));
+            }
+            break;
+        case Op_TauLdVTableAddr:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                instructionCallback.setCurrentPersistentId(inst->getPersistentInstructionId());
+                Type * dstType = inst->getDst()->getType();
+                assert(dstType->isVTablePtr() || dstType->isVTablePtrObj());
+                Opnd *base = inst->getSrc(0);
+                Opnd *tauBaseNonNull = inst->getSrc(1);
+
+                assert(tauBaseNonNull->getType()->tag == Type::Tau);
+
+                cgInst = instructionCallback.tau_ldVTableAddr(dstType,
+                    getCGInst(base),
+                    getCGInst(tauBaseNonNull));
+                instructionCallback.clearCurrentPersistentId();
+            }
+            break;
+        case Op_GetVTableAddr:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                if (!genConsts) break;
+                Type *type = ((TypeInst*)inst)->getTypeInfo();
+                assert(type->isObject());
+                Type * dstType = inst->getDst()->getType();
+                assert(dstType->isVTablePtr());
+                cgInst = instructionCallback.getVTableAddr( dstType,(ObjectType*)type);
+                isConstant = true;
+            }
+            break;
+        case Op_TauLdIntfcVTableAddr:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                TypeInst *typeInst = (TypeInst*)inst;
+                Type * vtableType = typeInst->getTypeInfo();
+                assert(vtableType->isUserObject());
+                Opnd *base = inst->getSrc(0);
+                cgInst = instructionCallback.tau_ldIntfTableAddr(inst->getDst()->getType(),
+                    getCGInst(base),
+                    (NamedType*)vtableType);
+            }
+            break;
+        case Op_TauArrayLen:
+            {
+                assert(inst->getNumSrcOperands() == 3);
+                Opnd *array = inst->getSrc(0);
+                Opnd *tauNonNullArray = inst->getSrc(1);
+                Opnd *tauIsArray = inst->getSrc(2);
+
+                assert(tauNonNullArray->getType()->tag == Type::Tau);
+
+                Type* dstType = inst->getDst()->getType();
+                Type* arrayType = inst->getSrc(0)->getType();
+                assert(arrayType->isArrayType());
+                Type* arrayLenType = dstType;
+                instructionCallback.setCurrentPersistentId(inst->getPersistentInstructionId());
+                cgInst = instructionCallback.tau_arrayLen(dstType, 
+                    (ArrayType*)arrayType,  
+                    arrayLenType,
+                    getCGInst(array),
+                    getCGInst(tauNonNullArray),
+                    getCGInst(tauIsArray));
+                instructionCallback.clearCurrentPersistentId();
+            }
+            break;
+            // load the base (zero element) address of array
+        case Op_LdArrayBaseAddr:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                cgInst = instructionCallback.ldElemBaseAddr(getCGInst(inst->getSrc(0)));
+            }
+            break;
+            // Add a scaled index to an array element address
+        case Op_AddScaledIndex:    
+            {
+                PtrType* arrType = (PtrType*) inst->getSrc(0)->getType();
+                Type*    refType = arrType->getPointedToType();
+
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.addElemIndex(refType,
+                    getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
+            // subtract 2 reference to yield difference as # of elements
+        case Op_ScaledDiffRef:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.scaledDiffRef(getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)),
+                    (Type *)inst->getSrc(0)->getType(),
+                    (Type *)inst->getSrc(1)->getType());
+            }
+            break;
+        case Op_UncompressRef:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                cgInst = instructionCallback.uncompressRef(getCGInst(inst->getSrc(0)));
+            }
+            break;
+        case Op_CompressRef:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                cgInst = instructionCallback.compressRef(getCGInst(inst->getSrc(0)));
+            }
+            break;
+        case Op_LdFieldOffset:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                if (!genConsts) break;
+                FieldAccessInst* fieldInst = (FieldAccessInst*)inst;
+                FieldDesc* fieldDesc = fieldInst->getFieldDesc();
+                cgInst = instructionCallback.ldFieldOffset(fieldDesc);
+                isConstant = true;
+            }
+            break;
+        case Op_LdFieldOffsetPlusHeapbase:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                if (!genConsts) break;
+                FieldAccessInst* fieldInst = (FieldAccessInst*)inst;
+                FieldDesc* fieldDesc = fieldInst->getFieldDesc();
+                cgInst = instructionCallback.ldFieldOffsetPlusHeapbase(fieldDesc);
+                isConstant = true;
+            }
+            break;
+        case Op_LdArrayBaseOffset:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                if (!genConsts) break;
+                TypeInst *typeInst = (TypeInst*)inst;
+                Type *elemType = typeInst->getTypeInfo();
+                cgInst = instructionCallback.ldArrayBaseOffset(elemType);
+                isConstant = true;
+            }
+            break;
+        case Op_LdArrayBaseOffsetPlusHeapbase:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                if (!genConsts) break;
+                TypeInst *typeInst = (TypeInst*)inst;
+                Type *elemType = typeInst->getTypeInfo();
+                cgInst = instructionCallback.ldArrayBaseOffsetPlusHeapbase(elemType);
+                isConstant = true;
+            }
+            break;
+        case Op_LdArrayLenOffset:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                if (!genConsts) break;
+                TypeInst *typeInst = (TypeInst*)inst;
+                Type *elemType = typeInst->getTypeInfo();
+                cgInst = instructionCallback.ldArrayLenOffset(elemType);
+                isConstant = true;
+            }
+            break;
+        case Op_LdArrayLenOffsetPlusHeapbase:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                if (!genConsts) break;
+                TypeInst *typeInst = (TypeInst*)inst;
+                Type *elemType = typeInst->getTypeInfo();
+                cgInst = instructionCallback.ldArrayLenOffsetPlusHeapbase(elemType);
+                isConstant = true;
+            }
+            break;
+        case Op_AddOffset:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                Opnd *dstop = inst->getDst();
+                Opnd *ref = inst->getSrc(0);
+                Opnd *offset = inst->getSrc(1);
+                Type *dstType = dstop->getType();
+                cgInst = instructionCallback.addOffset(dstType, getCGInst(ref), getCGInst(offset));
+            }
+            break;
+        case Op_AddOffsetPlusHeapbase:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                Opnd *dstop = inst->getDst();
+                Opnd *ref = inst->getSrc(0);
+                Opnd *offset = inst->getSrc(1);
+                Type *dstType = dstop->getType();
+                cgInst = instructionCallback.addOffsetPlusHeapbase(dstType, 
+                    getCGInst(ref), 
+                    getCGInst(offset));
+            }
+            break;
+        case Op_StVar:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                VarAccessInst * varInst = (VarAccessInst *)inst;
+                instructionCallback.stVar(getCGInst(inst->getSrc(0)), 
+                    getVarHandle(varInst->getVar()));  
+
+            }
+            break;
+        case Op_TauStInd:
+            {
+                assert(inst->getNumSrcOperands() == 5);
+                Opnd *src = inst->getSrc(0);
+                Opnd *ptr = inst->getSrc(1);
+                Opnd *tauNonNullBase = inst->getSrc(2);
+                Opnd *tauAddressInRange = inst->getSrc(3);
+                Opnd *tauElemTypeChecked = inst->getSrc(4);
+
+                assert(tauNonNullBase->getType()->tag == Type::Tau);
+                assert(tauAddressInRange->getType()->tag == Type::Tau);
+                assert(tauElemTypeChecked->getType()->tag == Type::Tau);
+
+                AutoCompressModifier acmod = inst->getAutoCompressModifier();
+                bool autocompress = (acmod == AutoCompress_Yes);
+                Type::Tag type = inst->getType();
+                if (acmod == AutoCompress_Yes) {
+                    assert(Type::isReference(type));
+                    assert(!Type::isCompressedReference(type));
+                }
+                instructionCallback.tau_stInd(getCGInst(src),
+                    getCGInst(ptr),
+                    type,
+                    autocompress,
+                    getCGInst(tauNonNullBase),
+                    getCGInst(tauAddressInRange),
+                    getCGInst(tauElemTypeChecked));
+            }
+            break;
+        case Op_TauStField:
+            {
+                assert(inst->getNumSrcOperands() == 5);
+                Opnd *src = inst->getSrc(0);
+                Opnd *base = inst->getSrc(1);
+                Opnd *tauNonNullBase = inst->getSrc(2);
+                Opnd *tauTypeHasField = inst->getSrc(3);
+                Opnd *tauFieldTypeChecked = inst->getSrc(4);
+
+                assert(tauNonNullBase->getType()->tag == Type::Tau);
+                assert(tauTypeHasField->getType()->tag == Type::Tau);
+                assert(tauFieldTypeChecked->getType()->tag == Type::Tau);
+
+                AutoCompressModifier acmod = inst->getAutoCompressModifier();
+
+                FieldAccessInst* fieldInst = (FieldAccessInst*)inst;
+                FieldDesc* fieldDesc = fieldInst->getFieldDesc();
+
+                bool autocompress = (acmod == AutoCompress_Yes);
+                Type::Tag type = inst->getType();
+                if (acmod == AutoCompress_Yes) {
+                    assert(Type::isReference(type));
+                    assert(!Type::isCompressedReference(type));
+                }
+                instructionCallback.tau_stField(getCGInst(src),
+                    getCGInst(base),
+                    type,
+                    fieldDesc,
+                    autocompress,
+                    getCGInst(tauNonNullBase),
+                    getCGInst(tauTypeHasField),
+                    getCGInst(tauFieldTypeChecked));
+            }
+            break;
+
+        case Op_TauStStatic: 
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                Opnd *src = inst->getSrc(0);
+                Opnd *tauFieldTypeOk = inst->getSrc(1);
+
+                AutoCompressModifier acmod = inst->getAutoCompressModifier();
+                bool autocompress = (acmod == AutoCompress_Yes);
+                Type::Tag type = inst->getType();
+                if (acmod == AutoCompress_Yes) {
+                    assert(Type::isReference(type));
+                    assert(!Type::isCompressedReference(type));
+                }
+                FieldAccessInst* fieldInst = (FieldAccessInst *)inst;
+                FieldDesc* fieldDesc = fieldInst->getFieldDesc();
+                instructionCallback.tau_stStatic(getCGInst(src),
+                    fieldDesc,
+                    type,
+                    autocompress,
+                    getCGInst(tauFieldTypeOk));
+            }
+            break;
+        case Op_TauStElem:
+            {
+                assert(inst->getNumSrcOperands() == 6);
+                Opnd *src = inst->getSrc(0);
+                Opnd *array = inst->getSrc(1);
+                Opnd *index = inst->getSrc(2);
+                AutoCompressModifier acmod = inst->getAutoCompressModifier();
+                Opnd *tauNonNullBase = inst->getSrc(3);
+                Opnd *tauAddressInRange = inst->getSrc(4);
+                Opnd *tauElemTypeChecked = inst->getSrc(5);
+
+                assert(tauNonNullBase->getType()->tag == Type::Tau);
+                assert(tauAddressInRange->getType()->tag == Type::Tau);
+                assert(tauElemTypeChecked->getType()->tag == Type::Tau);
+
+
+                instructionCallback.tau_stElem(getCGInst(src),
+                    getCGInst(array),
+                    getCGInst(index),
+                    acmod == AutoCompress_Yes,
+                    getCGInst(tauNonNullBase),
+                    getCGInst(tauAddressInRange),
+                    getCGInst(tauElemTypeChecked));
+            }
+            break;
+        case Op_TauStRef:
+            {
+                assert(inst->getNumSrcOperands() == 6);
+
+                Opnd *src = inst->getSrc(0);
+                Opnd *ptr = inst->getSrc(1);
+                Opnd *base = inst->getSrc(2);
+
+                Opnd *tauNonNullBase = inst->getSrc(3);
+                Opnd *tauTypeHasField = inst->getSrc(4);
+                Opnd *tauFieldTypeChecked = inst->getSrc(5);
+
+                assert(tauNonNullBase->getType()->tag == Type::Tau);
+                assert(tauTypeHasField->getType()->tag == Type::Tau);
+                assert(tauFieldTypeChecked->getType()->tag == Type::Tau);
+
+                AutoCompressModifier acmod = inst->getAutoCompressModifier();
+                StoreModifier UNUSED stmod = inst->getStoreModifier();
+
+                bool autocompress = (acmod == AutoCompress_Yes);
+                Type::Tag type = inst->getType();
+                if (acmod == AutoCompress_Yes) {
+                    assert(Type::isReference(type));
+                    assert(!Type::isCompressedReference(type));
+                }
+                assert(stmod == Store_WriteBarrier);
+                instructionCallback.tau_stRef(getCGInst(src),
+                    getCGInst(ptr),
+                    getCGInst(base),
+                    type,
+                    autocompress,
+                    getCGInst(tauNonNullBase),
+                    getCGInst(tauTypeHasField),
+                    getCGInst(tauFieldTypeChecked));
+            }
+            break;
+        case Op_TauCheckBounds:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.tau_checkBounds(getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
+        case Op_TauCheckLowerBound:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst =
+                    instructionCallback.tau_checkLowerBound(getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
+        case Op_TauCheckUpperBound:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst =
+                    instructionCallback.tau_checkUpperBound(getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
+        case Op_TauCheckNull:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                if ( inst->getDefArgModifier() == NonNullThisArg ) {
+                    if(Log::isEnabled()) {
+                        Log::out() << " chknull_NonNullThisArg_check" << ::std::endl;
+                    }
+                    cgInst = instructionCallback.tau_checkNull(getCGInst(inst->getSrc(0)), true);
+                }else{
+                    cgInst = instructionCallback.tau_checkNull(getCGInst(inst->getSrc(0)), false);
+                    assert(inst->getDefArgModifier() == DefArgNoModifier);
+                }
+            }
+            break;
+        case Op_TauCheckZero:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                cgInst = instructionCallback.tau_checkZero(getCGInst(inst->getSrc(0)));
+            }
+            break;
+        case Op_TauCheckDivOpnds:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                cgInst = instructionCallback.tau_checkDivOpnds(getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
+        case Op_TauCheckElemType:
+            {
+                assert(inst->getNumSrcOperands() == 4);
+                Opnd *array = inst->getSrc(0);
+                Opnd *src = inst->getSrc(1);
+                Opnd *tauCheckedNull = inst->getSrc(2);
+                Opnd *tauIsArray = inst->getSrc(3);
+                assert(tauCheckedNull->getType()->tag == Type::Tau);
+                cgInst = instructionCallback.tau_checkElemType(getCGInst(array),
+                    getCGInst(src),
+                    getCGInst(tauCheckedNull),
+                    getCGInst(tauIsArray));
+            }
+            break;
+        case Op_NewObj:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                TypeInst *typeInst = (TypeInst*)inst;
+                Type * objType = typeInst->getTypeInfo();
+                assert(objType->isObject());
+                cgInst = instructionCallback.newObj((ObjectType*)objType);
+            }
+            break;
+        case Op_NewArray:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                Type * arrayType = inst->getDst()->getType();
+                assert(arrayType->isArrayType());
+                cgInst = instructionCallback.newArray((ArrayType *)arrayType,
+                    getCGInst(inst->getSrc(0)));
+            }
+            break;
+        case Op_NewMultiArray:
+            {
+                Type * arrayType = inst->getDst()->getType();
+                assert(arrayType->isArrayType());
+                uint32 numDims = inst->getNumSrcOperands();
+                CG_OpndHandle ** dims = new(memManager) CG_OpndHandle*[numDims];
+                for (uint32 i = 0; i < numDims; i++) 
+                    dims[i] = getCGInst(inst->getSrc(i));
+                cgInst = instructionCallback.newMultiArray((ArrayType*)arrayType,
+                    numDims,
+                    dims);
+            }
+            break;
+        case Op_TauMonitorEnter:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                Opnd *tauOpnd = inst->getSrc(1);
+                instructionCallback.tau_monitorEnter(getCGInst(inst->getSrc(0)),
+                    getCGInst(tauOpnd));
+            }
+            break;
+        case Op_TauMonitorExit:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                Opnd *tauOpnd = inst->getSrc(1);
+                instructionCallback.tau_monitorExit(getCGInst(inst->getSrc(0)),
+                    getCGInst(tauOpnd));
+            }
+            break;
+        case Op_LdLockAddr:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                cgInst = instructionCallback.ldLockAddr(getCGInst(inst->getSrc(0)));
+            }
+            break;
+        case Op_IncRecCount:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                instructionCallback.incRecursionCount(getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
+        case Op_TauBalancedMonitorEnter:
+            {
+                assert(inst->getNumSrcOperands() == 3);
+                Opnd *tauOpnd = inst->getSrc(2);
+                cgInst = instructionCallback.tau_balancedMonitorEnter(getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)),
+                    getCGInst(tauOpnd));
+            }
+            break;
+        case Op_BalancedMonitorExit:
+            {
+                assert(inst->getNumSrcOperands() == 3);
+                instructionCallback.balancedMonitorExit(getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)),
+                    getCGInst(inst->getSrc(2)));
+            }
+            break;
+        case Op_TauOptimisticBalancedMonitorEnter:
+            {
+                assert(inst->getNumSrcOperands() == 3);
+                Opnd *tauOpnd = inst->getSrc(2);
+                cgInst = instructionCallback.tau_optimisticBalancedMonitorEnter(getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)),
+                    getCGInst(tauOpnd));
+            }
+            break;
+        case Op_OptimisticBalancedMonitorExit:
+            {
+                assert(inst->getNumSrcOperands() == 3);
+                instructionCallback.optimisticBalancedMonitorExit(getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)),
+                    getCGInst(inst->getSrc(2)));
+            }
+            break;
+        case Op_MonitorEnterFence:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                instructionCallback.monitorEnterFence(getCGInst(inst->getSrc(0)));
+            }
+            break;
+        case Op_MonitorExitFence:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                instructionCallback.monitorExitFence(getCGInst(inst->getSrc(0)));
+            }
+            break;
+        case Op_TypeMonitorEnter:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                Type * type = ((TypeInst*)inst)->getTypeInfo();
+                assert(type->isObject() || type->isUserValue());
+                instructionCallback.typeMonitorEnter((NamedType *)type);
+            }
+            break;
+        case Op_TypeMonitorExit:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                Type * type = ((TypeInst*)inst)->getTypeInfo();
+                assert(type->isObject() || type->isUserValue());
+                instructionCallback.typeMonitorExit((NamedType *)type);
+            }
+            break;
+        case Op_TauStaticCast:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                Opnd *src = inst->getSrc(0);
+                Opnd *tauCastChecked = inst->getSrc(1);
+                assert(tauCastChecked->getType()->tag == Type::Tau);
+                Type * toType = ((TypeInst*)inst)->getTypeInfo();
+                assert(toType->isObject());
+                cgInst = instructionCallback.tau_staticCast((ObjectType *)toType,
+                    getCGInst(src),
+                    getCGInst(tauCastChecked));
+            }
+            break;
+        case Op_TauCast:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                Type * toType = ((TypeInst*)inst)->getTypeInfo();
+                assert(toType->isObject());
+                Opnd *src = inst->getSrc(0);
+                Opnd *tauCheckedNull = inst->getSrc(1);
+                assert(tauCheckedNull->getType()->tag == Type::Tau);
+                cgInst = instructionCallback.tau_cast((ObjectType *)toType,
+                    getCGInst(src),
+                    getCGInst(tauCheckedNull));
+            }
+            break;
+        case Op_TauAsType:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                Type * toType = ((TypeInst*)inst)->getTypeInfo();
+                assert(toType->isObject());
+                Opnd *src = inst->getSrc(0);
+                Opnd *tauCheckedNull = inst->getSrc(1);
+                assert(tauCheckedNull->getType()->tag == Type::Tau);
+                cgInst = instructionCallback.tau_asType((ObjectType *)toType,
+                    getCGInst(src),
+                    getCGInst(tauCheckedNull));
+            }
+            break;
+        case Op_TauInstanceOf:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                Type * toType = ((TypeInst*)inst)->getTypeInfo();
+                assert(toType->isObject());
+                Opnd *src = inst->getSrc(0);
+                Opnd *tauCheckedNull = inst->getSrc(1);
+                assert(tauCheckedNull->getType()->tag == Type::Tau);
+                cgInst = instructionCallback.tau_instanceOf((ObjectType *)toType,
+                    getCGInst(src),
+                    getCGInst(tauCheckedNull));
+            }
+            break;
+        case Op_InitType:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                TypeInst *typeInst = (TypeInst*)inst;
+                instructionCallback.initType(typeInst->getTypeInfo());
+            }
+            break;
+        case Op_Label:
+            break;      // nothing to do
+        case Op_MethodEntry:
+            {  
+                assert(inst->isMethodMarker());
+                MethodMarkerInst* methEntryInst = inst->asMethodMarkerInst();
+                instructionCallback.methodEntry(methEntryInst->getMethodDesc());
+            }
+            break;      // nothing to do
+        case Op_MethodEnd:
+            {  
+                assert(inst->isMethodMarker());
+                MethodMarkerInst* methEntryInst = inst->asMethodMarkerInst();
+                // check that inst->getSrc(0) is really retOpnd and not thisOpnd
+                CG_OpndHandle* ret_val = inst->getNumSrcOperands()==0 ? NULL : 
+                getCGInst(inst->getSrc(0));
+                instructionCallback.methodEnd(methEntryInst->getMethodDesc(), 
+                    ret_val);
+            }
+            break;      // nothing to do
+        case Op_SourceLineNumber: 
+            {
+                break;      // nothing to do
+            }
+        case Op_LdObj:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                cgInst = instructionCallback.ldValueObj(inst->getDst()->getType(),
+                    getCGInst(inst->getSrc(0)));
+            }
+            break;
+        case Op_StObj:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                instructionCallback.stValueObj(getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
+        case Op_CopyObj:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                TypeInst *typeInst = (TypeInst *)inst;
+                instructionCallback.copyValueObj(typeInst->getTypeInfo(),
+                    getCGInst(inst->getSrc(0)),
+                    getCGInst(inst->getSrc(1)));
+            }
+            break;
+        case Op_InitObj:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                TypeInst * typeInst = (TypeInst *)inst;
+                instructionCallback.initValueObj(typeInst->getTypeInfo(),
+                    getCGInst(inst->getSrc(0)));
+            }
+            break;
+        case Op_Sizeof:
+            {
+                Type* type = inst->asTypeInst()->getTypeInfo();
+                assert(type->isValueType());
+                uint32 size = ((UserValueType*) type)->getUnboxedSize();
+                instructionCallback.ldc_i4(size);
+            }
+            break;
+        case Op_Box:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                Type * boxedType = inst->getDst()->getType();
+                assert(boxedType->isObject());
+                cgInst = instructionCallback.box((ObjectType *)boxedType,
+                    getCGInst(inst->getSrc(0))); 
+            }
+            break;
+        case Op_Unbox:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                cgInst = instructionCallback.unbox(inst->getDst()->getType(),
+                    getCGInst(inst->getSrc(0))); 
+            }
+            break;
+        case Op_LdToken:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                if (!genConsts) break;
+                TokenInst *tokenInst = (TokenInst *)inst;
+                uint32 token = tokenInst->getToken();
+                cgInst = instructionCallback.ldToken(inst->getDst()->getType(),
+                    tokenInst->getEnclosingMethod(), token);
+                isConstant = true;
+            }
+            break;
+        case Op_MkRefAny:
+            assert(0);
+            break;
+        case Op_RefAnyVal:
+            assert(0);
+            break;
+        case Op_RefAnyType:
+            assert(0);
+            break;
+        case Op_InitBlock:
+            assert(0);
+            break;
+        case Op_CopyBlock:
+            assert(0);
+            break;
+        case Op_Alloca:
+            assert(0);
+            break;
+        case Op_ArgList:
+            assert(0);
+            break;
+        case Op_Phi:
+            {
+                assert(0); // Phi nodes should be eliminated by deSSAing
+            }
+            break;
+        case Op_TauPi:
+            {
+                assert(0);
+            }
+            break;
+        case Op_IncCounter:
+            {
+                TokenInst *counterInst = (TokenInst *)inst;
+                uint32 counter = counterInst->getToken();
+                instructionCallback.incCounter(irmanager.getTypeManager().getUInt32Type(), counter);
+            }
+            break;
+        case Op_Prefetch:
+            {
+                assert(inst->getNumSrcOperands() == 3);
+                Opnd* src1 = inst->getSrc(0);
+                Opnd* src2 = inst->getSrc(1);
+                Opnd* src3 = inst->getSrc(2);
+                assert(src3->getInst()->isConst());
+                uint32 hints = src3->getInst()->asConstInst()->getValue().i4;
+                CG_OpndHandle * src1Handle = getCGInst(src1);
+                uint32 offset = 0;
+                if (src2->getInst()->isConst()) {
+                    offset = src2->getInst()->asConstInst()->getValue().i4;
+                } else {
+                    // Generate an add instruction to add offset to src1
+                    assert(src2->getType()->isInt4());
+                    src1Handle = instructionCallback.addRef(RefArithmeticOp::I4,
+                        src1Handle,getCGInst(src2));
+                }
+                instructionCallback.prefetch(src1Handle, offset, hints);
+            }
+            break;
+        case Op_TauPoint:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                cgInst = instructionCallback.tauPoint();
+            }
+            break;
+        case Op_TauEdge:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                cgInst = instructionCallback.tauEdge();
+            }
+            break;
+        case Op_TauAnd:
+            {
+                uint32 numSrcs = inst->getNumSrcOperands();
+                CG_OpndHandle **args = genCallArgs(inst, 0);
+                cgInst = instructionCallback.tauAnd(numSrcs, args);
+            }
+            break;
+        case Op_TauUnsafe:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                cgInst = instructionCallback.tauUnsafe();
+            }
+            break;
+        case Op_TauSafe:
+            {
+                assert(inst->getNumSrcOperands() == 0);
+                cgInst = instructionCallback.tauSafe();
+            }
+            break;
+        case Op_TauCheckCast:
+            {
+                assert(inst->getNumSrcOperands() == 2);
+                Opnd *src = inst->getSrc(0);
+                Opnd *tauCheckedNull = inst->getSrc(1);
+                assert(tauCheckedNull->getType()->tag == Type::Tau);
+                Type * toType = ((TypeInst*)inst)->getTypeInfo();
+                assert(toType->isObject());
+                cgInst = instructionCallback.tau_checkCast((ObjectType *)toType,
+                    getCGInst(src),
+                    getCGInst(tauCheckedNull));
+            }
+            break;
+        case Op_TauHasType:
+            {
+                cgInst = instructionCallback.tauPoint();
+            }
+            break;
+        case Op_TauHasExactType:
+            {
+                cgInst = instructionCallback.tauPoint();
+            }
+            break;
+        case Op_TauIsNonNull:
+            {
+                cgInst = instructionCallback.tauPoint();
+            }
+            break;
+        case Op_PredCmp:
+            {
+                if (inst->getNumSrcOperands() == 2) {
+                    // binary comparison
+                    CompareOp::Operators cmpOp = mapToComparisonOp(inst);
+                    CompareOp::Types opType = mapToCompareOpType(inst);
+                    cgInst = instructionCallback.pred_cmp(cmpOp, opType,
+                        getCGInst(inst->getSrc(0)),
+                        getCGInst(inst->getSrc(1)));
+                } else {
+                    assert(inst->getNumSrcOperands() == 1);
+                    // unary comparison against zero
+                    if (inst->getComparisonModifier() == Cmp_Zero) {
+                        cgInst = instructionCallback.pred_czero(mapToCompareZeroOpType(inst),
+                            getCGInst(inst->getSrc(0)));
+                    } else {
+                        // Nonzero
+                        cgInst = instructionCallback.pred_cnzero(mapToCompareZeroOpType(inst),
+                            getCGInst(inst->getSrc(0)));
+                    }
+                }
+            }
+            break;
+        case Op_PredBranch:
+            {
+                assert(inst->getNumSrcOperands() == 1);
+                instructionCallback.pred_btrue(getCGInst(inst->getSrc(0)));
+            }
+            break;
+        default:
+            assert(0);
+    } // end switch
+
+    if (cgInst) { // record mapping from dst
+        if(Log::isEnabled()) {
+            Log::out() << "genInstCode ";
+            inst->print(Log::out());
+            if (genConsts) {
+                Log::out() << "; genConsts=true";
+            } else {
+                Log::out() << "; genConsts=false";
+            }
+            Log::out() << " has cgInst"  << ::std::endl;
+        }
+
+        assert(dst);
+        if (isConstant) {
+            if(Log::isEnabled()) {
+                Log::out() << " isConstant" << ::std::endl;
+            }
+            assert(genConsts);
+            if (sinkConstants) {
+                if(Log::isEnabled()) {
+                    Log::out() << " sinkConstants=true" << ::std::endl;
+                }
+                setLocalCGInst(cgInst, dst);
+            } else {
+                if(Log::isEnabled()) {
+                    Log::out() << " sinkConstants=false" << ::std::endl;
+                }
+                setCGInst(cgInst, dst);
+            }
+        } else {
+            if(Log::isEnabled()) {
+                Log::out() << " isConstant=false" << ::std::endl;
+            }
+            setCGInst(cgInst, dst);
+            if (sinkConstants && sinkConstantsOne) {
+                // we just finished a non-constant inst, clear the constant inst map
+                clearLocalCGInsts();
+            }
+        }            
+    } else {
+        if(Log::isEnabled()) {
+            Log::out() << "genInstCode ";
+            inst->print(Log::out());
+            if (genConsts) {
+                Log::out() << "; genConsts=true";
+            } else {
+                Log::out() << "; genConsts=false";
+            }
+            Log::out() << " has NO cgInst"  << ::std::endl;
+        }
+    }
+}
+
+void _BlockCodeSelector::genCode(InstructionCallback& instructionCallback) {
+    callback = &instructionCallback;
+    //
+    // go through instructions
+    //
+    Inst*    labelInst = (Inst*)block->getFirstInst();
+    Inst*    inst = labelInst->getNextInst();
+    while (inst != NULL) {
+        if(Log::isEnabled()) {
+            Log::out() << "Code select ";
+            inst->print(Log::out());
+            Log::out() << ::std::endl;
+        }
+        if (irmanager.getCompilationInterface().isBCMapInfoRequired()) {
+            //POINTER_SIZE_INT instAddr = (POINTER_SIZE_INT) inst;
+            uint64 instID = inst->getId();
+            instructionCallback.setCurrentHIRInstrID(instID);
+        }
+        genInstCode(instructionCallback, inst, !sinkConstants);
+        inst = inst->getNextInst();
+    }
+}
+
+CG_OpndHandle* _BlockCodeSelector::getCGInst(Opnd* opnd) {
+    CG_OpndHandle *res = opndToCGInstMap[opnd->getId()];
+    if (!res) {
+        assert(sinkConstants);
+        res = localOpndToCGInstMap[opnd->getId()];
+        if (!res) {
+            genInstCode(*callback, opnd->getInst(), true); // generate code for the constant
+            res = localOpndToCGInstMap[opnd->getId()];
+            assert(res);
+        }
+    }
+    return res;
+}
+    
+void _BlockCodeSelector::setLocalCGInst(CG_OpndHandle* inst, Opnd* opnd) {
+    assert(sinkConstants);
+    localOpndToCGInstMap[opnd->getId()] = inst;
+}
+    
+void _BlockCodeSelector::clearLocalCGInsts() {
+    assert(sinkConstants && sinkConstantsOne);
+    localOpndToCGInstMap.clear();
+}
+
+void _BlockCodeSelector::setCGInst(CG_OpndHandle* inst,Opnd* opnd) {
+    opndToCGInstMap[opnd->getId()] = inst;
+    if (opnd->isGlobal()) 
+        callback->opndMaybeGlobal(inst);
+}
+
+uint32 _BlockCodeSelector::getVarHandle(VarOpnd *var) {
+    return varIdMap[var->getId()];
+}
+
+
+void _CFGCodeSelector::genCode(Callback& callback) {
+    bool    hasEdgeProfile = flowGraph->hasEdgeProfile();
+    //
+    // go through nodes in flow graph and call genDispatchNode for nodes
+    // that are handlers (dispatchers) and genBlock for nodes that are blocks.
+    // record the integer id that is returned and map it to the node.
+    //
+
+    //
+    // this table maps from a node's depth-first number to the 
+    // node id returned by the code selector
+    //
+    uint32*    nodeMapTable = new (memManager) uint32[numNodes];
+    ::std::vector<Node*> nodes;
+    nodes.reserve(numNodes);
+
+    // Compute postorder list to get only reachable nodes.
+    flowGraph->getNodesPostOrder(nodes);
+
+    assert(flowGraph->getExitNode()->getTraversalNum() == flowGraph->getTraversalNum());
+    Node* unwind = flowGraph->getUnwindNode();
+    Node* exit = flowGraph->getExitNode();
+    // Use reverse iterator to generate nodes in reverse postorder.
+    ::std::vector<Node*>::reverse_iterator niter;
+    for(niter = nodes.rbegin(); niter != nodes.rend(); ++niter) {
+        Node* node = *niter;
+        //
+        // Count in and out edges
+        //
+        uint32 numOutEdges = node->getOutDegree();
+        uint32 numInEdges = node->getInDegree();
+        uint32 nodeId = MAX_UINT32;
+        double cnt = (hasEdgeProfile? node->getExecCount() : -1.0);
+
+        if (node == exit) {
+            nodeId = callback.genExitNode(numInEdges,cnt);
+        }
+        else if (node == unwind) {
+            nodeId = callback.genUnwindNode(numInEdges,numOutEdges,cnt);
+        }
+        else if (node->isBlockNode()) {
+            _BlockCodeSelector    blockCodeSelector(memManager,
+                irmanager,
+                node,
+                opndToCGInstMap,
+                varIdMap,
+                sinkConstants,
+                sinkConstantsOne);
+
+
+            //
+            //  Derive the block kind (prolog, epilog, inner block)
+            //
+            CFGCodeSelector::Callback::BlockKind blockKind;
+            if (node == flowGraph->getEntryNode())
+                blockKind = CFGCodeSelector::Callback::Prolog;
+            else if (node == flowGraph->getReturnNode())
+                blockKind = CFGCodeSelector::Callback::Epilog;
+            else
+                blockKind = CFGCodeSelector::Callback::InnerBlock;
+            nodeId = callback.genBlock(numInEdges,
+                numOutEdges,
+                blockKind,
+                blockCodeSelector,
+                cnt);
+
+        } else if (node->isDispatchNode()) {
+            nodeId = callback.genDispatchNode(numInEdges,numOutEdges,cnt);
+        }
+        assert(nodeId < numNodes);
+        callback.setPersistentId(nodeId, node->getId());
+        nodeMapTable[node->getDfNum()] = nodeId;
+    }
+    //
+    // go through edges in flow graph 
+    //
+    for(niter = nodes.rbegin(); niter != nodes.rend(); ++niter) {
+        double    prob;
+        Node* tailNode = *niter;
+        uint32 tailNodeId = nodeMapTable[tailNode->getDfNum()];
+        if (((Inst*)tailNode->getLastInst())->isSwitch()) { 
+            //
+            //  Generate switch edges
+            //
+            SwitchInst* sw = (SwitchInst *)tailNode->getLastInst();
+            Node *defaultNode = sw->getDefaultTarget()->getNode();
+            uint32 defaultNodeId = nodeMapTable[defaultNode->getDfNum()];
+            uint32 numTargets = sw->getNumTargets();
+            uint32 * targetNodeIds = new (memManager) uint32[numTargets];
+            double * targetProbs = new (memManager) double[numTargets];
+            uint32 i;
+            for (i = 0; i < numTargets; i++) {
+                Node *headNode = sw->getTarget(i)->getNode();
+                Edge *edge = (Edge *) tailNode->findTargetEdge(headNode);
+                targetNodeIds[i] = nodeMapTable[headNode->getDfNum()];
+                targetProbs[i] = (hasEdgeProfile? edge->getEdgeProb() : -1.0);
+            }
+            callback.genSwitchEdges(tailNodeId,numTargets,targetNodeIds, 
+                targetProbs, defaultNodeId);
+            //
+            //  Generate an exception edge if it exists
+            //
+            Edge* throwEdge = (Edge*) tailNode->getExceptionEdge();
+            if(throwEdge != NULL) {
+                assert(0);
+                Node *succNode = throwEdge->getTargetNode();
+                assert(succNode->isDispatchNode());
+                uint32 headNodeId = nodeMapTable[succNode->getDfNum()];
+                prob = (hasEdgeProfile? throwEdge->getEdgeProb() : -1.0);
+                callback.genExceptionEdge(tailNodeId,headNodeId,prob);
+            }
+        }

[... 73 lines stripped ...]