JIT_OP_LADD: binary
	[lreg, imm] -> {
		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);
		}
		else if(value2 != 0)
		{
			x86_alu_reg_imm(inst, X86_ADD, %1, value2);
		}
	}
	[lreg, local] -> {
		x86_alu_reg_membase(inst, X86_ADD, $1, X86_EBP, $2);
		x86_alu_reg_membase(inst, X86_ADC, %1, X86_EBP, $2+4);
	}
	[lreg, lreg] -> {
		x86_alu_reg_reg(inst, X86_ADD, $1, $2);
		x86_alu_reg_reg(inst, X86_ADC, %1, %2);
	}

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 != 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_NO, 0, 1);
			inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
			x86_patch(patch, inst);
		}
		else if(value2 != 0)
		{
			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 if(value2 != 0)
		{
			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];
		if(value1 != 0)
		{
			x86_alu_reg_imm(inst, X86_SUB, $1, value1);
			x86_alu_reg_imm(inst, X86_SBB, %1, value2);
		}
		else if(value2 != 0)
		{
			x86_alu_reg_imm(inst, X86_SUB, %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;
		if(value1 != 0)
		{
			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);
	    	}
		else if(value2 != 0)
		{
			x86_alu_reg_imm(inst, X86_SUB, %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;
		if(value1 != 0)
		{
			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);
		}
		else if(value2 != 0)
		{
			x86_alu_reg_imm(inst, X86_SUB, %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: binary
	[lreg, imm, scratch("?"), clobber("eax", "edx")] -> {
		jit_uint value1 = ((jit_uint *)($2))[0];
		jit_uint value2 = ((jit_uint *)($2))[1];
		jit_long value_imm = ((jit_long *)($2))[0];
		switch(value_imm)
		{
			case 0:
			{
				x86_clear_reg(inst, $1);
				x86_clear_reg(inst, %1);
			}
			break;
			case 1: break;
			case -1:
			{
				x86_not_reg(inst, $1);
				x86_not_reg(inst, %1);
				x86_alu_reg_imm(inst, X86_ADD, $1, 1);
				x86_alu_reg_imm(inst, X86_ADC, $1, 0);
			}
			break;
			default:
			{
				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);
				}
			}
			break;
		}
	}
	[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: binary
	[lreg, imm, scratch("?"), clobber("eax", "edx")] -> {
		unsigned char *patch;
		jit_uint value1 = ((jit_uint *)($2))[0];
		jit_uint value2 = ((jit_uint *)($2))[1];
		jit_long value_imm = ((jit_long *)($2))[0];
		switch(value_imm)
		{
			case 0:
			{
				x86_clear_reg(inst, $1);
				x86_clear_reg(inst, %1);
			}
			break;
			case 1: break;
			case -1:
			{
				unsigned char *patch1, *patch2;
				x86_alu_reg_imm(inst, X86_CMP, $1, 0);
				patch1 = inst;
				x86_branch8(inst, X86_CC_NE, 0, 0);
				x86_alu_reg_imm(inst, X86_CMP, %1, 0x80000000);
				patch2 = inst;
				x86_branch8(inst, X86_CC_NE, 0, 0);
				inst = throw_builtin(inst, func, JIT_RESULT_OVERFLOW);
				x86_patch(patch1, inst);
				x86_patch(patch2, inst);
				x86_not_reg(inst, $1);
				x86_not_reg(inst, %1);
				x86_alu_reg_imm(inst, X86_ADD, $1, 1);
				x86_alu_reg_imm(inst, X86_ADC, %1, 0);
			}
			break;
			default:
			{
				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);
				}
			}
			break;
		}
	}
	[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];
		jit_long value_imm = ((jit_long *)($2))[0];
		switch(value_imm)
		{
			case 0:
			{
				x86_clear_reg(inst, $1);
				x86_clear_reg(inst, %1);
			}
			break;
			case 1: break;
			default:
			{
	        		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];
		jit_long value_imm = ((jit_long *)($2))[0];
		switch(value_imm)
		{
			case 0:
			{
				inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO);
			}
			break;
			case 1: break;
			case -1:
			{	
				x86_not_reg(inst, $1);
				x86_not_reg(inst, %1);
				x86_alu_reg_imm(inst, X86_ADD, $1, 1);
				x86_alu_reg_imm(inst, X86_ADC, $1, 0);
			}
			break;
			default:
			{
				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);
			}
			break;
		}
	}
	[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];
		jit_long value_imm = ((jit_long *)($2))[0];
		switch(value_imm)
		{
			case 0:
			{
				inst = throw_builtin(inst, func, JIT_RESULT_DIVISION_BY_ZERO);
			}
			break;
			case 1: break;
		    	default:
			{
				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);
			}
			break;
		}
    	}
	[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);
	}
