in vm/jitrino/src/codegenerator/ipf/IpfVerifier.cpp [715:876]
bool IpfVerifier::cmp_cmp4(string * res, Inst * inst, InstCode icode, OpndVector & opnds, CompVector & cmpls) {
if (!IS_O(4) || !IS_C(0)) return false;
if (!IS_PR(1) || !IS_PR(2) || !(IS_GR(3) || IS_IMM(3)) || !IS_GR(4)) return false;
if (IS_GR(3) && IS_GR(4)) {
// if (GR(3)->getDataKind() != GR(4)->getDataKind()) {
// res->append(IrPrinter::toString(O(3))
// + " and "
// + IrPrinter::toString(O(4))
// + " have different DataKind: "
// + getDataKindStr(GR(3)->getDataKind())
// + ", "
// + getDataKindStr(GR(4)->getDataKind()));
// return false;
// }
}
int64 p1=V(1), p2=V(2);
int64 r2=V(3), r3=V(4);
OpndKind okind3=K(3);
Completer crel = C(0);
Completer ctype = ( IS_C(1) ? C(1) : CMPLT_INVALID );
uint64 opcode=0, ta=0, c=0, x2;
int64 tmp;
// parse pseudo-op
if ( !IS_C(1) || ctype==CMPLT_CMP_CTYPE_UNC ) {
if ( IS_IMM8(3) ) {
switch (crel) {
case CMPLT_CMP_CREL_NE:
crel=CMPLT_CMP_CREL_EQ;
tmp = p1; p1 = p2; p2 = tmp;
break;
case CMPLT_CMP_CREL_LE:
crel=CMPLT_CMP_CREL_LT;
r2--;
break;
case CMPLT_CMP_CREL_GT:
crel=CMPLT_CMP_CREL_LT;
r2--;
tmp = p1; p1 = p2; p2 = tmp;
break;
case CMPLT_CMP_CREL_GE:
crel=CMPLT_CMP_CREL_LT;
tmp = p1; p1 = p2; p2 = tmp;
break;
case CMPLT_CMP_CREL_LEU:
crel=CMPLT_CMP_CREL_LTU;
r2--;
break;
case CMPLT_CMP_CREL_GTU:
crel=CMPLT_CMP_CREL_LTU;
r2--;
tmp = p1; p1 = p2; p2 = tmp;
break;
case CMPLT_CMP_CREL_GEU:
crel=CMPLT_CMP_CREL_LTU;
tmp = p1; p1 = p2; p2 = tmp;
break;
default:
break;
}
} else {
switch (crel) {
case CMPLT_CMP_CREL_NE:
crel=CMPLT_CMP_CREL_EQ;
tmp = p1; p1 = p2; p2 = tmp;
break;
case CMPLT_CMP_CREL_LE:
crel=CMPLT_CMP_CREL_LT;
tmp = r3; r3 = r2; r2 = tmp;
tmp = p1; p1 = p2; p2 = tmp;
break;
case CMPLT_CMP_CREL_GT:
crel=CMPLT_CMP_CREL_LT;
tmp = r3; r3 = r2; r2 = tmp;
break;
case CMPLT_CMP_CREL_GE:
crel=CMPLT_CMP_CREL_LT;
tmp = p1; p1 = p2; p2 = tmp;
break;
case CMPLT_CMP_CREL_LEU:
crel=CMPLT_CMP_CREL_LTU;
tmp = r3; r3 = r2; r2 = tmp;
tmp = p1; p1 = p2; p2 = tmp;
break;
case CMPLT_CMP_CREL_GTU:
crel=CMPLT_CMP_CREL_LTU;
tmp = r3; r3 = r2; r2 = tmp;
break;
case CMPLT_CMP_CREL_GEU:
crel=CMPLT_CMP_CREL_LTU;
tmp = p1; p1 = p2; p2 = tmp;
break;
default:
break;
}
}
} else if ( crel!=CMPLT_CMP_CREL_EQ && crel!=CMPLT_CMP_CREL_NE ) {
if ( crel==CMPLT_CMP_CREL_LT && r2>0 ) {
crel=CMPLT_CMP_CREL_GT;
tmp = r3; r3 = r2; r2 = tmp;
} else if ( crel==CMPLT_CMP_CREL_LE && r2>0 ) {
crel=CMPLT_CMP_CREL_GE;
tmp = r3; r3 = r2; r2 = tmp;
} else if ( crel==CMPLT_CMP_CREL_GT && r2>0 ) {
crel=CMPLT_CMP_CREL_LT;
tmp = r3; r3 = r2; r2 = tmp;
} else if ( crel==CMPLT_CMP_CREL_GE && r2>0 ) {
crel=CMPLT_CMP_CREL_LE;
tmp = r3; r3 = r2; r2 = tmp;
}
}
switch (ctype) {
case CMPLT_CMP_CTYPE_AND: opcode=0xC; break;
case CMPLT_CMP_CTYPE_OR: opcode=0xD; break;
case CMPLT_CMP_CTYPE_OR_ANDCM: opcode=0xE; break;
default:
switch (crel) {
case CMPLT_CMP_CREL_LT: opcode=0xC; break;
case CMPLT_CMP_CREL_LTU: opcode=0xD; break;
case CMPLT_CMP_CREL_EQ: opcode=0xE; break;
default:
return false;
}
}
switch (crel) {
case CMPLT_CMP_CREL_NE: ta=1; c=1; break;
case CMPLT_CMP_CREL_GE: ta=1; c=0; break;
case CMPLT_CMP_CREL_LE: ta=0; c=1; break;
case CMPLT_CMP_CREL_GT: ta=0; c=0; break;
case CMPLT_CMP_CREL_LTU: ta=0; c=(ctype==CMPLT_CMP_CTYPE_UNC ? 1 : 0); break;
case CMPLT_CMP_CREL_EQ:
if ( cmpls.size()==1 ) { ta=0; c=0; }
else if ( ctype==CMPLT_CMP_CTYPE_UNC ) { ta=0; c=1; }
else { ta=1; c=0; }
break;
case CMPLT_CMP_CREL_LT:
if ( cmpls.size()==1 ) { ta=0; c=0; }
else if ( ctype==CMPLT_CMP_CTYPE_UNC ) { ta=0; c=1; }
else { ta=1; c=1; }
break;
default:
return false;
}
if ( (ctype==CMPLT_CMP_CTYPE_NORMAL || ctype==CMPLT_CMP_CTYPE_UNC
|| crel==CMPLT_CMP_CREL_NE || crel==CMPLT_CMP_CREL_EQ || cmpls.size()==1)
&& okind3==OPND_G_REG ) {
x2 = icode==INST_CMP ? 0 : 1;
return true;
} else if ( IS_IMM8(3) ) {
x2 = icode==INST_CMP ? 2 : 3;
return true;
} else {
if (r2!=0) return false;
x2 = icode==INST_CMP ? 0 : 1;
return true;
}
return false;
}