in vm/jitrino/src/codegenerator/ipf/IpfEncoder.cpp [1390:1542]
uint64 Encoder::cmp_cmp4(InstCode icode, Inst * inst, CompVector & cmpls, OpndVector & opnds, uint64 qp) {
assert(opnds.size()>=5);
int64 p1=opnds[1]->getValue(), p2=opnds[2]->getValue();
int64 r2=opnds[3]->getValue(), r3=opnds[4]->getValue();
OpndKind okind3=opnds[3]->getOpndKind();
Completer crel = cmpls[0];
Completer ctype = ( cmpls.size()>1 ? cmpls[1] : CMPLT_INVALID );
uint64 opcode=0, ta=0, c=0, x2;
int64 tmp, & imm8 = r2;
// parse pseudo-op
if ( cmpls.size() == 1 || ctype==CMPLT_CMP_CTYPE_UNC ) {
if (opnds[3]->isImm(8)) {
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:
IPF_ERR << __FILE__ << ": " << __LINE__ << ": BAD ctype/crel\n";
assert(0);
break;
}
}
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:
IPF_ERR << __FILE__ << ": " << __LINE__ << ": BAD ctype/crel\n";
assert(0);
break;
}
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 A6(opcode, x2, ta, c, p1, p2, r2, r3, qp);
} else if (opnds[3]->isImm(8)) {
x2 = icode==INST_CMP ? 2 : 3;
return A8(opcode, x2, ta, c, p1, p2, imm8, r3, qp);
} else {
assert(r2==0);
x2 = icode==INST_CMP ? 0 : 1;
return A7(opcode, x2, ta, c, p1, p2, r3, qp);
}
}