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);
}
