bool IpfVerifier::br()

in vm/jitrino/src/codegenerator/ipf/IpfVerifier.cpp [543:656]


bool IpfVerifier::br(string * res, Inst * inst, InstCode icode, OpndVector & opnds, CompVector & cmpls) {
    unsigned int is13 = (icode==INST_BR13 || icode==INST_BRL13 ? 1 : 0);  // must be 1 or 0
    
    switch (icode) {
    case INST_BRL13:
    case INST_BRL:
        if (IS_C(0) && C(0)==CMPLT_BTYPE_CALL) {
            if (!IS_O(is13 + 2)) return false;
            if (!IS_IMM64(is13 + 2)) return false;
            if (!IS_BR(is13 + 1)) return false;
        } else {
            if (!IS_O(is13 + 1)) return false;
            if (!IS_IMM64(is13 + 1)) return false;
        }
        for (uint64 i=1 ; IS_C(i) ; i++ ) {
            switch (C(i)) {
            case CMPLT_DH_CLR:
            case CMPLT_WH_SPTK: 
            case CMPLT_WH_SPNT: 
            case CMPLT_WH_DPTK: 
            case CMPLT_WH_DPNT: 
            case CMPLT_PH_FEW:  
            case CMPLT_PH_MANY: 
                break;
            default: 
                return false;
            }
        }
        return true;
        
    case INST_BR:
    case INST_BR13:
        if (!IS_O(is13 + 1)) return false;
        {
            OpndKind okind1 = K(is13 + 1);
            uint64 cmplt_btype=CMPLT_BTYPE_COND, btype=0, ph=0, bwh=0, dh=0;
            
            for (uint64 i=0 ; IS_C(i) ; i++) {
                switch (C(i)) {
                case CMPLT_BTYPE_COND:  btype=0; cmplt_btype=C(i); break;
                case CMPLT_BTYPE_IA:    btype=1; cmplt_btype=C(i); break;
                case CMPLT_BTYPE_RET:   btype=4; cmplt_btype=C(i); break;
                case CMPLT_BTYPE_CLOOP: btype=5; cmplt_btype=C(i); break;
                case CMPLT_BTYPE_CEXIT: btype=6; cmplt_btype=C(i); break;
                case CMPLT_BTYPE_CTOP:  btype=7; cmplt_btype=C(i); break;
                case CMPLT_BTYPE_WEXIT: btype=2; cmplt_btype=C(i); break;
                case CMPLT_BTYPE_WTOP:  btype=3; cmplt_btype=C(i); break;
                case CMPLT_BTYPE_CALL:  btype=(uint64)-1; cmplt_btype=C(i); break;
                //----------------------------
                // Branch_Whether_Hint, NOT for all branch instructions!
                case CMPLT_WH_SPTK: bwh=0; break;
                case CMPLT_WH_SPNT: bwh=1; break;
                case CMPLT_WH_DPTK: bwh=2; break;
                case CMPLT_WH_DPNT: bwh=3; break;
                //----------------------------
                // Branch_Sequential_Prefetch_Hint (br, brl)
                case CMPLT_PH_FEW:  ph=0; break;
                case CMPLT_PH_MANY: ph=1; break;
                //----------------------------
                // Branch_Cache_Deallocation_Hint (br, brl)
                case CMPLT_DH_NOT_CLR: dh=0; break;
                case CMPLT_DH_CLR:     dh=1; break;
                default: 
                    return false;
                }
            }
            
            if (cmplt_btype==CMPLT_BTYPE_CALL) {
                if (!IS_O(is13 + 2)) return false;
                if (!IS_BR(is13 + 1)) return false;

                if (IS_BR(is13 + 2)) {
                    return true;
                } else {
                    if (!IS_IMM25(is13 + 2)) return false;
                    if ( IS_NODE_REF(is13 + 2) ) {
                        return true;
                    } else {
                        return true;
                    }
                }
            } else if (cmplt_btype==CMPLT_BTYPE_RET) {
                return true;
            } else if (cmplt_btype==CMPLT_BTYPE_CLOOP 
                    || cmplt_btype==CMPLT_BTYPE_CEXIT
                    || cmplt_btype==CMPLT_BTYPE_CTOP) {
                if ( IS_NODE_REF(is13 + 1) ) {
                    //assert(target != 0);
                    return true;
                } else {
                    return true;
                }
            } else if (okind1==OPND_B_REG) {
                return true;
            } else {
                if (!IS_IMM25(is13 + 1)) return false;
                if ( IS_NODE_REF(is13 + 1) ) {
                    //assert(target!=0);
                    return true;
                } else {
                    return true;
                }
            }
        }
        // fall to assert(0)        
    default:
        IPF_LOG << __FILE__ << ": " << __LINE__ 
                << ": NOT YET IMPLEMENTED VERIFIER FOR INSTRUCTION: " 
                << IrPrinter::toString(inst) << "\n";
        return false;
    }
    
    return false;
}