JIT_OP_LADD_OVF: binary
	[lreg, imm] -> {
		unsigned char *patch;
		jit_uint value1 = ((jit_uint *)($2))[0];
		jit_uint value2 = ((jit_uint *)($2))[1];
		if(!value1)
		{
			x86_alu_reg_imm(inst, X86_ADD, $1, value1);
			x86_alu_reg_imm(inst, X86_ADC, %1, value2);
			patch = inst;
			x86_branch8(inst, X86_CC_NO, 0, 1);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch, inst);
		}
		else
		{
			x86_alu_reg_imm(inst, X86_ADD, %1, value2);
			patch = inst;
			x86_branch8(inst, X86_CC_NO, 0, 1);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch, inst);
		}
	}
	[lreg, local] -> {
		unsigned char *patch;
		x86_alu_reg_membase(inst, X86_ADD, $1, X86_EBP, $2);
		x86_alu_reg_membase(inst, X86_ADC, %1, X86_EBP, $2 + 4);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
	}
	[lreg, lreg] -> {
		unsigned char *patch;
		x86_alu_reg_reg(inst, X86_ADD, $1, $2);
		x86_alu_reg_reg(inst, X86_ADC, %1, %2);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
	}

JIT_OP_LADD_OVF_UN: binary
	[lreg, imm] -> {
		unsigned char *patch;
		jit_uint value1 = ((jit_uint *)($2))[0];
		jit_uint value2 = ((jit_uint *)($2))[1];
		if(value1 != 0)
		{
			x86_alu_reg_imm(inst, X86_ADD, $1, value1);
			x86_alu_reg_imm(inst, X86_ADC, %1, value2);
			patch = inst;
			x86_branch8(inst, X86_CC_NC, 0, 0);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch, inst);
		}
		else
		{
			x86_alu_reg_imm(inst, X86_ADD, %1, value2);
			patch = inst;
			x86_branch8(inst, X86_CC_NC, 0, 0);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch, inst);
		}
	}
	[lreg, local] -> {
		unsigned char *patch;
		x86_alu_reg_membase(inst, X86_ADD, $1, X86_EBP, $2);
		x86_alu_reg_membase(inst, X86_ADC, %1, X86_EBP, $2+4);
		patch = inst;
		x86_branch8(inst, X86_CC_NC, 0, 0);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
	}
	[lreg, lreg] -> {
		unsigned char *patch;
		x86_alu_reg_reg(inst, X86_ADD, $1, $2);
		x86_alu_reg_reg(inst, X86_ADC, %1, %2);
		patch = inst;
		x86_branch8(inst, X86_CC_NC, 0, 0);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
	}

JIT_OP_LSUB: binary
	[lreg, imm] -> {
		jit_uint value1 = ((jit_uint *)($2))[0];
		jit_uint value2 = ((jit_uint *)($2))[1];
		x86_alu_reg_imm(inst, X86_SUB, $1, value1);
		x86_alu_reg_imm(inst, X86_SBB, %1, value2);
	}
	[lreg, local] -> {
		x86_alu_reg_membase(inst, X86_SUB, $1, X86_EBP, $2);
		x86_alu_reg_membase(inst, X86_SBB, %1, X86_EBP, $2 + 4);
	}
	[lreg, lreg] -> {
		x86_alu_reg_reg(inst, X86_SUB, $1, $2);
		x86_alu_reg_reg(inst, X86_SBB, %1, %2);
	}

JIT_OP_LSUB_OVF: binary
	[lreg, imm] -> {
		jit_uint value1 = ((jit_uint *)($2))[0];
		jit_uint value2 = ((jit_uint *)($2))[1];
		unsigned char *patch;
		x86_alu_reg_imm(inst, X86_SUB, $1, value1);
		x86_alu_reg_imm(inst, X86_SBB, %1, value2);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
	}
	[lreg, local] -> {
		unsigned char *patch;
		x86_alu_reg_membase(inst, X86_SUB, $1, X86_EBP, $2);
		x86_alu_reg_membase(inst, X86_SBB, %1, X86_EBP, $2 + 4);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
	}
	[lreg, lreg] -> {
		unsigned char *patch;
		x86_alu_reg_reg(inst, X86_SUB, $1, $2);
		x86_alu_reg_reg(inst, X86_SBB, %1, %2);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
	}

JIT_OP_LSUB_OVF_UN: binary
	[lreg, imm] -> {
		jit_uint value1 = ((jit_uint *)($2))[0];
		jit_uint value2 = ((jit_uint *)($2))[1];
		unsigned char *patch;
		x86_alu_reg_imm(inst, X86_SUB, $1, value1);
		x86_alu_reg_imm(inst, X86_SBB, %1, value2);
		patch = inst;
		x86_branch8(inst, X86_CC_NC, 0, 0);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
	}
	[lreg, local] -> {
		unsigned char *patch;
		x86_alu_reg_membase(inst, X86_SUB, $1, X86_EBP, $2);
		x86_alu_reg_membase(inst, X86_SBB, %1, X86_EBP, $2 + 4);
		patch = inst;
		x86_branch8(inst, X86_CC_NC, 0, 0);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
	}
	[lreg, lreg] -> {
		unsigned char *patch;
		x86_alu_reg_reg(inst, X86_SUB, $1, $2);
		x86_alu_reg_reg(inst, X86_SBB, %1, %2);
		patch = inst;
		x86_branch8(inst, X86_CC_NC, 0, 0);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
	}

JIT_OP_LMUL:
	[=lreg("eax" | "edx"), local, local, scratch("eax", "ebx", "ecx", "edx")] -> {
		unsigned char *patch;
		x86_mov_reg_membase(inst, X86_EBX, X86_EBP, $2 + 4, 4);
		x86_mov_reg_membase(inst, X86_ECX, X86_EBP, $3 + 4, 4);
		x86_mov_reg_reg(inst, X86_EAX, X86_EBX, 4);
		x86_alu_reg_reg(inst, X86_OR, X86_EBX, X86_ECX);
		patch = inst;
		x86_branch8(inst, X86_CC_NE, 0, 0);
		x86_mul_membase(inst, X86_EBP, $3, 1);
		x86_mov_reg_reg(inst, X86_EBX, X86_EAX, 4);
		x86_mov_reg_membase(inst, X86_EAX, X86_EBP, $2, 4);
		x86_mul_reg(inst, X86_ECX, 1);
		x86_alu_reg_reg(inst, X86_ADD, X86_EBX, X86_EAX);
		x86_patch(patch, inst);
		x86_mov_reg_membase(inst, X86_EAX, X86_EBP, $2, 4);
		x86_mul_membase(inst, X86_EBP, $3, 0);
		x86_alu_reg_reg(inst, X86_ADD, X86_EDX, X86_EBX);
	}
	[lreg, imm, scratch("?"), clobber("eax", "edx")] -> {
		jit_uint value1 = ((jit_uint *)($2))[0];
		jit_uint value2 = ((jit_uint *)($2))[1];
		x86_mov_reg_reg(inst, $3, $1, 4);
		x86_imul_reg_reg_imm(inst, $3, $3, value2);
		x86_imul_reg_reg_imm(inst, %1, %1, value1);
		x86_alu_reg_reg(inst, X86_ADD, %1, $3);
		if(%1 == X86_EDX || %1 == X86_EAX) x86_mov_reg_reg(inst, $3, %1, 4);
		if($1 == X86_EAX)
		{
			x86_mov_reg_imm(inst, X86_EDX, value1);
			x86_mul_reg(inst, X86_EDX, 0);
		}
		else
		{
			x86_mov_reg_imm(inst, X86_EAX, value1);
			x86_mul_reg(inst, $1, 0);
		}
		if(%1 == X86_EDX || %1 == X86_EAX)
		{
			x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX);
			x86_mov_reg_reg(inst, %1, $3, 4);
		}
		else
		{
			x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX);
		}
	}

	[lreg, local, scratch("?"), clobber("eax", "edx")] -> {
		x86_mov_reg_reg(inst, $3, $1, 4);
		x86_imul_reg_membase(inst, $3, X86_EBP, $2 + 4);
		x86_imul_reg_membase(inst, %1, X86_EBP, $2);
		x86_alu_reg_reg(inst, X86_ADD, %1, $3);
		if(%1 == X86_EDX || %1 == X86_EAX) x86_mov_reg_reg(inst, $3, %1, 4);
		if($1 != X86_EAX) x86_mov_reg_reg(inst, X86_EAX, $1, 4);
		x86_mul_membase(inst, X86_EBP, $2, 0);
		if(%1 == X86_EDX || %1 == X86_EAX)
		{
			x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX);
			x86_mov_reg_reg(inst, %1, $3, 4);
		}
		else
		{
			x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX);
		}
		if($1 != X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4);
	}

	[lreg, lreg, scratch("?"), clobber("eax", "edx")] -> {
		x86_mov_reg_reg(inst, $3, $1, 4);
		x86_imul_reg_reg(inst, $3, %2);
		x86_imul_reg_reg(inst, %1, $2);
		x86_alu_reg_reg(inst, X86_ADD, %1, $3);
		if(%1 == X86_EDX || %1 == X86_EAX) x86_mov_reg_reg(inst, $3, %1, 4);
		if($1 != X86_EAX) x86_mov_reg_reg(inst, X86_EAX, $1, 4);
		x86_mul_reg(inst, $2, 0);
		if(%1 == X86_EDX || %1 == X86_EAX)
		{
			x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX);
			x86_mov_reg_reg(inst, %1, $3, 4);
		}
		else
		{
			x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX);
		}
		if($1 != X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4);
	}

JIT_OP_LMUL_OVF:
	[lreg, imm, scratch("?"), clobber("eax", "edx")] -> {
		unsigned char *patch;
		jit_uint value1 = ((jit_uint *)($2))[0];
		jit_uint value2 = ((jit_uint *)($2))[1];
		x86_mov_reg_reg(inst, $3, $1, 4);
		x86_imul_reg_reg_imm(inst, $3, $3, value2);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		x86_imul_reg_reg_imm(inst, %1, %1, value1);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		x86_alu_reg_reg(inst, X86_ADD, %1, $3);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		if(%1 == X86_EDX || %1 == X86_EAX) x86_mov_reg_reg(inst, $3, %1, 4);
		if($1 == X86_EAX)
		{
			x86_mov_reg_imm(inst, X86_EDX, value1);
			x86_mul_reg(inst, X86_EDX, 0);
		}
		else
		{
			x86_mov_reg_imm(inst, X86_EAX, value1);
			x86_mul_reg(inst, $1, 0);
			x86_mov_reg_reg(inst, $1, X86_EAX, 4);
		}
		if(%1 == X86_EDX || %1 == X86_EAX)
		{
			x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX);
			patch = inst;
			x86_branch8(inst, X86_CC_NO, 0, 1);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch, inst);
			x86_mov_reg_reg(inst, %1, $3, 4);
		}
		else
		{
			x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX);
			patch = inst;
			x86_branch8(inst, X86_CC_NO, 0, 1);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch, inst);
		}
	}
	[lreg, local, scratch("?"), clobber("eax", "edx")] -> {
		unsigned char *patch;
		x86_mov_reg_reg(inst, $3, $1, 4);
		x86_imul_reg_membase(inst, $3, X86_EBP, $2 + 4);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		x86_imul_reg_membase(inst, %1, X86_EBP, $2);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		x86_alu_reg_reg(inst, X86_ADD, %1, $3);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		if(%1 == X86_EDX || %1 == X86_EAX) x86_mov_reg_reg(inst, $3, %1, 4);
		if($1 != X86_EAX) x86_mov_reg_reg(inst, X86_EAX, $1, 4);
		x86_mul_membase(inst, X86_EBP, $2, 0);
		if(%1 == X86_EDX || %1 == X86_EAX)
		{
			x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX);
			patch = inst;
			x86_branch8(inst, X86_CC_NO, 0, 1);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch, inst);
			x86_mov_reg_reg(inst, %1, $3, 4);
		}
		else
		{
			x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX);
			patch = inst;
			x86_branch8(inst, X86_CC_NO, 0, 1);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch, inst);
		}
		if($1 != X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4);
	}
	[lreg, lreg, scratch("?"), clobber("eax", "edx")] -> {
		unsigned char *patch;
		x86_mov_reg_reg(inst, $3, $1, 4);
		x86_imul_reg_reg(inst, $3, %2);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		x86_imul_reg_reg(inst, %1, $2);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		x86_alu_reg_reg(inst, X86_ADD, %1, $3);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		if(%1 == X86_EDX || %1 == X86_EAX) x86_mov_reg_reg(inst, $3, %1, 4);
		if($1 != X86_EAX) x86_mov_reg_reg(inst, X86_EAX, $1, 4);
		x86_mul_reg(inst, $2, 0);
		if(%1 == X86_EDX || %1 == X86_EAX)
		{
			x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX);
			patch = inst;
			x86_branch8(inst, X86_CC_NO, 0, 1);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch, inst);
			x86_mov_reg_reg(inst, %1, $3, 4);
		}
		else
		{
			x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX);
			patch = inst;
			x86_branch8(inst, X86_CC_NO, 0, 1);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch, inst);
		}
		if($1!=X86_EAX)	x86_mov_reg_reg(inst, $1, X86_EAX, 4);
	}

JIT_OP_LMUL_OVF_UN: binary
	[lreg, imm, scratch("?"), clobber("eax", "edx")] -> {
		unsigned char *patch;
		jit_uint value1 = ((jit_uint *)($2))[0];
		jit_uint value2 = ((jit_uint *)($2))[1];
		x86_mov_reg_reg(inst, $3, $1, 4);
		x86_imul_reg_reg_imm(inst, $3, $1, value2);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		x86_imul_reg_reg_imm(inst, %1, %1, value1);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		x86_alu_reg_reg(inst, X86_ADD, %1, $3);
		patch = inst;
		x86_branch8(inst, X86_CC_NC, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		if(%1 == X86_EDX || %1 == X86_EAX) x86_mov_reg_reg(inst, $3, %1, 4);
		if($1 == X86_EAX)
		{
			x86_mov_reg_imm(inst, X86_EDX, value1);
			x86_mul_reg(inst, X86_EDX, 0);
		}
		else
		{
			x86_mov_reg_imm(inst, X86_EAX, value1);
			x86_mul_reg(inst, $1, 0);
		}
		if(%1 == X86_EDX || %1 == X86_EAX)
		{
			x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX);
			patch = inst;
			x86_branch8(inst, X86_CC_NC, 0, 1);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch, inst);
			x86_mov_reg_reg(inst, %1, $3, 4);
		}
		else
		{
			x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX);
			patch = inst;
			x86_branch8(inst, X86_CC_NC, 0, 1);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch, inst);
		}
		if($1 != X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4);
	}
	[lreg, local, scratch("?"), clobber("eax", "edx")] -> {
		unsigned char *patch;
		x86_mov_reg_reg(inst, $3, $1, 4);
		x86_imul_reg_membase(inst, $3, X86_EBP, $2 + 4);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		x86_imul_reg_membase(inst, %1, X86_EBP, $2);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		x86_alu_reg_reg(inst, X86_ADD, %1, $3);
		patch = inst;
		x86_branch8(inst, X86_CC_NC, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		if(%1 == X86_EDX || %1 == X86_EAX) x86_mov_reg_reg(inst, $3, %1, 4);
		if($1 != X86_EAX) x86_mov_reg_reg(inst, X86_EAX, $1, 4);
		x86_mul_membase(inst, X86_EBP, $2, 0);
		if(%1 == X86_EDX || %1 == X86_EAX)
		{
			x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX);
			patch = inst;
			x86_branch8(inst, X86_CC_NC, 0, 1);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch, inst);
			x86_mov_reg_reg(inst, %1, $3, 4);
		}
		else
		{
			x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX);
			patch = inst;
			x86_branch8(inst, X86_CC_NC, 0, 1);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch, inst);
		}
		if($1 != X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4);
	}
	[lreg, lreg, scratch("?"), clobber("eax", "edx")] -> {
		unsigned char *patch;
		x86_mov_reg_reg(inst, $3, $1, 4);
		x86_imul_reg_reg(inst, $3, %2);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		x86_imul_reg_reg(inst, %1, $2);
		patch = inst;
		x86_branch8(inst, X86_CC_NO, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		x86_alu_reg_reg(inst, X86_ADD, %1, $3);
		patch = inst;
		x86_branch8(inst, X86_CC_NC, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch, inst);
		if(%1 == X86_EDX || %1 == X86_EAX) x86_mov_reg_reg(inst, $3, %1, 4);
		if($1 != X86_EAX) x86_mov_reg_reg(inst, X86_EAX, $1, 4);
		x86_mul_reg(inst, $2, 0);
		if(%1 == X86_EDX || %1 == X86_EAX)
		{
			x86_alu_reg_reg(inst, X86_ADD, $3, X86_EDX);
			patch = inst;
			x86_branch8(inst, X86_CC_NC, 0, 0);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch, inst);
			x86_mov_reg_reg(inst, %1, $3, 4);
		}
		else
		{
			x86_alu_reg_reg(inst, X86_ADD, %1, X86_EDX);
			patch = inst;
			x86_branch8(inst, X86_CC_NC, 0, 0);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch, inst);
		}
		if($1 != X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4);
	}

JIT_OP_LDIV: binary
	[lreg, imm, clobber("eax", "ecx", "edx", "ebx")] -> {
		extern long long __divdi3(long long a, long long b);
		jit_uint value1 = ((jit_uint *)($2))[0];
		jit_uint value2 = ((jit_uint *)($2))[1];
		if(!$2) inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO);
		else if($2 == -1)
		{
			unsigned char *patch1, *patch2;
			x86_alu_reg_imm(inst, X86_CMP, %1, 0x80000000);
			patch1 = inst;
			x86_branch8(inst, X86_CC_NE, 0, 1);
			x86_alu_reg_imm(inst, X86_CMP, $1, 0);
			patch2 = inst;
			x86_branch8(inst, X86_CC_NE, 0, 1);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch1, inst);
			x86_patch(patch2, inst);
			x86_push_imm(inst, value2);
			x86_push_imm(inst, value1);
			x86_push_reg(inst, %1);
			x86_push_reg(inst, $1);
			x86_call_code(inst, __divdi3);
			x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 4 * sizeof(void *));	
			if(%1 != X86_EDX) x86_mov_reg_reg(inst, %1, X86_EDX, 4);
			if($1 != X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4);
		}
		else
		{
			x86_push_imm(inst, value2);
			x86_push_imm(inst, value1);
			x86_push_reg(inst, %1);
			x86_push_reg(inst, $1);
			x86_call_code(inst, __divdi3);
			x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 4 * sizeof(void *));	
			if(%1 != X86_EDX) x86_mov_reg_reg(inst, %1, X86_EDX, 4);
			if($1 != X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4);
		}
	}
	[lreg, local, clobber("eax", "ecx", "edx", "ebx")] -> {
		extern long long __divdi3(long long a, long long b);
		unsigned char *patch1, *patch2, *patch3, *patch4;
	    #ifndef JIT_USE_SIGNALS
		x86_alu_membase_imm(inst, X86_CMP, X86_EBP, $2, 0);
		patch1 = inst;
		x86_branch8(inst, X86_CC_NE, 0, 0);
		x86_alu_membase_imm(inst, X86_CMP, X86_EBP, $2 + 4, 0);
		patch2 = inst;
		x86_branch8(inst, X86_CC_NE, 0, 0);
		inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO);
		x86_patch(patch1, inst);
		x86_patch(patch2, inst);
	    #endif
		x86_alu_reg_imm(inst, X86_CMP, %1, 0x80000000);
		patch1 = inst;
		x86_branch8(inst, X86_CC_NE, 0, 1);
		x86_alu_reg_imm(inst, X86_CMP, $1, 0);
		patch2 = inst;
		x86_branch8(inst, X86_CC_NE, 0, 1);
		x86_alu_membase_imm(inst, X86_CMP, X86_EBP, $2, 0xffffffff);
		patch3 = inst;
		x86_branch8(inst, X86_CC_NE, 0, 1);
		x86_alu_membase_imm(inst, X86_CMP, X86_EBP, $2 + 4, 0xffffffff);
		patch4 = inst;
		x86_branch8(inst, X86_CC_NE, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch1, inst);
		x86_patch(patch2, inst);
		x86_patch(patch3, inst);
		x86_patch(patch4, inst);
		x86_push_membase(inst, X86_EBP, $2 + 4);
		x86_push_membase(inst, X86_EBP, $2);
		x86_push_reg(inst, %1);
		x86_push_reg(inst, $1);
		x86_call_code(inst, __divdi3);
		x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 4 * sizeof(void *));
		if(%1 != X86_EDX) x86_mov_reg_reg(inst, %1, X86_EDX, 4);
		if($1 != X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4);
	}
	[lreg, lreg, clobber("eax", "ecx", "edx", "ebx")] -> {
		extern long long __divdi3(long long a, long long b);
		unsigned char *patch1, *patch2, *patch3, *patch4;
	    #ifndef JIT_USE_SIGNALS
		x86_alu_reg_imm(inst, X86_CMP, $2, 0);
		patch1 = inst;
		x86_branch8(inst, X86_CC_NE, 0, 0);
		x86_alu_reg_imm(inst, X86_CMP, %2, 0);
		patch2 = inst;
		x86_branch8(inst, X86_CC_NE, 0, 0);
		inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO);
		x86_patch(patch1, inst);
		x86_patch(patch2, inst);
	    #endif
		x86_alu_reg_imm(inst, X86_CMP, %1, 0x80000000);
		patch1 = inst;
		x86_branch8(inst, X86_CC_NE, 0, 1);
		x86_alu_reg_imm(inst, X86_CMP, $1, 0);
		patch2 = inst;
		x86_branch8(inst, X86_CC_NE, 0, 1);
		x86_alu_reg_imm(inst, X86_CMP, $2, 0xffffffff);
		patch3 = inst;
		x86_branch8(inst, X86_CC_NE, 0, 1);
		x86_alu_reg_imm(inst, X86_CMP, %2, 0xffffffff);
		patch4 = inst;
		x86_branch8(inst, X86_CC_NE, 0, 1);
		inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
		x86_patch(patch1, inst);
		x86_patch(patch2, inst);
		x86_patch(patch3, inst);
		x86_patch(patch4, inst);
		x86_push_reg(inst, %2);
		x86_push_reg(inst, $2);
		x86_push_reg(inst, %1);
		x86_push_reg(inst, $1);
		x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 4 * sizeof(void *));
		x86_call_code(inst, __divdi3);
		if(%1 != X86_EDX) x86_mov_reg_reg(inst, %1, X86_EDX, 4);
		if($1 != X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4);
	}

JIT_OP_LDIV_UN: binary
	[lreg, imm, clobber("eax", "ecx", "edx", "ebx")] -> {
		extern unsigned long long __udivmoddi4(unsigned long long a, unsigned long long b, unsigned long long c);
		jit_uint value1 = ((jit_uint *)($2))[0];
		jit_uint value2 = ((jit_uint *)($2))[1];
		if($2 == 0)
		{
			inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO);
		}
	    	else
		{
			x86_push_imm(inst, 0);
			x86_push_imm(inst, 0);
			x86_push_imm(inst, value2);
			x86_push_imm(inst, value1);
			x86_push_reg(inst, %1);
			x86_push_reg(inst, $1);
			x86_call_code(inst, __udivmoddi4);
			x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 6 * sizeof(void *));	
			if(%1 != X86_EDX) x86_mov_reg_reg(inst, %1, X86_EDX, 4);
			if($1 != X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4);
		}
    	}
	[lreg, local, clobber("eax", "ecx", "edx", "ebx")] -> {
		extern unsigned long long __udivmoddi4(unsigned long long a, unsigned long long b, unsigned long long c);
		#ifndef JIT_USE_SIGNALS
		unsigned char *patch1, *patch2;
		x86_alu_membase_imm(inst, X86_CMP, X86_EBP, $2, 0);
		patch1 = inst;
		x86_branch8(inst, X86_CC_NE, 0, 0);
		x86_alu_membase_imm(inst, X86_CMP, X86_EBP, $2 + 4, 0);
		patch2 = inst;
		x86_branch8(inst, X86_CC_NE, 0, 0);
		inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO);
		x86_patch(patch1, inst);
		x86_patch(patch2, inst);
		#endif
		x86_push_imm(inst, 0);
		x86_push_imm(inst, 0);
		x86_push_membase(inst, X86_EBP, $2 + 4);
		x86_push_membase(inst, X86_EBP, $2);
		x86_push_reg(inst, %1);
		x86_push_reg(inst, $1);
		x86_call_code(inst, __udivmoddi4);
		x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 6 * sizeof(void *));	
		if(%1 != X86_EDX) x86_mov_reg_reg(inst, %1, X86_EDX, 4);
		if($1 != X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4);
	}
	[lreg, lreg, clobber("eax", "ecx", "edx", "ebx")] -> {
		extern unsigned long long __udivmoddi4(unsigned long long a, unsigned long long b, unsigned long long c);
		#ifndef JIT_USE_SIGNALS
		unsigned char *patch1, *patch2;
		x86_alu_membase_imm(inst, X86_CMP, X86_EBP, $2, 0);
		patch1 = inst;
		x86_branch8(inst, X86_CC_NE, 0, 0);
		x86_alu_membase_imm(inst, X86_CMP, X86_EBP, $2 + 4, 0);
		patch2 = inst;
		x86_branch8(inst, X86_CC_NE, 0, 0);
		inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO);
		x86_patch(patch1, inst);
		x86_patch(patch2, inst);
		#endif
		x86_push_imm(inst, 0);
		x86_push_imm(inst, 0);
		x86_push_reg(inst, %2);
		x86_push_reg(inst, $2);
		x86_push_reg(inst, %1);
		x86_push_reg(inst, $1);
		x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 6 * sizeof(void *));
		x86_call_code(inst, __udivmoddi4);
		if(%1 != X86_EDX) x86_mov_reg_reg(inst, %1, X86_EDX, 4);
		if($1 != X86_EAX) x86_mov_reg_reg(inst, $1, X86_EAX, 4);
	}
