U0 ICAddEct(CIntermediateCode *tmpi, CICType t1, I64 r1, I64 d1, CICType t2, I64 r2, I64 d2, CICType t3, I64 r3, I64 d3, I64 op, I64 rip) { I64 i, tmp,res_reg = REG_RAX; Bool swap = FALSE; if (r3 != res_reg) { swap ^= TRUE; SwapI64(&t2, &t3); SwapI64(&r2, &r3); SwapI64(&d2, &d3); } if (t2.raw_type >= RT_I64 && r2 != res_reg && t2 & MDG_REG_DISP_SIB_RIP) { if (t1 & MDF_REG && !(r2 == r1 && t2 & MDG_REG_DISP_SIB)) res_reg = r1; ICMov(tmpi, MDF_REG + RT_I64, res_reg, 0, t3, r3, d3, rip); i=ICModr1(res_reg, t2, r2, d2); if (tmpi->ic_flags & ICF_LOCK) ICU8(tmpi, OC_LOCK_PREFIX); ICRex(tmpi, i.u8[1]); ICU16(tmpi, i.u8[2] << 8 + op); ICModr2(tmpi, i,, d2, rip); } else { if (t2 & MDF_REG) tmp = r2; else tmp = REG_RCX; if (t1 & MDF_REG) res_reg = r1; if (tmp == res_reg) res_reg = REG_RDX; if (swap) { if (r3 == tmp && t3 & MDG_REG_DISP_SIB) tmp = REG_RCX; ICMov(tmpi, MDF_REG + RT_I64, tmp, 0, t2, r2, d2, rip); ICMov(tmpi, MDF_REG + RT_I64, res_reg, 0, t3, r3, d3, rip); } else { if (r2 == res_reg && t2 & MDG_REG_DISP_SIB) res_reg = REG_RDX; ICMov(tmpi, MDF_REG + RT_I64, res_reg, 0, t3, r3, d3, rip); ICMov(tmpi, MDF_REG + RT_I64, tmp, 0, t2, r2, d2, rip); } i = 0x48; if (res_reg > 7) i += 4; if (tmp > 7) i++; if (tmpi->ic_flags & ICF_LOCK) ICU8(tmpi, OC_LOCK_PREFIX); ICU24(tmpi, 0xC00000 + i + (tmp & 7) << 16 + (res_reg & 7) << 19 + op << 8); } ICMov(tmpi, t1, r1, d1, MDF_REG + RT_I64, res_reg, 0, rip); } U0 ICAddSubEctImm(CIntermediateCode *tmpi, CICType t1, I64 r1, I64 d1, CICType t2, I64 r2, I64 d2, I64 d, I64 op, I64 rip) { I64 i; if (op.u8[0] == 0x2B) { op = 0x0003; d = -d; } if (t1 & MDF_REG) { if (!(t2 & MDF_REG)) { ICMov(tmpi, t1, r1, d1, t2, r2, d2, rip); t2 = t1; r2 = r1; d2 = d1; } if (r1 == r2) { if (r1 > 7) i = 0x49; else i = 0x48; if (!d && (op.u8[0] == 0x03 || op.u8[0] == 0x2B || op.u8[0] == 0x33 || op.u8[0] == 0x0B)) return; else if (d == 1 && op.u8[0] == 0x03) { ICU24(tmpi, 0xC0FF00 + op.u8[1] << 19 + i + (r1 & 7) << 16); return; } else if (d == -1 && op.u8[0] == 0x03) { ICU24(tmpi, 0xC8FF00 + i + (r1 & 7) << 16); return; } else if (I8_MIN <= d <= I8_MAX) { ICU24(tmpi, 0xC08300 + op.u8[1] << 19 + i + (r1 & 7) << 16); ICU8(tmpi, d); return; } else if (I32_MIN <= d <= I32_MAX) { ICU24(tmpi, 0xC08100 + op.u8[1] << 19 + i + (r1 & 7) << 16); ICU32(tmpi, d); return; } } if (op.u8[0] == 0x03 && I32_MIN <= d <= I32_MAX && !Bt(&cmp.non_ptr_vars_mask, r2)) { i = ICModr1(r1, MDF_DISP + RT_I64, r2, d); i.u8[1] |= 0x48; ICU24(tmpi, i.u8[2] << 16 + 0x8D00 + i.u8[1]); ICModr2(tmpi, i,, d, rip); return; } } switch (Bsr(t1)) { case MDf_REG: case MDf_DISP: case MDf_SIB: case MDf_RIP_DISP32: if (t1 != t2 || r1 != r2 || d1 != d2) { ICMov(tmpi, t1, r1, d1, t2, r2, d2, rip); t2 = t1; r2 = r1; d2 = d1; } if (!d &&(op.u8[0] == 0x03 || op.u8[0] == 0x2B || op.u8[0] == 0x33 || op.u8[0] == 0x0B)) return; if (op.u8[0] == 0x03 && d == -1) //add -1 op.u8[1] = 1; //Decrement slash val if (op.u8[0] == 0x03 && (d == 1 || d == -1)) { //Add i = ICModr1(op.u8[1], t1, r1, d1); if (!(t1 & MDF_REG) && tmpi->ic_flags & ICF_LOCK) ICU8(tmpi, OC_LOCK_PREFIX); switch (t1.raw_type) { case RT_I8: case RT_U8: ICRex(tmpi, i.u8[1]); ICU16(tmpi, i.u8[2] << 8 + 0xFE); break; case RT_I16: case RT_U16: ICOpSizeRex(tmpi, i.u8[1]); ICU16(tmpi, i.u8[2] << 8 + 0xFF); break; default: ICRex(tmpi, i.u8[1]); ICU16(tmpi, i.u8[2] << 8 + 0xFF); } ICModr2(tmpi, i,, d1, rip); return; } if (I8_MIN <= d <= I8_MAX || t1 & (RTG_MASK - RTF_UNSIGNED) == RT_I8) { ICSlashOp(tmpi, t1, r1, d1, SLASH_OP_IMM_U8 + op.u8[1], rip + 1); ICU8(tmpi, d); return; } if (I32_MIN <= d <= I32_MAX || t1.raw_type < RT_I64) { ICSlashOp(tmpi, t1, r1, d1, SLASH_OP_IMM_U32 + op.u8[1], rip); if (t1 & (RTG_MASK - RTF_UNSIGNED) == RT_I16) ICU16(tmpi, d); else ICU32(tmpi, d); return; } break; case MDf_STACK: ICAddSubEctImm(tmpi, MDF_REG + RT_I64, REG_RAX, 0, t2, r2, d2, d, op, rip); ICPushRegs(tmpi, 1 << REG_RAX); return; } ICAddEct(tmpi, t1, r1, d1, MDF_IMM + RT_I64, 0, d, t2, r2, d2, op.u8[0], rip); } U0 ICSub(CIntermediateCode *tmpi, CICType t1, I64 r1, I64 d1, CICType t2, I64 r2, I64 d2, CICType t3, I64 r3, I64 d3, I64 rip) { I64 i = 0x48, op = 0x2B; Bool swap = FALSE; if (r3 != REG_RAX) { swap = TRUE; SwapI64(&t2, &t3); SwapI64(&r2, &r3); SwapI64(&d2, &d3); } if (t2.raw_type >= RT_I64 && r2.u8[0] != REG_RAX && (!(t2 & MDF_SIB) || r2.u8[1] & 15 != REG_RAX) && t2 & MDG_REG_DISP_SIB_RIP) { ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, t3, r3, d3, rip); if (!swap) { op = 0x03; ICU24(tmpi, 0xD8F748); } i = ICModr1(REG_RAX, t2, r2, d2); if (tmpi->ic_flags & ICF_LOCK) ICU8(tmpi, OC_LOCK_PREFIX); ICRex(tmpi, i.u8[1]); ICU16(tmpi, i.u8[2] << 8 + op); ICModr2(tmpi, i,, d2, rip); ICMov(tmpi, t1, r1, d1, MDF_REG + RT_I64, REG_RAX, 0, rip); } else { if (!(t3 & MDF_REG) || t3.raw_type < RT_I64) { if (swap) { swap = FALSE; ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, t3, r3, d3, rip); ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, t2, r2, d2, rip); r2 = REG_RAX; r3 = REG_RCX; } else { ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, t3, r3, d3, rip); ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, t2, r2, d2, rip); r3 = REG_RAX; r2 = REG_RCX; } } else { ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, t2, r2, d2, rip); r2 = REG_RCX; } if (swap) { op = 0x03; ICU24(tmpi, 0xD9F748); } if (r3 > 7) i++; if (r2 > 7) i += 4; if (tmpi->ic_flags & ICF_LOCK) ICU8(tmpi, OC_LOCK_PREFIX); ICU24(tmpi, 0xC00000 + i + (r3 & 7) << 16 + (r2 & 7) << 19 + op << 8); ICMov(tmpi, t1, r1, d1, MDF_REG + RT_I64, r2, 0, rip); } } U0 ICMul(CIntermediateCode *tmpi, I64 rip) { I64 i, r2, r = REG_RAX, j; CICArg *arg1, *arg2; Bool alt; if (tmpi->arg1.type & MDF_IMM) { arg1 = &tmpi->arg2; arg2 = &tmpi->arg1; alt = TRUE; } else { arg1 = &tmpi->arg1; arg2 = &tmpi->arg2; alt = FALSE; } i = arg2->disp; if (!(tmpi->ic_class->raw_type & RTF_UNSIGNED) && arg2->type & MDF_IMM && I32_MIN <= i <= I32_MAX) { if (tmpi->res.type == MDF_REG + RT_I64) { ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp, arg1->type, arg1->reg, arg1->disp, rip); r = tmpi->res.reg; } else ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, arg1->type, arg1->reg, arg1->disp, rip); if (r > 7) j = 0xC0004D; else j = 0xC00048; if (I8_MIN <= i <= I8_MAX) ICU32(tmpi, i << 24 + 0x6B00 + j + (r & 7) << 16 + (r & 7) << 19); else { ICU24(tmpi, 0x6900 + j + (r & 7) << 16 + (r & 7) << 19); ICU32(tmpi, i); } } else { if (tmpi->ic_class->raw_type & RTF_UNSIGNED) i = 0xE0F748; else i = 0xE8F748; if (alt) { ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, arg1->type, arg1->reg, arg1->disp, rip); r2 = REG_RCX; ICMov(tmpi, MDF_REG + RT_I64,REG_RAX, 0, arg2->type, arg2->reg, arg2->disp, rip); } else { ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, arg2->type, arg2->reg, arg2->disp, rip); if (!(arg1->type & MDF_REG) || arg1->type.raw_type < RT_I64) { ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, arg1->type, arg1->reg, arg1->disp, rip); r2 = REG_RCX; } else r2 = arg1->reg; } if (r2 > 7) { i++; r2 &= 7; } ICU24(tmpi, i + r2 << 16); } ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp, MDF_REG + RT_I64, r, 0, rip); } U0 ICMulEqu(CIntermediateCode *tmpi, I64 rip) { I64 i = tmpi->arg2.disp, r = REG_RAX, j; if (!(tmpi->ic_class->raw_type & RTF_UNSIGNED) && tmpi->arg2.type & MDF_IMM && I32_MIN <= i <= I32_MAX) { if (tmpi->ic_flags & ICF_BY_VAL) { if (tmpi->arg1.type == MDF_REG + RT_I64) r = tmpi->arg1.reg; else ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, tmpi->arg1.type & MDG_MASK + tmpi->arg1_type_pointed_to, tmpi->arg1.reg, tmpi->arg1.disp, rip); if (r > 7) j = 0xC0004D; else j = 0xC00048; if (I8_MIN <= i <= I8_MAX) ICU32(tmpi, i << 24 + 0x6B00 + j + (r & 7) << 16 + (r & 7) << 19); else { ICU24(tmpi, 0x6900 + j + (r & 7) << 16 + (r & 7) << 19); ICU32(tmpi, i); } ICMov(tmpi, tmpi->arg1.type & MDG_MASK + tmpi->arg1_type_pointed_to, tmpi->arg1.reg, tmpi->arg1.disp, MDF_REG + RT_I64, r, 0, rip); } else { ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, tmpi->arg1.type, tmpi->arg1.reg, tmpi->arg1.disp, rip); ICMov(tmpi, MDF_REG + RT_I64, REG_RBX, 0, MDF_DISP + tmpi->arg1_type_pointed_to, REG_RCX, 0, rip); r = REG_RBX; if (I8_MIN <= i <= I8_MAX) ICU32(tmpi, i << 24 + 0xDB6B48); else { ICU24(tmpi, 0xDB6948); ICU32(tmpi, i); } ICMov(tmpi, MDF_DISP + tmpi->arg1_type_pointed_to, REG_RCX, 0, MDF_REG + RT_I64, REG_RBX, 0, rip); } } else { if (tmpi->ic_class->raw_type & RTF_UNSIGNED) i = 0xE3F748; else i = 0xEBF748; if (tmpi->ic_flags & ICF_BY_VAL) { ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, tmpi->arg2.type, tmpi->arg2.reg, tmpi->arg2.disp, rip); ICMov(tmpi, MDF_REG + RT_I64, REG_RBX, 0, tmpi->arg1.type & MDG_MASK + tmpi->arg1_type_pointed_to, tmpi->arg1.reg, tmpi->arg1.disp, rip); ICU24(tmpi, i); ICMov(tmpi, tmpi->arg1.type & MDG_MASK + tmpi->arg1_type_pointed_to, tmpi->arg1.reg, tmpi->arg1.disp, MDF_REG + RT_I64, REG_RAX, 0, rip); } else { ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, tmpi->arg2.type, tmpi->arg2.reg, tmpi->arg2.disp, rip); ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, tmpi->arg1.type, tmpi->arg1.reg, tmpi->arg1.disp, rip); ICMov(tmpi, MDF_REG + RT_I64, REG_RBX, 0, MDF_DISP + tmpi->arg1_type_pointed_to, REG_RCX, 0, rip); ICU24(tmpi, i); ICMov(tmpi, MDF_DISP + tmpi->arg1_type_pointed_to, REG_RCX, 0, MDF_REG + RT_I64, REG_RAX, 0, rip); } } if (tmpi->res.type.mode) ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp, MDF_REG + RT_I64, r, 0, rip); } U0 ICDiv(CIntermediateCode *tmpi, I64 rip) { ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, tmpi->arg2.type, tmpi->arg2.reg, tmpi->arg2.disp, rip); ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, tmpi->arg1.type, tmpi->arg1.reg, tmpi->arg1.disp, rip); if (tmpi->ic_class->raw_type & RTF_UNSIGNED) { ICZero(tmpi, REG_RDX); ICU24(tmpi, 0xF1F748); } else { ICU16(tmpi, 0x9948); ICU24(tmpi, 0xF9F748); } ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp, MDF_REG + RT_I64, REG_RAX, 0, rip); } U0 ICDivEqu(CIntermediateCode *tmpi, Bool is_mod, I64 rip) { if (tmpi->ic_flags & ICF_BY_VAL) { ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, tmpi->arg2.type, tmpi->arg2.reg, tmpi->arg2.disp, rip); ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, tmpi->arg1.type & MDG_MASK + tmpi->arg1_type_pointed_to, tmpi->arg1.reg, tmpi->arg1.disp, rip); if (tmpi->ic_class->raw_type & RTF_UNSIGNED) { ICZero(tmpi, REG_RDX); ICU24(tmpi, 0xF1F748); } else { ICU16(tmpi, 0x9948); ICU24(tmpi, 0xF9F748); } if (is_mod) ICMov(tmpi, tmpi->arg1.type & MDG_MASK + tmpi->arg1_type_pointed_to, tmpi->arg1.reg, tmpi->arg1.disp, MDF_REG + RT_I64, REG_RDX, 0, rip); else ICMov(tmpi, tmpi->arg1.type & MDG_MASK + tmpi->arg1_type_pointed_to, tmpi->arg1.reg, tmpi->arg1.disp, MDF_REG + RT_I64, REG_RAX, 0, rip); } else { ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, tmpi->arg2.type, tmpi->arg2.reg, tmpi->arg2.disp, rip); ICMov(tmpi, MDF_REG + RT_I64, REG_RBX, 0, tmpi->arg1.type, tmpi->arg1.reg, tmpi->arg1.disp, rip); //dangerous might clobber RBX in Mov, but it doesn't ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, MDF_DISP + tmpi->arg1_type_pointed_to, REG_RBX, 0, rip); if (tmpi->ic_class->raw_type & RTF_UNSIGNED) { ICZero(tmpi, REG_RDX); ICU24(tmpi, 0xF1F748); } else { ICU16(tmpi, 0x9948); ICU24(tmpi, 0xF9F748); } if (is_mod) ICMov(tmpi, MDF_DISP + tmpi->arg1_type_pointed_to, REG_RBX, 0, MDF_REG + RT_I64, REG_RDX, 0, rip); else ICMov(tmpi, MDF_DISP + tmpi->arg1_type_pointed_to, REG_RBX, 0, MDF_REG + RT_I64, REG_RAX, 0, rip); } if (tmpi->res.type.mode) { if (is_mod) ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp, MDF_REG + RT_I64, REG_RDX, 0, rip); else ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp, MDF_REG + RT_I64, REG_RAX, 0, rip); } } U0 ICMod(CIntermediateCode *tmpi, I64 rip) { ICMov(tmpi, MDF_REG +RT_I64, REG_RCX, 0, tmpi->arg2.type, tmpi->arg2.reg, tmpi->arg2.disp, rip); ICMov(tmpi, MDF_REG +RT_I64, REG_RAX, 0, tmpi->arg1.type, tmpi->arg1.reg, tmpi->arg1.disp, rip); if (tmpi->ic_class->raw_type & RTF_UNSIGNED) { ICZero(tmpi, REG_RDX); ICU24(tmpi, 0xF1F748); } else { ICU16(tmpi, 0x9948); ICU24(tmpi, 0xF9F748); } ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp, MDF_REG + RT_I64, REG_RDX, 0, rip); } U0 ICAddSubEctEqu(CIntermediateCode *tmpi, U8 type_pointed_to, CICType t1, I64 r1, I64 d1, CICType t2, I64 r2, I64 d2, CICType t3, I64 r3, I64 d3, I64 op, I64 rip) { Bool done; I64 res_reg, tmp, i; if (tmpi->ic_flags & ICF_BY_VAL) { if (t3 & MDF_IMM) { ICAddSubEctImm(tmpi, t2 & MDG_MASK + type_pointed_to, r2, d2, t2 & MDG_MASK + type_pointed_to, r2, d2, d3, op, rip); if (t1.mode) ICMov(tmpi, t1, r1, d1, t2 & MDG_MASK + type_pointed_to, r2, d2, rip); return; } else { done = FALSE; if (type_pointed_to >= RT_I64) { if (!t1.mode && t2 & MDG_REG_DISP_SIB_RIP) { if (t3 & MDF_REG) tmp = r3; else { tmp = REG_RCX; ICMov(tmpi, MDF_REG + RT_I64, tmp, 0, t3, r3, d3, rip); } i = ICModr1(tmp, t2 & MDG_MASK + type_pointed_to, r2, d2); if (tmpi->ic_flags & ICF_LOCK) ICU8(tmpi, OC_LOCK_PREFIX); ICRex(tmpi, i.u8[1]); ICU16(tmpi, i.u8[2] << 8 + op.u8[5]); ICModr2(tmpi, i,, d2, rip); return; } if (t3.raw_type >= RT_I64 && t3 & MDG_REG_DISP_SIB_RIP) { if (t2 & MDF_REG) res_reg = r2; else { res_reg = REG_RCX; ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, t2, r2, d2, rip); } i = ICModr1(res_reg, t3 & MDG_MASK + type_pointed_to, r3, d3); if (tmpi->ic_flags & ICF_LOCK) ICU8(tmpi, OC_LOCK_PREFIX); ICRex(tmpi, i.u8[1]); ICU16(tmpi, i.u8[2] << 8 + op.u8[0]); ICModr2(tmpi, i,, d3, rip); ICMov(tmpi, t2 & MDG_MASK + type_pointed_to, r2, d2, MDF_REG + RT_I64, res_reg, 0, rip); done = TRUE; } } if (!done) { ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, t3, r3, d3, rip); if (t2 & MDF_REG && r2 != REG_RAX) res_reg = r2; else { res_reg = REG_RCX; ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, t2 & MDG_MASK + type_pointed_to, r2, d2, rip); } if (tmpi->ic_flags & ICF_LOCK) ICU8(tmpi, OC_LOCK_PREFIX); if (res_reg > 7) ICU8(tmpi, 0x4C); else ICU8(tmpi, 0x48); ICU16(tmpi, 0xC000 + op.u8[0] + (res_reg & 7) << 11); ICMov(tmpi, t2 & MDG_MASK + type_pointed_to, r2, d2, MDF_REG + RT_I64, res_reg, 0, rip); } } } else { done = FALSE; if (t3 & MDF_IMM && op.u8[2]) { if (!d3.u32[1]) { if (tmpi->ic_flags & ICF_RES_NOT_USED && t2 & MDF_REG && d3(U64) <= I8_MAX) { ICSlashOp(tmpi, MDF_DISP + type_pointed_to, r2, 0, 0x838000 + op.u8[4], rip); ICU8(tmpi, d3); done = TRUE; } else if (op.u8[2] == 0x24) {//AND ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, t2, r2, d2, rip); ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, MDF_DISP + type_pointed_to, REG_RCX, 0, rip); res_reg = REG_RAX; if (tmpi->ic_flags & ICF_LOCK) ICU8(tmpi, OC_LOCK_PREFIX); ICU16(tmpi, op.u8[3] << 8 + 0x40); ICU32(tmpi, d3); ICMov(tmpi, MDF_DISP + type_pointed_to, REG_RCX, 0, MDF_REG + RT_I64, res_reg, 0, rip); done = TRUE; } else if (type_pointed_to < RT_I64) {//OR/XOR ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, t2, r2, d2, rip); ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, MDF_DISP + type_pointed_to, REG_RCX, 0, rip); res_reg = REG_RAX; if (tmpi->ic_flags & ICF_LOCK) ICU8(tmpi, OC_LOCK_PREFIX); if (d3.u16[1]) { ICU16(tmpi, op.u8[3] << 8 + 0x40); ICU32(tmpi, d3); } else if (d3.u8[1]) { ICU24(tmpi, op.u8[3] << 16 + 0x4000 + OC_OP_SIZE_PREFIX); ICU16(tmpi, d3); } else { ICU16(tmpi, op.u8[2] << 8 + 0x40); ICU8(tmpi, d3); } ICMov(tmpi, MDF_DISP + type_pointed_to, REG_RCX, 0, MDF_REG + RT_I64, res_reg, 0, rip); done = TRUE; } } } if (!done) { ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, t3, r3, d3, rip); ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, t2, r2, d2, rip); ICMov(tmpi, MDF_REG + RT_I64, REG_RBX, 0, MDF_DISP + type_pointed_to, REG_RCX, 0, rip); res_reg = REG_RBX; if (tmpi->ic_flags & ICF_LOCK) ICU8(tmpi, OC_LOCK_PREFIX); ICU8(tmpi, 0x48); ICU16(tmpi, 0xC000 + op.u8[0] + (res_reg & 7) << 11); ICMov(tmpi, MDF_DISP + type_pointed_to, REG_RCX, 0, MDF_REG + RT_I64, res_reg, 0, rip); } } if (t1.mode) ICMov(tmpi, t1, r1, d1, MDF_REG + RT_I64, res_reg, 0, rip); } U0 ICShift(CIntermediateCode *tmpi, CICType t1, I64 r1, I64 d1, CICType t2, I64 r2, I64 d2, CICType t3, I64 r3, I64 d3, I64 us, I64 is, I64 rip) { I64 i = 0x48, res_reg; if (tmpi->ic_class->raw_type & RTF_UNSIGNED || tmpi->ic_flags & ICF_USE_UNSIGNED) is = us; if (t1 & MDF_REG) { res_reg = r1; if (res_reg > 7) i++; } else res_reg = REG_RAX; if (t3 & MDF_IMM) { ICMov(tmpi, MDF_REG + RT_I64, res_reg, 0, t2, r2, d2, rip); if (d3 == 1) ICU24(tmpi, i + is.u16[2] << 8 + (res_reg & 7) << 16); else { ICU24(tmpi, i + is.u16[0] << 8 + (res_reg & 7) << 16); ICU8(tmpi, d3); } } else { ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, t3, r3, d3, rip); ICMov(tmpi, MDF_REG + RT_I64, res_reg, 0, t2, r2, d2, rip); ICU24(tmpi, i + is.u16[1] << 8 + (res_reg & 7) << 16); } ICMov(tmpi, t1, r1, d1, MDF_REG + RT_I64, res_reg, 0, rip); } U0 ICShiftEqu(CIntermediateCode *tmpi,U8 type_pointed_to, CICType t1, I64 r1, I64 d1, CICType t2, I64 r2, I64 d2, CICType t3, I64 r3, I64 d3, I64 us, I64 is, I64 rip) { I64 res_reg; if (tmpi->ic_class->raw_type & RTF_UNSIGNED || tmpi->ic_flags & ICF_USE_UNSIGNED) is = us; if (tmpi->ic_flags & ICF_BY_VAL) { if (!(t3 & MDF_IMM)) ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, t3, r3, d3, rip); if (t2 & MDF_REG) res_reg = r2; else { res_reg = REG_RAX; ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, t2 & MDG_MASK + type_pointed_to, r2, d2, rip); } if (res_reg > 7) ICU8(tmpi, 0x49); else ICU8(tmpi, 0x48); if (t3 & MDF_IMM) { if (d3 == 1) ICU16(tmpi, is.u16[2] + (res_reg & 7) << 8); else { ICU16(tmpi, is.u16[0] + (res_reg & 7) << 8); ICU8(tmpi, d3); } } else ICU16(tmpi, is.u16[1] + (res_reg & 7) << 8); ICMov(tmpi, t2 & MDG_MASK + type_pointed_to, r2, d2, MDF_REG + RT_I64, res_reg, 0, rip); } else { if (!(t3 & MDF_IMM)) ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, t3, r3, d3, rip); ICMov(tmpi, MDF_REG + RT_I64, REG_RDX, 0, t2, r2, d2, rip); ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, MDF_DISP + type_pointed_to, REG_RDX, 0, rip); res_reg = REG_RAX; ICU8(tmpi, 0x48); if (t3 & MDF_IMM) { if (d3 == 1) ICU16(tmpi, is.u16[2] + (res_reg & 7) << 8); else { ICU16(tmpi, is.u16[0] + (res_reg & 7) << 8); ICU8(tmpi, d3); } } else ICU16(tmpi, is.u16[1] + (res_reg & 7) << 8); ICMov(tmpi, MDF_DISP + type_pointed_to, REG_RDX, 0, MDF_REG + RT_I64, res_reg, 0, rip); } if (t1.mode) ICMov(tmpi, t1, r1, d1, MDF_REG + RT_I64, res_reg, 0, rip); }