/* Do the actual opcode */
switch (inst.code.op) {
	case t_ADDb:	case t_ADDw:	case t_ADDd:
		lf_var1d=inst.op1.d;
		lf_var2d=inst.op2.d;
		inst.op1.d=lf_resd=lf_var1d + lf_var2d;
		lflags.type=inst.code.op;
		break;
	case t_CMPb:	case t_CMPw:	case t_CMPd:
	case t_SUBb:	case t_SUBw:	case t_SUBd:
		lf_var1d=inst.op1.d;
		lf_var2d=inst.op2.d;
		inst.op1.d=lf_resd=lf_var1d - lf_var2d;
		lflags.type=inst.code.op;
		break;
	case t_ORb:		case t_ORw:		case t_ORd:
		lf_var1d=inst.op1.d;
		lf_var2d=inst.op2.d;
		inst.op1.d=lf_resd=lf_var1d | lf_var2d;
		lflags.type=inst.code.op;
		break;
	case t_XORb:	case t_XORw:	case t_XORd:
		lf_var1d=inst.op1.d;
		lf_var2d=inst.op2.d;
		inst.op1.d=lf_resd=lf_var1d ^ lf_var2d;
		lflags.type=inst.code.op;
		break;
	case t_TESTb:	case t_TESTw:	case t_TESTd:
	case t_ANDb:	case t_ANDw:	case t_ANDd:
		lf_var1d=inst.op1.d;
		lf_var2d=inst.op2.d;
		inst.op1.d=lf_resd=lf_var1d & lf_var2d;
		lflags.type=inst.code.op;
		break;
	case t_ADCb:	case t_ADCw:	case t_ADCd:
		lflags.oldcf=(get_CF()!=0);
		lf_var1d=inst.op1.d;
		lf_var2d=inst.op2.d;
		inst.op1.d=lf_resd=lf_var1d + lf_var2d + lflags.oldcf;
		lflags.type=inst.code.op;
		break;
	case t_SBBb:	case t_SBBw:	case t_SBBd:
		lflags.oldcf=(get_CF()!=0);
		lf_var1d=inst.op1.d;
		lf_var2d=inst.op2.d;
		inst.op1.d=lf_resd=lf_var1d - lf_var2d - lflags.oldcf;
		lflags.type=inst.code.op;
		break;
	case t_INCb:	case t_INCw:	case t_INCd:
		LoadCF;
		lf_var1d=inst.op1.d;
		inst.op1.d=lf_resd=inst.op1.d+1;
		lflags.type=inst.code.op;
		break;
	case t_DECb:	case t_DECw:	case t_DECd:
		LoadCF;
		lf_var1d=inst.op1.d;
		inst.op1.d=lf_resd=inst.op1.d-1;
		lflags.type=inst.code.op;
		break;
/* Using the instructions.h defines */
	case t_ROLb:
		ROLB(inst.op1.b,inst.op2.b,LoadD,SaveD);
		break;
	case t_ROLw:
		ROLW(inst.op1.w,inst.op2.b,LoadD,SaveD);
		break;
	case t_ROLd:
		ROLD(inst.op1.d,inst.op2.b,LoadD,SaveD);
		break;

	case t_RORb:
		RORB(inst.op1.b,inst.op2.b,LoadD,SaveD);
		break;
	case t_RORw:
		RORW(inst.op1.w,inst.op2.b,LoadD,SaveD);
		break;
	case t_RORd:
		RORD(inst.op1.d,inst.op2.b,LoadD,SaveD);
		break;

	case t_RCLb:
		RCLB(inst.op1.b,inst.op2.b,LoadD,SaveD);
		break;
	case t_RCLw:
		RCLW(inst.op1.w,inst.op2.b,LoadD,SaveD);
		break;
	case t_RCLd:
		RCLD(inst.op1.d,inst.op2.b,LoadD,SaveD);
		break;

	case t_RCRb:
		RCRB(inst.op1.b,inst.op2.b,LoadD,SaveD);
		break;
	case t_RCRw:
		RCRW(inst.op1.w,inst.op2.b,LoadD,SaveD);
		break;
	case t_RCRd:
		RCRD(inst.op1.d,inst.op2.b,LoadD,SaveD);
		break;

	case t_SHLb:
		SHLB(inst.op1.b,inst.op2.b,LoadD,SaveD);
		break;
	case t_SHLw:
		SHLW(inst.op1.w,inst.op2.b,LoadD,SaveD);
		break;
	case t_SHLd:
		SHLD(inst.op1.d,inst.op2.b,LoadD,SaveD);
		break;

	case t_SHRb:
		SHRB(inst.op1.b,inst.op2.b,LoadD,SaveD);
		break;
	case t_SHRw:
		SHRW(inst.op1.w,inst.op2.b,LoadD,SaveD);
		break;
	case t_SHRd:
		SHRD(inst.op1.d,inst.op2.b,LoadD,SaveD);
		break;

	case t_SARb:
		SARB(inst.op1.b,inst.op2.b,LoadD,SaveD);
		break;
	case t_SARw:
		SARW(inst.op1.w,inst.op2.b,LoadD,SaveD);
		break;
	case t_SARd:
		SARD(inst.op1.d,inst.op2.b,LoadD,SaveD);
		break;

	case O_DSHLw:
		{
			DSHLW(inst.op1.w,inst.op2.w,inst.imm.b,LoadD,SaveD);
			break;
		}
	case O_DSHRw:
		{
			DSHRW(inst.op1.w,inst.op2.w,inst.imm.b,LoadD,SaveD);
			break;
		}
	case O_DSHLd:
		{
			DSHLD(inst.op1.d,inst.op2.d,inst.imm.b,LoadD,SaveD);
			break;
		}
	case O_DSHRd:
		{
			DSHRD(inst.op1.d,inst.op2.d,inst.imm.b,LoadD,SaveD);
			break;
		}

	case t_NEGb:
		lf_var1b=inst.op1.b;
		inst.op1.b=lf_resb=0-inst.op1.b;
		lflags.type=t_NEGb;
		break;
	case t_NEGw:
		lf_var1w=inst.op1.w;
		inst.op1.w=lf_resw=0-inst.op1.w;
		lflags.type=t_NEGw;
		break;
	case t_NEGd:
		lf_var1d=inst.op1.d;
		inst.op1.d=lf_resd=0-inst.op1.d;
		lflags.type=t_NEGd;
		break;
	
	case O_NOT:
		inst.op1.d=~inst.op1.d;
		break;	
		
	/* Special instructions */
	case O_IMULRw:
		DIMULW(inst.op1.ws,inst.op1.ws,inst.op2.ws,LoadD,SaveD);
		break;
	case O_IMULRd:
		DIMULD(inst.op1.ds,inst.op1.ds,inst.op2.ds,LoadD,SaveD);
		break;
	case O_MULb:
		MULB(inst.op1.b,LoadD,0);
		goto nextopcode;
	case O_MULw:
		MULW(inst.op1.w,LoadD,0);
		goto nextopcode;
	case O_MULd:
		MULD(inst.op1.d,LoadD,0);
		goto nextopcode;
	case O_IMULb:
		IMULB(inst.op1.b,LoadD,0);
		goto nextopcode;
	case O_IMULw:
		IMULW(inst.op1.w,LoadD,0);
		goto nextopcode;
	case O_IMULd:
		IMULD(inst.op1.d,LoadD,0);
		goto nextopcode;
	case O_DIVb:
		DIVB(inst.op1.b,LoadD,0);
		goto nextopcode;
	case O_DIVw:
		DIVW(inst.op1.w,LoadD,0);
		goto nextopcode;
	case O_DIVd:
		DIVD(inst.op1.d,LoadD,0);
		goto nextopcode;
	case O_IDIVb:
		IDIVB(inst.op1.b,LoadD,0);
		goto nextopcode;
	case O_IDIVw:
		IDIVW(inst.op1.w,LoadD,0);
		goto nextopcode;
	case O_IDIVd:
		IDIVD(inst.op1.d,LoadD,0);
		goto nextopcode;
	case O_AAM:
		AAM(inst.op1.b);
		goto nextopcode;
	case O_AAD:
		AAD(inst.op1.b);
		goto nextopcode;

	case O_C_O:		inst.cond=TFLG_O;	break;
	case O_C_NO:	inst.cond=TFLG_NO;	break;
	case O_C_B:		inst.cond=TFLG_B;	break;
	case O_C_NB:	inst.cond=TFLG_NB;	break;
	case O_C_Z:		inst.cond=TFLG_Z;	break;
	case O_C_NZ:	inst.cond=TFLG_NZ;	break;
	case O_C_BE:	inst.cond=TFLG_BE;	break;
	case O_C_NBE:	inst.cond=TFLG_NBE;	break;
	case O_C_S:		inst.cond=TFLG_S;	break;
	case O_C_NS:	inst.cond=TFLG_NS;	break;
	case O_C_P:		inst.cond=TFLG_P;	break;
	case O_C_NP:	inst.cond=TFLG_NP;	break;
	case O_C_L:		inst.cond=TFLG_L;	break;
	case O_C_NL:	inst.cond=TFLG_NL;	break;
	case O_C_LE:	inst.cond=TFLG_LE;	break;
	case O_C_NLE:	inst.cond=TFLG_NLE;	break;

	case O_ALOP:
		reg_al=LoadMb(inst.rm_eaa);
		goto nextopcode;
	case O_AXOP:
		reg_ax=LoadMw(inst.rm_eaa);
		goto nextopcode;
	case O_EAXOP:
		reg_eax=LoadMd(inst.rm_eaa);
		goto nextopcode;
	case O_OPAL:
		SaveMb(inst.rm_eaa,reg_al);
		goto nextopcode;
	case O_OPAX:
		SaveMw(inst.rm_eaa,reg_ax);
		goto nextopcode;
	case O_OPEAX:
		SaveMd(inst.rm_eaa,reg_eax);
		goto nextopcode;
	case O_SEGDS:
		inst.code.extra=ds;
		break;
	case O_SEGES:
		inst.code.extra=es;
		break;
	case O_SEGFS:
		inst.code.extra=fs;
		break;
	case O_SEGGS:
		inst.code.extra=gs;
		break;
	case O_SEGSS:
		inst.code.extra=ss;
		break;
	
	case O_LOOP:
		if (inst.prefix & PREFIX_ADDR) {
			if (--reg_ecx) break;
		} else {
			if (--reg_cx) break;
		}
		goto nextopcode;
	case O_LOOPZ:
		if (inst.prefix & PREFIX_ADDR) {
			if (--reg_ecx && get_ZF()) break;
		} else {
			if (--reg_cx && get_ZF()) break;
		}
		goto nextopcode;
	case O_LOOPNZ:
		if (inst.prefix & PREFIX_ADDR) {
			if (--reg_ecx && !get_ZF()) break;
		} else {
			if (--reg_cx && !get_ZF()) break;
		}
		goto nextopcode;
	case O_JCXZ:
		if (inst.prefix & PREFIX_ADDR) {
			if (reg_ecx) goto nextopcode;
		} else {
			if (reg_cx) goto nextopcode;
		}
		break;
	case O_XCHG_AX:
		{
			Bit16u temp=reg_ax;
			reg_ax=inst.op1.w;
			inst.op1.w=temp;
			break;
		}
	case O_XCHG_EAX:
		{
			Bit32u temp=reg_eax;
			reg_eax=inst.op1.d;
			inst.op1.d=temp;
			break;
		}
	case O_CALLNw:
		SaveIP();
		Push_16(reg_ip);
		break;
	case O_CALLNd:
		SaveIP();
		Push_32(reg_eip);
		break;
	case O_CALLFw:
		LEAVECORE;
		CPU_CALL(false,inst.op2.d,inst.op1.d);
		goto restart_core;
	case O_CALLFd:
		LEAVECORE;
		CPU_CALL(true,inst.op2.d,inst.op1.d);
		goto restart_core;
	case O_JMPFw:
		LEAVECORE;
		CPU_JMP(false,inst.op2.d,inst.op1.d);
		goto restart_core;
	case O_JMPFd:
		LEAVECORE;
		CPU_JMP(true,inst.op2.d,inst.op1.d);
		goto restart_core;
	case O_INT:
		LEAVECORE;
#if C_DEBUG
		if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint()) 
			return debugCallback;
		else if (DEBUG_IntBreakpoint(inst.op1.b)) 
			return debugCallback;
#endif
		CPU_SW_Interrupt(inst.op1.b,IPPoint-inst.opcode_start);
		goto restart_core;
	case O_INb:
		reg_al=IO_ReadB(inst.op1.d);
		goto nextopcode;
	case O_INw:
		reg_ax=IO_ReadW(inst.op1.d);
		goto nextopcode;
	case O_INd:
		reg_eax=IO_ReadD(inst.op1.d);
		goto nextopcode;
	case O_OUTb:
		IO_WriteB(inst.op1.d,reg_al);
		goto nextopcode;
	case O_OUTw:
		IO_WriteW(inst.op1.d,reg_ax);
		goto nextopcode;
	case O_OUTd:
		IO_WriteD(inst.op1.d,reg_eax);
		goto nextopcode;
	case O_CBACK:
		LEAVECORE;
		return inst.op1.d;
	case O_GRP6w:
	case O_GRP6d:
		switch (inst.rm_index) {
		case 0x00:	/* SLDT */
			{
				Bitu selector;
				CPU_SLDT(selector);
				inst.op1.d=(Bit32u)selector;
			}
			break;
		case 0x01:	/* STR */
			{
				Bitu selector;
				CPU_STR(selector);
				inst.op1.d=(Bit32u)selector;
			}
			break;
		case 0x02:	/* LLDT */
			CPU_LLDT(inst.op1.d);
			goto nextopcode;		/* Else value will saved */
		case 0x03:	/* LTR */
			CPU_LTR(inst.op1.d);
			goto nextopcode;		/* Else value will saved */
		case 0x04:	/* VERR */
			FillFlags();
			CPU_VERR(inst.op1.d);
			goto nextopcode;		/* Else value will saved */
		case 0x05:	/* VERW */
			FillFlags();
			CPU_VERW(inst.op1.d);
			goto nextopcode;		/* Else value will saved */
		default:
			LOG(LOG_CPU,LOG_ERROR)("Group 6 Illegal subfunction %X",inst.rm_index);
		}
		break;
	case O_GRP7w:
	case O_GRP7d:
		switch (inst.rm_index) {
		case 0:		/* SGDT */
			{
				Bitu limit,base;
				CPU_SGDT(limit,base);
				SaveMw(inst.rm_eaa,limit);
				SaveMd(inst.rm_eaa+2,base);
				goto nextopcode;
			}
		case 1:		/* SIDT */
			{
				Bitu limit,base;
				CPU_SIDT(limit,base);
				SaveMw(inst.rm_eaa,limit);
				SaveMd(inst.rm_eaa+2,base);
				goto nextopcode;
			}
		case 2:		/* LGDT */
			CPU_LGDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF));
			goto nextopcode;
		case 3:		/* LIDT */
			CPU_LIDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF));
			goto nextopcode;
		case 4:		/* SMSW */
			{
				Bitu word;CPU_SMSW(word);
				inst.op1.d=word;
				break;
			}
		case 6:		/* LMSW */
			FillFlags();
			CPU_LMSW(inst.op1.w);
			goto nextopcode;
		default:
			LOG(LOG_CPU,LOG_ERROR)("Group 7 Illegal subfunction %X",inst.rm_index);
		}
		break;
	case O_M_CRx_Rd:
		CPU_SET_CRX(inst.rm_index,inst.op1.d);
		break;
	case O_M_Rd_CRx:
		inst.op1.d=CPU_GET_CRX(inst.rm_index);
		break;
	case O_M_DRx_Rd:
//		LOG(LOG_CPU,LOG_NORMAL)("MOV DR%d,%X",inst.rm_index,inst.op1.d);
		break;
	case O_M_Rd_DRx:
		inst.op1.d=0;
//		LOG(LOG_CPU,LOG_NORMAL)("MOV %X,DR%d",inst.op1.d,inst.rm_index);
		break;
	case O_LAR:
		{
			FillFlags();
			Bitu ar;CPU_LAR(inst.op1.d,ar);
			inst.op1.d=(Bit32u)ar;
		}
		break;
	case O_LSL:
		{
			FillFlags();
			Bitu limit;CPU_LSL(inst.op1.d,limit);
			inst.op1.d=(Bit32u)limit;
		}
		break;
	case O_ARPL:
		{
			FillFlags();
			Bitu new_sel=inst.op1.d;
			CPU_ARPL(new_sel,inst.op2.d);
			inst.op1.d=(Bit32u)new_sel;
		}
		break;
	case O_BSFw:
		{
			FillFlags();
			if (!inst.op1.w) {
				SETFLAGBIT(ZF,true);
				goto nextopcode;
			} else {
				Bitu count=0;
				while (1) {
					if (inst.op1.w & 0x1) break;
					count++;inst.op1.w>>=1;
				}
				inst.op1.d=count;
				SETFLAGBIT(ZF,false);
			}
		}
		break;
	case O_BSFd:
		{
			FillFlags();
			if (!inst.op1.d) {
				SETFLAGBIT(ZF,true);
				goto nextopcode;
			} else {
				Bitu count=0;
				while (1) {
					if (inst.op1.d & 0x1) break;
					count++;inst.op1.d>>=1;
				}
				inst.op1.d=count;
				SETFLAGBIT(ZF,false);
			}
		}
		break;
	case O_BSRw:
		{
			FillFlags();
			if (!inst.op1.w) {
				SETFLAGBIT(ZF,true);
				goto nextopcode;
			} else {
				Bitu count=15;
				while (1) {
					if (inst.op1.w & 0x8000) break;
					count--;inst.op1.w<<=1;
				}
				inst.op1.d=count;
				SETFLAGBIT(ZF,false);
			}
		}
		break;
	case O_BSRd:
		{
			FillFlags();
			if (!inst.op1.d) {
				SETFLAGBIT(ZF,true);
				goto nextopcode;
			} else {
				Bitu count=31;
				while (1) {
					if (inst.op1.d & 0x80000000) break;
					count--;inst.op1.d<<=1;
				}
				inst.op1.d=count;
				SETFLAGBIT(ZF,false);
			}
		}
		break;
	case O_BTw:
		FillFlags();
		SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15))));
		break;
	case O_BTSw:
		FillFlags();
		SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15))));
		inst.op1.d|=(1 << (inst.op2.d & 15));
		break;
	case O_BTCw:
		FillFlags();
		SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15))));
		inst.op1.d^=(1 << (inst.op2.d & 15));
		break;
	case O_BTRw:
		FillFlags();
		SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15))));
		inst.op1.d&=~(1 << (inst.op2.d & 15));
		break;
	case O_BTd:
		FillFlags();
		SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31))));
		break;
	case O_BTSd:
		FillFlags();
		SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31))));
		inst.op1.d|=(1 << (inst.op2.d & 31));
		break;
	case O_BTCd:
		FillFlags();
		SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31))));
		inst.op1.d^=(1 << (inst.op2.d & 31));
		break;
	case O_BTRd:
		FillFlags();
		SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31))));
		inst.op1.d&=~(1 << (inst.op2.d & 31));
		break;
	case O_BSWAP:
		BSWAP(inst.op1.d);
		break;
	case O_FPU:
#if C_FPU
		switch (((inst.rm>=0xc0) << 3) | inst.code.save) {
		case 0x00:	FPU_ESC0_EA(inst.rm,inst.rm_eaa);break;
		case 0x01:	FPU_ESC1_EA(inst.rm,inst.rm_eaa);break;
		case 0x02:	FPU_ESC2_EA(inst.rm,inst.rm_eaa);break;
		case 0x03:	FPU_ESC3_EA(inst.rm,inst.rm_eaa);break;
		case 0x04:	FPU_ESC4_EA(inst.rm,inst.rm_eaa);break;
		case 0x05:	FPU_ESC5_EA(inst.rm,inst.rm_eaa);break;
		case 0x06:	FPU_ESC6_EA(inst.rm,inst.rm_eaa);break;
		case 0x07:	FPU_ESC7_EA(inst.rm,inst.rm_eaa);break;

		case 0x08:	FPU_ESC0_Normal(inst.rm);break;
		case 0x09:	FPU_ESC1_Normal(inst.rm);break;
		case 0x0a:	FPU_ESC2_Normal(inst.rm);break;
		case 0x0b:	FPU_ESC3_Normal(inst.rm);break;
		case 0x0c:	FPU_ESC4_Normal(inst.rm);break;
		case 0x0d:	FPU_ESC5_Normal(inst.rm);break;
		case 0x0e:	FPU_ESC6_Normal(inst.rm);break;
		case 0x0f:	FPU_ESC7_Normal(inst.rm);break;
		}
		goto nextopcode;
#else
		LOG(LOG_CPU,LOG_ERROR)("Unhandled FPU ESCAPE %d",inst.code.save);
		goto nextopcode;
#endif
	case O_BOUNDw:
		{
			Bit16s bound_min, bound_max;
			bound_min=LoadMw(inst.rm_eaa);
			bound_max=LoadMw(inst.rm_eaa+2);
			if ( (((Bit16s)inst.op1.w) < bound_min) || (((Bit16s)inst.op1.w) > bound_max) ) {
				EXCEPTION(5);
			}
		}
		break;
	case 0:
		break;
	default:
		LOG(LOG_CPU,LOG_ERROR)("OP:Unhandled code %d entry %X",inst.code.op,inst.entry);
		
}
