U0 ICFOpEqu(CCompCtrl *cc, CIntermediateCode *tmpi, I64 op, U8 *buf2, I64 rip)
{//for ADD,SUB,DIV,MUL
        CICArg  *arg1 = &tmpi->arg1, *arg2 = &tmpi->arg2;
        Bool     dont_push_float, dont_pop_float, p1_mem;
        I64              rsp_size = 0, builtin2 = 0, t1, r1, d1, t2, r2, d2;

        if (cc->flags & CCF_AOT_COMPILE)
                buf2 = cc->aotc->rip;

        CompSetFloatOpPushPop(cc, tmpi, &dont_push_float, &dont_pop_float);
        if (dont_pop_float)
                throw('Compiler');

        if (tmpi->ic_flags & ICF_BY_VAL)
        {
                p1_mem = FALSE;
                if (dont_push_float)
                {
                        if (tmpi->arg1_type_pointed_to != RT_F64)
                        {
                                ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0,
                                          arg1->type & MDG_MASK + tmpi->arg1_type_pointed_to,
                                          arg1->reg, arg1->disp, rip);
                                ICFConvert2(cc, tmpi, REG_RAX, MDF_REG + RT_I64, REG_RAX, 0, FALSE, rip);
                                ICPush(tmpi, MDF_REG + RT_I64, REG_RAX, 0, rip);
                                t1 = MDF_SIB + RT_I64;
                                r1 = REG_RSP + REG_RSP << 8;
                                d1 = 0;
                                rsp_size += 8;
                        }
                        else
                        {
                                if (tmpi->arg1_type_pointed_to >= RT_I64 && arg1->type & MDG_DISP_SIB_RIP)
                                {
                                        t1 = arg1->type & MDG_MASK + tmpi->arg1_type_pointed_to;
                                        r1 = arg1->reg;
                                        d1 = arg1->disp;
                                        p1_mem = TRUE;
                                }
                                else
                                {
                                        ICPush(tmpi, arg1->type & MDG_MASK + tmpi->arg1_type_pointed_to, arg1->reg, arg1->disp, rip);
                                        t1 = MDF_SIB + RT_I64;
                                        r1 = REG_RSP + REG_RSP << 8;
                                        d1 = 0;
                                        rsp_size += 8;
                                }
                        }
                }
                else
                {
                        if (tmpi->arg1_type_pointed_to != RT_F64 || arg1->type & MDF_STACK)
                        {
                                ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, arg2->type, arg2->reg, arg2->disp, rip);
                                ICMov(tmpi, MDF_REG + RT_I64, REG_RDX, 0,
                                          arg1->type & MDG_MASK + tmpi->arg1_type_pointed_to,
                                          arg1->reg, arg1->disp, rip);
                                if (tmpi->arg1_type_pointed_to != RT_F64)
                                        ICFConvert2(cc, tmpi, REG_RDX, MDF_REG + RT_I64, REG_RDX, 0, FALSE, rip);
                                ICU16(tmpi, 0x5052); //PUSH EDX PUSH EAX
                                rsp_size = 16;
                                t1 = MDF_SIB + RT_I64;
                                r1 = REG_RSP + REG_RSP << 8;
                                d1 = 8;
                                t2 = MDF_SIB + RT_I64;
                                r2 = REG_RSP + REG_RSP << 8;
                                d2 = 0;
                        }
                        else
                        {
                                if (arg2->type.raw_type >= RT_I64 && arg2->type & MDG_DISP_SIB_RIP)
                                {
                                        t2 = arg2->type;
                                        r2 = arg2->reg;
                                        d2 = arg2->disp;
                                }
                                else
                                {
                                        if (arg2->type & MDF_IMM)
                                        {
                                                if (!(builtin2 = ICBuiltInFloatConst(arg2->disp(F64))))
                                                {
                                                        t2 = MDF_RIP_DISP32 + RT_I64;
                                                        r2 = REG_RIP;
                                                        d2 = COCFloatConstFind(cc, arg2->disp(F64)) + buf2;
                                                }
                                        }
                                        else
                                        {
                                                ICPush(tmpi, arg2->type, arg2->reg, arg2->disp, rip);
                                                t2 = MDF_SIB + RT_I64;
                                                r2 = REG_RSP + REG_RSP << 8;
                                                d2 = 0;
                                                rsp_size += 8;
                                        }
                                }
                                if (tmpi->arg1_type_pointed_to >= RT_I64 && arg1->type & MDG_DISP_SIB_RIP)
                                {
                                        t1 = arg1->type & MDG_MASK + tmpi->arg1_type_pointed_to;
                                        r1 = arg1->reg;
                                        d1 = arg1->disp;
                                        p1_mem = TRUE;
                                }
                                else
                                {
                                        ICPush(tmpi, arg1->type & MDG_MASK + tmpi->arg1_type_pointed_to, arg1->reg, arg1->disp, rip);
                                        t1 = MDF_SIB + RT_I64;
                                        r1 = REG_RSP + REG_RSP << 8;
                                        d1 = 0;
                                        rsp_size += 8;
                                        if (r2 == REG_RSP + REG_RSP << 8)
                                                d2 += 8;
                                }
                        }
                }
                if (!rsp_size && !(p1_mem && tmpi->arg1_type_pointed_to == RT_F64))
                {
                        rsp_size = 8;
                        ICAddRSP(tmpi, -8);
                }
                if (!dont_push_float)
                {
                        if (builtin2)
                                ICU16(tmpi, builtin2);
                        else
                                ICSlashOp(tmpi, t2, r2, d2, SLASH_OP_FLD, rip);
                }
                switch (op.u8[0])
                {
                        case 4:
                                op = SLASH_OP_FSUBR;
                                break;

                        case 6:
                                op = SLASH_OP_FDIVR;
                                break;
                }
                ICSlashOp(tmpi, t1, r1, d1, op, rip);
                CompNoteFloatOp(cc, tmpi, TRUE, FALSE, CN_INST);
                if (p1_mem && tmpi->arg1_type_pointed_to == RT_F64)
                {
                        ICSlashOp(tmpi, t1, r1, d1, SLASH_OP_FSTP, rip);
                        if (rsp_size)
                                ICAddRSP(tmpi, rsp_size);
                }
                else
                {
                        if (rsp_size == 8)
                                ICSlashOp(tmpi, MDF_SIB + RT_I64, REG_RSP + REG_RSP << 8, 0, SLASH_OP_FSTP, rip);
                        else if (rsp_size > 8)
                        {
                                ICSlashOp(tmpi, MDF_SIB + RT_I64, REG_RSP + REG_RSP << 8, rsp_size - 8, SLASH_OP_FSTP, rip);
                                ICAddRSP(tmpi, rsp_size - 8);
                        }
                        if (tmpi->arg1_type_pointed_to != RT_F64)
                        {
                                ICPop(tmpi, MDF_REG + RT_I64, REG_RAX, 0, rip);
                                ICFConvert2(cc, tmpi, REG_RAX, MDF_REG + RT_I64, REG_RAX, 0, TRUE, rip);
                                ICMov(tmpi,arg1->type & MDG_MASK + tmpi->arg1_type_pointed_to,
                                          arg1->reg, arg1->disp, MDF_REG + RT_I64, REG_RAX, 0, rip);
                        }
                        else
                                ICPop(tmpi, arg1->type & MDG_MASK + tmpi->arg1_type_pointed_to,
                                          arg1->reg, arg1->disp, rip);
                }
                if (tmpi->res.type.mode)
                        ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp,
                                                arg1->type & MDG_MASK + tmpi->arg1_type_pointed_to,
                                                arg1->reg, arg1->disp, rip);
        }
        else
        {
                if (tmpi->arg1_type_pointed_to >= RT_I64)
                        p1_mem = TRUE;
                else
                        p1_mem = FALSE;
                if (dont_push_float)
                {
                        ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, arg1->type, arg1->reg, arg1->disp, rip);
                        if (tmpi->arg1_type_pointed_to != RT_F64)
                        {
                                ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, MDF_DISP + tmpi->arg1_type_pointed_to, REG_RCX, 0, rip);
                                ICFConvert2(cc, tmpi, REG_RAX, MDF_REG + RT_I64, REG_RAX, 0, FALSE, rip);
                                ICPush(tmpi, MDF_REG + RT_I64, REG_RAX, 0, rip);
                        }
                        else
                                ICPush(tmpi, MDF_DISP + tmpi->arg1_type_pointed_to, REG_RCX, 0, rip);
                        t1 = MDF_SIB + RT_I64;
                        r1 = REG_RSP + REG_RSP << 8;
                        d1 = 0;
                        rsp_size += 8;
                }
                else
                {
                        if (tmpi->arg1_type_pointed_to != RT_F64 || arg1->type & MDF_STACK)
                        {
                                ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, arg2->type, arg2->reg, arg2->disp, rip);
                                ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, arg1->type, arg1->reg, arg1->disp, rip);
                                ICMov(tmpi, MDF_REG + RT_I64, REG_RDX, 0, MDF_DISP + tmpi->arg1_type_pointed_to, REG_RCX, 0, rip);
                                if (tmpi->arg1_type_pointed_to != RT_F64)
                                        ICFConvert2(cc,tmpi, REG_RDX, MDF_REG + RT_I64, REG_RDX, 0, FALSE, rip);
                                ICU16(tmpi, 0x5052);            //PUSH EDX PUSH EAX
                                rsp_size = 16;
                                t1 = MDF_SIB + RT_I64;
                                r1 = REG_RSP + REG_RSP << 8;
                                d1 = 8;
                                t2 = MDF_SIB + RT_I64;
                                r2 = REG_RSP + REG_RSP << 8;
                                d2 = 0;
                        }
                        else
                        {
                                if (arg2->type.raw_type >= RT_I64 && arg2->type & MDG_DISP_SIB_RIP)
                                {
                                        t2 = arg2->type;
                                        r2 = arg2->reg;
                                        d2 = arg2->disp;
                                }
                                else
                                {
                                        if (arg2->type & MDF_IMM)
                                        {
                                                if (!(builtin2 = ICBuiltInFloatConst(arg2->disp(F64))))
                                                {
                                                        t2 = MDF_RIP_DISP32 + RT_I64;
                                                        r2 = REG_RIP;
                                                        d2 = COCFloatConstFind(cc, arg2->disp(F64)) + buf2;
                                                }
                                        }
                                        else
                                        {
                                                ICPush(tmpi, arg2->type, arg2->reg, arg2->disp, rip);
                                                t2 = MDF_SIB + RT_I64;
                                                r2 = REG_RSP + REG_RSP << 8;
                                                d2 = 0;
                                                rsp_size += 8;
                                        }
                                }
                                ICMov(tmpi, MDF_REG + RT_I64, REG_RCX, 0, arg1->type, arg1->reg, arg1->disp, rip);
                                ICPush(tmpi, MDF_DISP + tmpi->arg1_type_pointed_to, REG_RCX, 0, rip);
                                t1 = MDF_SIB + RT_I64;
                                r1 = REG_RSP + REG_RSP << 8;
                                d1 = 0;
                                rsp_size += 8;
                                if (r2 == REG_RSP + REG_RSP << 8)
                                        d2 += 8;
                        }
                }
                if (!rsp_size && !(p1_mem && tmpi->arg1_type_pointed_to == RT_F64))
                {
                        rsp_size = 8;
                        ICAddRSP(tmpi, -8);
                }
                if (!dont_push_float)
                {
                        if (builtin2)
                                ICU16(tmpi, builtin2);
                        else
                                ICSlashOp(tmpi, t2, r2, d2, SLASH_OP_FLD, rip);
                }

                switch (op.u8[0])
                {
                        case 4:
                                op = SLASH_OP_FSUBR;
                                break;

                        case 6:
                                op = SLASH_OP_FDIVR;
                                break;
                }
                ICSlashOp(tmpi, t1, r1, d1, op, rip);
                CompNoteFloatOp(cc, tmpi, TRUE, FALSE, CN_INST);
                if (p1_mem && tmpi->arg1_type_pointed_to == RT_F64)
                {
                        ICSlashOp(tmpi, MDF_DISP + tmpi->arg1_type_pointed_to, REG_RCX, 0, SLASH_OP_FSTP, rip);
                        if (rsp_size)
                                ICAddRSP(tmpi, rsp_size);
                }
                else
                {
                        if (rsp_size == 8)
                                ICSlashOp(tmpi, MDF_SIB + RT_I64, REG_RSP + REG_RSP << 8, 0, SLASH_OP_FSTP, rip);
                        else if (rsp_size > 8)
                        {
                                ICSlashOp(tmpi, MDF_SIB + RT_I64, REG_RSP + REG_RSP << 8, rsp_size - 8, SLASH_OP_FSTP, rip);
                                ICAddRSP(tmpi, rsp_size - 8);
                        }
                        ICPop(tmpi, MDF_REG + RT_I64, REG_RAX, 0, rip);
                        if (tmpi->arg1_type_pointed_to != RT_F64)
                                ICFConvert2(cc, tmpi, REG_RAX, MDF_REG + RT_I64, REG_RAX, 0, TRUE, rip);
                        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, REG_RAX, 0, rip);
        }
}
 
U0 ICFCmpAndBranch(CCompCtrl *cc, CIntermediateCode *tmpi, I64 rip, I64 us, I64 not_us, U8 *buf, I64 rip2)
{
        CICArg          *arg1, *arg2;
        Bool             dont_push_float, dont_pop_float, alt, short_jmp;
        I64                      i, rsp_size = 0, builtin1 = 0, builtin2 = 0, t1, r1, d1, t2, r2, d2;
        CCodeMisc       *lb;
        U8                      *buf2;

        if (tmpi->ic_flags & ICF_ALT_TEMPLATE)
        {
                arg1 = &tmpi->arg2;
                arg2 = &tmpi->arg1;
                alt = TRUE;
        }
        else
        {
                arg1 = &tmpi->arg1;
                arg2 = &tmpi->arg2;
                alt = FALSE;
        }

        if (cc->flags & CCF_AOT_COMPILE)
                buf2 = cc->aotc->rip;
        else
                buf2 = buf;

        CompSetFloatOpPushPop(cc, tmpi, &dont_push_float, &dont_pop_float);
        if (dont_push_float)
        {
                if (tmpi->ic_flags & ICF_POP_CMP && alt)
                {
                        t2 = MDF_SIB + RT_I64;
                        r2 = REG_RSP + REG_RSP << 8;
                        d2 = 0;
                        rsp_size += 8;
                }
                else
                {
                        if (arg2->type.raw_type >= RT_I64 && arg2->type & MDG_DISP_SIB_RIP)
                        {
                                t2 = arg2->type;
                                r2 = arg2->reg;
                                d2 = arg2->disp;
                        }
                        else
                        {
                                if (arg2->type & MDF_IMM)
                                {
                                        if (!(builtin2 = ICBuiltInFloatConst(arg2->disp(F64))) || tmpi->ic_flags & ICF_PUSH_CMP)
                                        {
                                                t2 = MDF_RIP_DISP32 + RT_I64;
                                                r2 = REG_RIP;
                                                d2 = COCFloatConstFind(cc, arg2->disp(F64)) + buf2;
                                        }
                                }
                                else
                                {
                                        ICPush(tmpi, arg2->type, arg2->reg, arg2->disp, rip2);
                                        t2 = MDF_SIB + RT_I64;
                                        r2 = REG_RSP + REG_RSP << 8;
                                        d2 = 0;
                                        rsp_size += 8;
                                }
                        }
                }
        }
        else
        {
                if (alt)
                {
                        if (!(arg2->type & MDF_STACK))
                        {
                                if (tmpi->ic_flags & ICF_POP_CMP)
                                {
                                        t1 = MDF_SIB + RT_I64;
                                        r1 = REG_RSP + REG_RSP << 8;
                                        d1 = 0;
                                        rsp_size += 8;
                                }
                                else
                                {
                                        if (arg1->type.raw_type >= RT_I64 && arg1->type & MDG_DISP_SIB_RIP)
                                        {
                                                t1 = arg1->type;
                                                r1 = arg1->reg;
                                                d1 = arg1->disp;
                                        }
                                        else
                                        {
                                                if (arg1->type & MDF_IMM)
                                                {
                                                        if (!(builtin1 = ICBuiltInFloatConst(arg1->disp(F64))))
                                                        {
                                                                t1 = MDF_RIP_DISP32 + RT_I64;
                                                                r1 = REG_RIP;
                                                                d1 = COCFloatConstFind(cc, arg1->disp(F64)) + buf2;
                                                        }
                                                }
                                                else
                                                {
                                                        ICPush(tmpi, arg1->type, arg1->reg, arg1->disp, rip2);
                                                        t1 = MDF_SIB + RT_I64;
                                                        r1 = REG_RSP + REG_RSP << 8;
                                                        d1 = 0;
                                                        rsp_size += 8;
                                                }
                                        }
                                }
                                if (arg2->type.raw_type >= RT_I64 && arg2->type & MDG_DISP_SIB_RIP)
                                {
                                        t2 = arg2->type;
                                        r2 = arg2->reg;
                                        d2 = arg2->disp;
                                }
                                else
                                {
                                        if (arg2->type & MDF_IMM)
                                        {
                                                if (!(builtin2 = ICBuiltInFloatConst(arg2->disp(F64))) || tmpi->ic_flags & ICF_PUSH_CMP)
                                                {
                                                        t2 = MDF_RIP_DISP32 + RT_I64;
                                                        r2 = REG_RIP;
                                                        d2 = COCFloatConstFind(cc, arg2->disp(F64)) + buf2;
                                                }
                                        }
                                        else
                                        {
                                                ICPush(tmpi, arg2->type, arg2->reg, arg2->disp, rip2);
                                                t2 = MDF_SIB + RT_I64;
                                                r2 = REG_RSP + REG_RSP << 8;
                                                d2 = 0;
                                                rsp_size += 8;
                                                if (r1 == REG_RSP + REG_RSP << 8)
                                                        d1 += 8;
                                        }
                                }
                        }
                        else
                        {
                                if (tmpi->ic_flags & ICF_POP_CMP)
                                        ICPopRegs(tmpi, 1 << REG_RDX);
                                else
                                        ICMov(tmpi, MDF_REG + RT_I64, REG_RDX, 0, arg1->type, arg1->reg, arg1->disp, rip2);
                                ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, arg2->type, arg2->reg, arg2->disp, rip2);
                                ICU16(tmpi, 0x5052);            //PUSH EDX PUSH EAX
                                rsp_size = 16;
                                t1 = MDF_SIB + RT_I64;
                                r1 = REG_RSP + REG_RSP << 8;
                                d1 = 8;
                                t2 = MDF_SIB + RT_I64;
                                r2 = REG_RSP + REG_RSP << 8;
                                d2 = 0;
                        }
                }
                else
                {
                        if (!(arg1->type & MDF_STACK))
                        {
                                if (arg2->type.raw_type >= RT_I64 && arg2->type & MDG_DISP_SIB_RIP)
                                {
                                        t2 = arg2->type;
                                        r2 = arg2->reg;
                                        d2 = arg2->disp;
                                }
                                else
                                {
                                        if (arg2->type & MDF_IMM)
                                        {
                                                if (!(builtin2 = ICBuiltInFloatConst(arg2->disp(F64))) || tmpi->ic_flags & ICF_PUSH_CMP)
                                                {
                                                        t2 = MDF_RIP_DISP32 + RT_I64;
                                                        r2 = REG_RIP;
                                                        d2 = COCFloatConstFind(cc, arg2->disp(F64)) + buf2;
                                                }
                                        }
                                        else
                                        {
                                                ICPush(tmpi, arg2->type, arg2->reg, arg2->disp, rip2);
                                                t2 = MDF_SIB + RT_I64;
                                                r2 = REG_RSP + REG_RSP << 8;
                                                d2 = 0;
                                                rsp_size += 8;
                                        }
                                }
                                if (tmpi->ic_flags & ICF_POP_CMP)
                                {
                                        t1 = MDF_SIB + RT_I64;
                                        r1 = REG_RSP + REG_RSP << 8;
                                        d1 = 0;
                                        rsp_size += 8;
                                        if (r2 == REG_RSP + REG_RSP << 8)
                                                d1 += 8;
                                }
                                else
                                {
                                        if (arg1->type.raw_type >= RT_I64 && arg1->type & MDG_DISP_SIB_RIP)
                                        {
                                                t1 = arg1->type;
                                                r1 = arg1->reg;
                                                d1 = arg1->disp;
                                        }
                                        else
                                        {
                                                if (arg1->type & MDF_IMM)
                                                {
                                                        if (!(builtin1 = ICBuiltInFloatConst(arg1->disp(F64))))
                                                        {
                                                                t1 = MDF_RIP_DISP32 + RT_I64;
                                                                r1 = REG_RIP;
                                                                d1 = COCFloatConstFind(cc, arg1->disp(F64)) + buf2;
                                                        }
                                                }
                                                else
                                                {
                                                        ICPush(tmpi, arg1->type, arg1->reg, arg1->disp, rip2);
                                                        t1 = MDF_SIB + RT_I64;
                                                        r1 = REG_RSP + REG_RSP << 8;
                                                        d1 = 0;
                                                        rsp_size += 8;
                                                        if (r2 == REG_RSP + REG_RSP << 8)
                                                                d2 += 8;
                                                }
                                        }
                                }
                        }
                        else
                        {
                                ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, arg2->type, arg2->reg, arg2->disp, rip2);
                                if (tmpi->ic_flags & ICF_POP_CMP)
                                        ICPopRegs(tmpi, 1 << REG_RDX);
                                else
                                        ICMov(tmpi, MDF_REG + RT_I64, REG_RDX, 0, arg1->type, arg1->reg, arg1->disp, rip2);
                                ICU16(tmpi, 0x5052); //PUSH EDX PUSH EAX
                                rsp_size = 16;
                                t1 = MDF_SIB + RT_I64;
                                r1 = REG_RSP + REG_RSP << 8;
                                d1 = 8;
                                t2 = MDF_SIB + RT_I64;
                                r2 = REG_RSP + REG_RSP << 8;
                                d2 = 0;
                        }
                }
        }
        if (!dont_push_float)
        {
                if (builtin1)
                        ICU16(tmpi, builtin1);
                else
                        ICSlashOp(tmpi, t1, r1, d1, SLASH_OP_FLD, rip2);
        }
        if (!alt)
                us = not_us;
        if (builtin2)
                ICU16(tmpi, builtin2);
        else
                ICSlashOp(tmpi, t2, r2, d2, SLASH_OP_FLD, rip2);
        if (tmpi->ic_flags & ICF_PUSH_CMP)
        {
                t2 = MDF_SIB + RT_I64;
                r2 = REG_RSP + REG_RSP << 8;
                d2 = 0;
                if (!rsp_size)
                {
                        rsp_size = 8;
                        ICAddRSP(tmpi, -8);
                }
                else if (rsp_size == 16)
                        d2 = 8;

                if (alt)
                {
                        ICU16(tmpi, 0xF1DF); //FCOMIP
                        ICSlashOp(tmpi, t2, r2, d2, SLASH_OP_FSTP, rip2);
                }
                else
                {
                        ICU16(tmpi, 0xF1DB); //FCOMI
                        ICSlashOp(tmpi, t2, r2, d2, SLASH_OP_FSTP, rip2);
                        ICU32(tmpi, 0xF7D9C0DD); //FFREE,FINCSTP
                }
        }
        else
        {
                ICU16(tmpi, 0xF1DF);     //FCOMIP
                ICU32(tmpi, 0xF7D9C0DD); //FFREE, FINCSTP
        }
        CompNoteFloatOp(cc, tmpi, TRUE, FALSE, CN_INST);

        if (tmpi->ic_flags & ICF_PUSH_CMP)
        {
                if (r2.u8[0] == REG_RSP)
                {
                        while (d2 && rsp_size)
                        {
                                ICU8(tmpi, 0x5B); //POP RBX (Dont change flags)
                                rsp_size -= 8;
                                d2 -= 8;
                        }
                }
                else
                {
                        while (rsp_size)
                        {
                                ICU8(tmpi, 0x5B); //POP RBX (Dont change flags)
                                rsp_size -= 8;
                        }
                        ICPush(tmpi, t2, r2, d2, rip2);
                }
        }
        else
        {
                while (rsp_size)
                {
                        ICU8(tmpi, 0x5B); //POP RBX (Dont change flags)
                        rsp_size -= 8;
                }
        }

        rip += tmpi->ic_count;
        lb = OptLabelFwd(tmpi->ic_data);
        short_jmp = ToBool(tmpi->ic_flags & ICF_SHORT_JMP);
        if (!buf && lb->addr != INVALID_PTR)
        {
                i = lb->addr - (rip + 2);
                if (lb->flags & CMF_POP_CMP)
                {
                        if (tmpi->ic_flags & ICF_PUSH_CMP)
                                i += 4;
                        else
                                i += 8;
                }
                if (I8_MIN <= i <= I8_MAX)
                        short_jmp = TRUE;
        }

        if (short_jmp)
        {
                tmpi->ic_flags |= ICF_SHORT_JMP;
                i = lb->addr - (rip + 2);
                if (lb->flags & CMF_POP_CMP)
                {
                        if (tmpi->ic_flags & ICF_PUSH_CMP)
                                i += 4;
                        else
                                i += 8;
                }
                ICU16(tmpi, i << 8 + us.u8[2]);
        }
        else
        {
                tmpi->ic_flags &= ~ICF_SHORT_JMP;
                i = lb->addr - (rip + 6);
                if (lb->flags & CMF_POP_CMP)
                {
                        if (tmpi->ic_flags & ICF_PUSH_CMP)
                                i += 4;
                        else
                                i += 8;
                }
                ICU16(tmpi, us.u16[0]);
                ICU32(tmpi, i);
        }
}

U0 ICFMul(CCompCtrl *cc, CIntermediateCode *tmpi, U8 *buf, I64 rip)
{
        if (tmpi->arg1.type & MDF_IMM && tmpi->arg1.type & RTG_MASK == RT_F64 && tmpi->arg1.disp(F64) == 1.0)
        {
                CompNoteFloatOp(cc, tmpi, FALSE, FALSE, CN_INST);
                ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp, tmpi->arg2.type, tmpi->arg2.reg, tmpi->arg2.disp, rip);
        }
        else if (tmpi->arg2.type & MDF_IMM && tmpi->arg2.type & RTG_MASK == RT_F64 && tmpi->arg2.disp(F64) == 1.0)
        {
                CompNoteFloatOp(cc, tmpi, FALSE, FALSE, CN_INST);
                ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp, tmpi->arg1.type, tmpi->arg1.reg, tmpi->arg1.disp, rip);
        }
        else
                ICFOp(cc, tmpi, SLASH_OP_FMUL, buf, rip);
}

U0 ICFDiv(CCompCtrl *cc, CIntermediateCode *tmpi, U8 *buf, I64 rip)
{
        if (tmpi->arg2.type & MDF_IMM && tmpi->arg2.type & RTG_MASK == RT_F64 && tmpi->arg2.disp(F64) == 1.0)
        {
                CompNoteFloatOp(cc, tmpi, FALSE, FALSE, CN_INST);
                ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp, tmpi->arg1.type, tmpi->arg1.reg, tmpi->arg1.disp, rip);
        }
        else
                ICFOp(cc, tmpi, SLASH_OP_FDIV, buf, rip);
}

U0 ICFAdd(CCompCtrl *cc, CIntermediateCode *tmpi, U8 *buf, I64 rip)
{
        Bool dont_push_float, dont_pop_float;

        CompSetFloatOpPushPop(cc, tmpi, &dont_push_float, &dont_pop_float);
        if (tmpi->arg1.type & MDF_IMM && !tmpi->arg1.disp)
        {
                if (dont_push_float)
                {
                        ICCopyTemplate(cc, tmpi, CMP_TEMPLATE_FSTP, FALSE, TRUE, TRUE, CN_INST);
                        ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp, MDF_REG + RT_I64, REG_RAX, 0, rip);
                }
                else if (dont_pop_float)
                {
                        ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, tmpi->arg2.type, tmpi->arg2.reg, tmpi->arg2.disp, rip);
                        ICCopyTemplate(cc, tmpi, CMP_TEMPLATE_FLD, FALSE, TRUE, TRUE, CN_INST);
                }
                else
                {
                        CompNoteFloatOp(cc, tmpi, TRUE, TRUE, CN_INST);
                        ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp, tmpi->arg2.type, tmpi->arg2.reg, tmpi->arg2.disp, rip);
                }
        }
        else if (tmpi->arg2.type & MDF_IMM && !tmpi->arg2.disp)
        {
                if (dont_push_float)
                {
                        ICCopyTemplate(cc, tmpi, CMP_TEMPLATE_FSTP, FALSE, TRUE, TRUE, CN_INST);
                        ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp, MDF_REG + RT_I64, REG_RAX, 0, rip);
                }
                else if (dont_pop_float)
                {
                        ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, tmpi->arg1.type, tmpi->arg1.reg, tmpi->arg1.disp, rip);
                        ICCopyTemplate(cc, tmpi, CMP_TEMPLATE_FLD, FALSE, TRUE, TRUE, CN_INST);
                }
                else
                {
                        ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp, tmpi->arg1.type, tmpi->arg1.reg, tmpi->arg1.disp, rip);
                        CompNoteFloatOp(cc, tmpi, TRUE, TRUE, CN_INST);
                }
        }
        else
                ICFOp(cc, tmpi, SLASH_OP_FADD, buf, rip);
}

U0 ICFSub(CCompCtrl *cc, CIntermediateCode *tmpi, U8 *buf, I64 rip)
{
        Bool dont_push_float, dont_pop_float;

        if (tmpi->arg2.type & MDF_IMM && !tmpi->arg2.disp)
        {
                CompSetFloatOpPushPop(cc, tmpi, &dont_push_float, &dont_pop_float);
                if (dont_push_float)
                {
                        ICCopyTemplate(cc, tmpi, CMP_TEMPLATE_FSTP, FALSE, TRUE, TRUE, CN_INST);
                        ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp, MDF_REG + RT_I64, REG_RAX, 0, rip);
                }
                else if (dont_pop_float)
                {
                        ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, tmpi->arg1.type, tmpi->arg1.reg, tmpi->arg1.disp, rip);
                        ICCopyTemplate(cc, tmpi, CMP_TEMPLATE_FLD, FALSE, TRUE, TRUE, CN_INST);
                }
                else
                {
                        ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp, tmpi->arg1.type, tmpi->arg1.reg, tmpi->arg1.disp, rip);
                        CompNoteFloatOp(cc, tmpi, TRUE, TRUE, CN_INST);
                }
        }
        else
                ICFOp(cc, tmpi, SLASH_OP_FSUB, buf, rip);
}

U0 ICFPreIncDec(CCompCtrl *cc, CIntermediateCode *tmpi, I64 op, I64 rip)
{
        if (tmpi->ic_flags & ICF_BY_VAL)
        {
                ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, tmpi->arg1.type & MDG_MASK + RT_I64, tmpi->arg1.reg, tmpi->arg1.disp, rip);
                ICCopyTemplate(cc, tmpi, op, FALSE, TRUE, TRUE, CN_INST);
                ICMov(tmpi, tmpi->arg1.type, 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->arg1.type, tmpi->arg1.reg, tmpi->arg1.disp, rip);
                ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, MDF_DISP + RT_I64, REG_RCX, 0, rip);
                ICCopyTemplate(cc, tmpi, op, FALSE, TRUE, TRUE, CN_INST);
                ICMov(tmpi, MDF_DISP + RT_I64, 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, REG_RAX, 0, rip);
}

U0 ICFPostIncDec(CCompCtrl *cc, CIntermediateCode *tmpi, I64 op, I64 rip)
{
        if (tmpi->ic_flags & ICF_BY_VAL)
        {
                ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, tmpi->arg1.type & MDG_MASK + RT_I64, tmpi->arg1.reg, tmpi->arg1.disp, rip);
                if (tmpi->res.type.mode)
                        ICMov(tmpi, MDF_REG + RT_I64, REG_RDX, 0, MDF_REG + RT_I64, REG_RAX, 0, rip);
                ICCopyTemplate(cc, tmpi, op, FALSE, TRUE, TRUE, CN_INST);
                ICMov(tmpi, tmpi->arg1.type, 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->arg1.type, tmpi->arg1.reg, tmpi->arg1.disp, rip);
                ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, MDF_DISP + RT_I64, REG_RCX, 0, rip);
                if (tmpi->res.type.mode)
                        ICMov(tmpi, MDF_REG + RT_I64, REG_RDX, 0, MDF_REG + RT_I64, REG_RAX, 0, rip);
                ICCopyTemplate(cc, tmpi, op, FALSE, TRUE, TRUE, CN_INST);
                ICMov(tmpi, MDF_DISP + RT_I64, 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, REG_RDX, 0, rip);
}

U0 ICFTemplateFun(CCompCtrl *cc, CIntermediateCode *tmpi, I64 op, I64 rip)
{
        Bool dont_push_float, dont_pop_float;

        CompSetFloatOpPushPop(cc, tmpi, &dont_push_float, &dont_pop_float);
        if (!dont_push_float)
                ICMov(tmpi, MDF_REG + RT_I64, REG_RAX, 0, tmpi->arg1.type, tmpi->arg1.reg, tmpi->arg1.disp, rip);

        ICCopyTemplate(cc, tmpi, op, FALSE, TRUE, TRUE, CN_INST);
        if (tmpi->res.type.mode && !(tmpi->ic_flags & ICF_RES_TO_F64) && !(tmpi->ic_flags & ICF_RES_TO_INT))
                ICMov(tmpi, tmpi->res.type, tmpi->res.reg, tmpi->res.disp, MDF_REG + RT_I64, REG_RAX, 0, rip);
}