case SEL_OP_AND: p->AND(dst, src0, src1); break;
case SEL_OP_OR: p->OR (dst, src0, src1); break;
case SEL_OP_XOR: p->XOR(dst, src0, src1); break;
+ case SEL_OP_I64AND:
+ {
+ GenRegister xdst = GenRegister::retype(dst, GEN_TYPE_UL),
+ xsrc0 = GenRegister::retype(src0, GEN_TYPE_UL),
+ xsrc1 = GenRegister::retype(src1, GEN_TYPE_UL);
+ int execWidth = p->curr.execWidth;
+ p->push();
+ p->curr.execWidth = 8;
+ for (int nib = 0; nib < execWidth / 4; nib ++) {
+ p->curr.chooseNib(nib);
+ p->AND(xdst.bottom_half(), xsrc0.bottom_half(), xsrc1.bottom_half());
+ p->AND(xdst.top_half(), xsrc0.top_half(), xsrc1.top_half());
+ xdst = GenRegister::suboffset(xdst, 4),
+ xsrc0 = GenRegister::suboffset(xsrc0, 4),
+ xsrc1 = GenRegister::suboffset(xsrc1, 4);
+ }
+ p->pop();
+ }
+ break;
+ case SEL_OP_I64OR:
+ {
+ GenRegister xdst = GenRegister::retype(dst, GEN_TYPE_UL),
+ xsrc0 = GenRegister::retype(src0, GEN_TYPE_UL),
+ xsrc1 = GenRegister::retype(src1, GEN_TYPE_UL);
+ int execWidth = p->curr.execWidth;
+ p->push();
+ p->curr.execWidth = 8;
+ for (int nib = 0; nib < execWidth / 4; nib ++) {
+ p->curr.chooseNib(nib);
+ p->OR(xdst.bottom_half(), xsrc0.bottom_half(), xsrc1.bottom_half());
+ p->OR(xdst.top_half(), xsrc0.top_half(), xsrc1.top_half());
+ xdst = GenRegister::suboffset(xdst, 4),
+ xsrc0 = GenRegister::suboffset(xsrc0, 4),
+ xsrc1 = GenRegister::suboffset(xsrc1, 4);
+ }
+ p->pop();
+ }
+ break;
+ case SEL_OP_I64XOR:
+ {
+ GenRegister xdst = GenRegister::retype(dst, GEN_TYPE_UL),
+ xsrc0 = GenRegister::retype(src0, GEN_TYPE_UL),
+ xsrc1 = GenRegister::retype(src1, GEN_TYPE_UL);
+ int execWidth = p->curr.execWidth;
+ p->push();
+ p->curr.execWidth = 8;
+ for (int nib = 0; nib < execWidth / 4; nib ++) {
+ p->curr.chooseNib(nib);
+ p->XOR(xdst.bottom_half(), xsrc0.bottom_half(), xsrc1.bottom_half());
+ p->XOR(xdst.top_half(), xsrc0.top_half(), xsrc1.top_half());
+ xdst = GenRegister::suboffset(xdst, 4),
+ xsrc0 = GenRegister::suboffset(xsrc0, 4),
+ xsrc1 = GenRegister::suboffset(xsrc1, 4);
+ }
+ p->pop();
+ }
+ break;
case SEL_OP_SHR: p->SHR(dst, src0, src1); break;
case SEL_OP_SHL: p->SHL(dst, src0, src1); break;
case SEL_OP_RSR: p->RSR(dst, src0, src1); break;
ALU2(AND)
ALU2(OR)
ALU2(XOR)
+ ALU2(I64AND)
+ ALU2(I64OR)
+ ALU2(I64XOR)
ALU2(SHR)
ALU2(SHL)
ALU2(RSR)
sel.ADD(dst, src0, src1);
sel.pop();
break;
- case OP_XOR: sel.XOR(dst, src0, src1); break;
- case OP_OR: sel.OR(dst, src0, src1); break;
- case OP_AND: sel.AND(dst, src0, src1); break;
+ case OP_XOR:
+ if (type == Type::TYPE_U64 || type == Type::TYPE_S64)
+ sel.I64XOR(dst, src0, src1);
+ else
+ sel.XOR(dst, src0, src1);
+ break;
+ case OP_OR:
+ if (type == Type::TYPE_U64 || type == Type::TYPE_S64)
+ sel.I64OR(dst, src0, src1);
+ else
+ sel.OR(dst, src0, src1);
+ break;
+ case OP_AND:
+ if (type == Type::TYPE_U64 || type == Type::TYPE_S64)
+ sel.I64AND(dst, src0, src1);
+ else
+ sel.AND(dst, src0, src1);
+ break;
case OP_SUB:
if (type == Type::TYPE_U64 || type == Type::TYPE_S64) {
GenRegister t = sel.selReg(sel.reg(RegisterFamily::FAMILY_QWORD), Type::TYPE_S64);