#define RETF_a16(stack_offset)                                  \
		if ((msw&1) && !(cpu_state.eflags&VM_FLAG))     \
		{                                               \
			pmoderetf(0, stack_offset);             \
			return 1;                               \
		}                                               \
		if (stack32)                                    \
		{                                               \
			cpu_state.pc = readmemw(ss, ESP);       \
			loadcs(readmemw(ss, ESP + 2));          \
		}                                               \
		else                                            \
		{                                               \
			cpu_state.pc = readmemw(ss, SP);        \
			loadcs(readmemw(ss, SP + 2));           \
		}                                               \
		if (cpu_state.abrt) return 1;                             \
		if (stack32) ESP += 4 + stack_offset;           \
		else         SP  += 4 + stack_offset;           \
		cycles -= timing_retf_rm;

#define RETF_a32(stack_offset)                                  \
		if ((msw&1) && !(cpu_state.eflags&VM_FLAG))     \
		{                                               \
			pmoderetf(1, stack_offset);             \
			return 1;                               \
		}                                               \
		if (stack32)                                    \
		{                                               \
			cpu_state.pc = readmeml(ss, ESP);       \
			loadcs(readmeml(ss, ESP + 4) & 0xffff); \
		}                                               \
		else                                            \
		{                                               \
			cpu_state.pc = readmeml(ss, SP);        \
			loadcs(readmeml(ss, SP + 4) & 0xffff);  \
		}                                               \
		if (cpu_state.abrt) return 1;                             \
		if (stack32) ESP += 8 + stack_offset;           \
		else         SP  += 8 + stack_offset;           \
		cycles -= timing_retf_rm;

static int opRETF_a16(uint32_t fetchdat)
{
	int cycles_old = cycles; UNUSED(cycles_old);

	CPU_BLOCK_END();
	RETF_a16(0);

	PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0);
	PREFETCH_FLUSH();
	return 0;
}
static int opRETF_a32(uint32_t fetchdat)
{
	int cycles_old = cycles; UNUSED(cycles_old);

	CPU_BLOCK_END();
	RETF_a32(0);

	PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,2,0,0, 1);
	PREFETCH_FLUSH();
	return 0;
}

static int opRETF_a16_imm(uint32_t fetchdat)
{
	uint16_t offset = getwordf();
	int cycles_old = cycles; UNUSED(cycles_old);

	CPU_BLOCK_END();
	RETF_a16(offset);

	PREFETCH_RUN(cycles_old-cycles, 3, -1, 2,0,0,0, 0);
	PREFETCH_FLUSH();
	return 0;
}
static int opRETF_a32_imm(uint32_t fetchdat)
{
	uint16_t offset = getwordf();
	int cycles_old = cycles; UNUSED(cycles_old);

	CPU_BLOCK_END();
	RETF_a32(offset);

	PREFETCH_RUN(cycles_old-cycles, 3, -1, 0,2,0,0, 1);
	PREFETCH_FLUSH();
	return 0;
}

static int opIRET_286(uint32_t fetchdat)
{
	int cycles_old = cycles; UNUSED(cycles_old);

	if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
	{
		x86gpf(NULL,0);
		return 1;
	}
	if (msw&1)
	{
		optype = IRET;
		pmodeiret(0);
		optype = 0;
	}
	else
	{
		uint16_t new_cs;
		if (stack32)
		{
			cpu_state.pc = readmemw(ss, ESP);
			new_cs = readmemw(ss, ESP + 2);
			cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2;
			ESP += 6;
		}
		else
		{
			cpu_state.pc = readmemw(ss, SP);
			new_cs = readmemw(ss, ((SP + 2) & 0xffff));
			cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
			SP += 6;
		}
		loadcs(new_cs);
		cycles -= timing_iret_rm;
	}
	flags_extract();
	nmi_enable = 1;
	CPU_BLOCK_END();

	PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0);
	PREFETCH_FLUSH();
	return cpu_state.abrt;
}

static int opIRET(uint32_t fetchdat)
{
	int cycles_old = cycles; UNUSED(cycles_old);

	if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
	{
		if (cr4 & CR4_VME)
		{
			uint16_t new_pc, new_cs, new_flags;

			new_pc = readmemw(ss, SP);
			new_cs = readmemw(ss, ((SP + 2) & 0xffff));
			new_flags = readmemw(ss, ((SP + 4) & 0xffff));
			if (cpu_state.abrt)
				return 1;

			if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG)))
			{
				x86gpf(NULL, 0);
				return 1;
			}
			SP += 6;
			if (new_flags & I_FLAG)
				cpu_state.eflags |= VIF_FLAG;
			else
				cpu_state.eflags &= ~VIF_FLAG;
			cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2;
			loadcs(new_cs);
			cpu_state.pc = new_pc;

			cycles -= timing_iret_rm;
		}
		else
		{
			x86gpf_expected(NULL,0);
			return 1;
		}
	}
	else
	{
		if (msw&1)
		{
			optype = IRET;
			pmodeiret(0);
			optype = 0;
		}
		else
		{
			uint16_t new_cs;
			if (stack32)
			{
				cpu_state.pc = readmemw(ss, ESP);
				new_cs = readmemw(ss, ESP + 2);
				cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2;
				ESP += 6;
			}
			else
			{
				cpu_state.pc = readmemw(ss, SP);
				new_cs = readmemw(ss, ((SP + 2) & 0xffff));
				cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2;
				SP += 6;
			}
			loadcs(new_cs);
			cycles -= timing_iret_rm;
		}
	}
	flags_extract();
	nmi_enable = 1;
	CPU_BLOCK_END();

	PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0);
	PREFETCH_FLUSH();
	return cpu_state.abrt;
}

static int opIRETD(uint32_t fetchdat)
{
	int cycles_old = cycles; UNUSED(cycles_old);

	if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
	{
		x86gpf_expected(NULL,0);
		return 1;
	}
	if (msw & 1)
	{
		optype = IRET;
		pmodeiret(1);
		optype = 0;
	}
	else
	{
		uint16_t new_cs;
		if (stack32)
		{
			cpu_state.pc = readmeml(ss, ESP);
			new_cs = readmemw(ss, ESP + 4);
			cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2;
			cpu_state.eflags = readmemw(ss, ESP + 10);
			ESP += 12;
		}
		else
		{
			cpu_state.pc = readmeml(ss, SP);
			new_cs = readmemw(ss, ((SP + 4) & 0xffff));
			cpu_state.flags = (readmemw(ss,(SP + 8) & 0xffff) & 0xffd5) | 2;
			cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff);
			SP += 12;
		}
		loadcs(new_cs);
		cycles -= timing_iret_rm;
	}
	flags_extract();
	nmi_enable = 1;
	CPU_BLOCK_END();

	PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,2,0,0, 1);
	PREFETCH_FLUSH();
	return cpu_state.abrt;
}

