#include "Flags.h"



PNATIVE_CODE_LINK FlgEmitPushfqInst()
{
	UCHAR RawData[] = { 0x9C };
	PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, 1);
	XedDecode(&Link->XedInstruction, Link->RawData, 1);
	return Link;
}

PNATIVE_CODE_LINK FlgEmitPopfqInst()
{
	UCHAR RawData[] = { 0x9D };
	PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, 1);
	XedDecode(&Link->XedInstruction, Link->RawData, 1);
	return Link;
}


BOOL FlgAreFlagsClobbered(PNATIVE_CODE_LINK Inst, PNATIVE_CODE_LINK Stop)
{
	XED_FLAG_SET Ledger;
	CONST XED_SIMPLE_FLAG* SimpleFlags = XedDecodedInstGetRflagsInfo(&Inst->XedInstruction);
	CONST XED_FLAG_SET* _Ledger1 = XedSimpleFlagGetWrittenFlagSet(SimpleFlags);
	CONST XED_FLAG_SET* _Ledger2 = XedSimpleFlagGetUndefinedFlagSet(SimpleFlags);
	Ledger.flat = (_Ledger1->flat | _Ledger2->flat);

	for (PNATIVE_CODE_LINK T = Inst->Next; T && T != Stop; T = T->Next)
	{
		if (T->Flags & CODE_FLAG_IS_LABEL)
			continue;

		CONST XED_SIMPLE_FLAG* InstFlags = XedDecodedInstGetRflagsInfo(&T->XedInstruction);
		CONST XED_FLAG_SET* FlagsRead = XedSimpleFlagGetReadFlagSet(InstFlags);

		if (FlagsRead->flat & Ledger.flat)
			return FALSE;

		CONST XED_FLAG_SET* FlagsWritten = XedSimpleFlagGetWrittenFlagSet(InstFlags);
		CONST XED_FLAG_SET* FlagsUndefined = XedSimpleFlagGetUndefinedFlagSet(InstFlags);

		Ledger.flat &= ~(Ledger.flat & (FlagsWritten->flat | FlagsUndefined->flat));
	}
	return TRUE;
}