msg_length,
response_length);
}
+
void Gen75Encoder::LOAD_DF_IMM(GenRegister dest, GenRegister tmp, double value) {
union { double d; unsigned u[2]; } u;
u.d = value;
}
void Gen75Encoder::MOV_DF(GenRegister dest, GenRegister src0, GenRegister r) {
+ GBE_ASSERT((src0.type == GEN_TYPE_F && dest.isdf()) || (src0.isdf() && dest.type == GEN_TYPE_F));
int w = curr.execWidth;
- if (src0.isdf()) {
- GBE_ASSERT(0); // MOV DF is called from convert instruction,
- // We should never convert a df to a df.
- } else {
- GenRegister r0 = GenRegister::h2(r);
+ GenRegister r0;
+ r0 = GenRegister::h2(r);
+ push();
+ curr.execWidth = 4;
+ curr.predicate = GEN_PREDICATE_NONE;
+ curr.noMask = 1;
+ MOV(r0, src0);
+ MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, 4));
+ curr.noMask = 0;
+ curr.quarterControl = 0;
+ curr.nibControl = 0;
+ MOV(dest, r0);
+ curr.nibControl = 1;
+ MOV(GenRegister::suboffset(dest, 4), GenRegister::suboffset(r0, 4));
+ pop();
+ if (w == 16) {
push();
curr.execWidth = 4;
curr.predicate = GEN_PREDICATE_NONE;
- MOV(r0, src0);
- MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, 4));
- curr.predicate = GEN_PREDICATE_NORMAL;
- curr.quarterControl = 0;
+ curr.noMask = 1;
+ MOV(r0, GenRegister::suboffset(src0, 8));
+ MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, 12));
+ curr.noMask = 0;
+ curr.quarterControl = 1;
curr.nibControl = 0;
- MOV(dest, r0);
+ MOV(GenRegister::suboffset(dest, 8), r0);
curr.nibControl = 1;
- MOV(GenRegister::suboffset(dest, 4), GenRegister::suboffset(r0, 4));
+ MOV(GenRegister::suboffset(dest, 12), GenRegister::suboffset(r0, 4));
pop();
- if (w == 16) {
- push();
- curr.execWidth = 4;
- curr.predicate = GEN_PREDICATE_NONE;
- MOV(r0, GenRegister::suboffset(src0, 8));
- MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, 12));
- curr.predicate = GEN_PREDICATE_NORMAL;
- curr.quarterControl = 1;
- curr.nibControl = 0;
- MOV(GenRegister::suboffset(dest, 8), r0);
- curr.nibControl = 1;
- MOV(GenRegister::suboffset(dest, 12), GenRegister::suboffset(r0, 4));
- pop();
- }
}
}
} /* End of the name space. */
}
void GenEncoder::MOV_DF(GenRegister dest, GenRegister src0, GenRegister r) {
+ GBE_ASSERT((src0.type == GEN_TYPE_F && dest.isdf()) || (src0.isdf() && dest.type == GEN_TYPE_F));
int w = curr.execWidth;
- if (src0.isdf()) {
- GBE_ASSERT(0); // MOV DF is called from convert instruction,
- // We should never convert a df to a df.
+ GenRegister r0;
+ int factor = 1;
+ if (dest.type == GEN_TYPE_F) {
+ r0 = r;
+ r = GenRegister::h2(r);
+ factor = 2;
} else {
- GenRegister r0 = GenRegister::h2(r);
+ r0 = GenRegister::h2(r);
+ }
+ push();
+ curr.execWidth = 8;
+ curr.predicate = GEN_PREDICATE_NONE;
+ curr.noMask = 1;
+ MOV(r0, src0);
+ MOV(GenRegister::suboffset(r0, 4 * factor), GenRegister::suboffset(src0, 4));
+ curr.noMask = 0;
+ curr.quarterControl = 0;
+ curr.nibControl = 0;
+ MOV(dest, r);
+ curr.nibControl = 1;
+ MOV(GenRegister::suboffset(dest, 4), GenRegister::suboffset(r, 8 / factor));
+ pop();
+ if (w == 16) {
push();
curr.execWidth = 8;
curr.predicate = GEN_PREDICATE_NONE;
curr.noMask = 1;
- MOV(r0, src0);
- MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, 4));
- curr.predicate = GEN_PREDICATE_NORMAL;
- curr.quarterControl = 0;
+ MOV(r0, GenRegister::suboffset(src0, 8));
+ MOV(GenRegister::suboffset(r0, 4 * factor), GenRegister::suboffset(src0, 12));
+ curr.noMask = 0;
+ curr.quarterControl = 1;
curr.nibControl = 0;
- MOV(dest, r);
+ MOV(GenRegister::suboffset(dest, 8), r);
curr.nibControl = 1;
- MOV(GenRegister::suboffset(dest, 4), GenRegister::suboffset(r, 8));
+ MOV(GenRegister::suboffset(dest, 12), GenRegister::suboffset(r, 8 / factor));
pop();
- if (w == 16) {
- push();
- curr.execWidth = 8;
- curr.predicate = GEN_PREDICATE_NONE;
- curr.noMask = 1;
- MOV(r0, GenRegister::suboffset(src0, 8));
- MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, 12));
- curr.predicate = GEN_PREDICATE_NORMAL;
- curr.quarterControl = 1;
- curr.nibControl = 0;
- MOV(GenRegister::suboffset(dest, 8), r);
- curr.nibControl = 1;
- MOV(GenRegister::suboffset(dest, 12), GenRegister::suboffset(r, 8));
- pop();
- }
}
}
}
if (unpacked.reg() != dst.reg())
sel.MOV(dst, unpacked);
- } else if ((dstType == ir::TYPE_S32 || dstType == ir::TYPE_U32) && srcFamily == FAMILY_QWORD) {
+ } else if ((dstType == ir::TYPE_S32 || dstType == ir::TYPE_U32) &&
+ (srcType == ir::TYPE_U64 || srcType == ir::TYPE_S64))
sel.CONVI64_TO_I(dst, src);
- } else if (dstType == ir::TYPE_FLOAT && srcFamily == FAMILY_QWORD) {
+ else if (dstType == ir::TYPE_FLOAT && (srcType == ir::TYPE_U64 || srcType == ir::TYPE_S64)) {
auto dag = sel.regDAG[src.reg()];
// FIXME, in the future, we need to do a common I64 lower to I32 analysis
// at llvm IR layer which could cover more cases then just this one.
sel.curr.subFlag = 1;
sel.CONVI64_TO_F(dst, src, tmp);
sel.pop();
- } else if (dst.isdf()) {
+ } else if ((dst.isdf() && srcType == ir::TYPE_FLOAT) ||
+ (src.isdf() && dstType == ir::TYPE_FLOAT)) {
ir::Register r = sel.reg(ir::RegisterFamily::FAMILY_QWORD);
sel.MOV_DF(dst, src, sel.selReg(r));
} else if (dst.isint64()) {