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;
}