#include "BlitzPointer.h"

// Hybrid specific defines.
#define CALLFUNCTION_DECL_BEGIN_64(NAME)				DLL_EXPORT int64_t BlitzPointer_CallFunction##NAME(intptr_t lpFunctionPointer
#define CALLFUNCTION_IMPL_PARAMETER_64(INDEX, NAME)		__asm MOV RAX, [NAME] __asm mov [esp + INDEX * 4], RAX
#define CALLFUNCTION_IMPL_CALL_64()						__asm CALL QWORD ptr[lpFunctionPointer]
#define CALLFUNCTION_IMPL_RESULT_64()					int64_t result; __asm MOV [result], RAX

/*
// No Parameters
CALLFUNCTION_DECL_BEGIN_64(Q0)
CALLFUNCTION_DECL_END() CALLFUNCTION_IMPL_BEGIN()
	CALLFUNCTION_IMPL_SAFEGUARD()
	CALLFUNCTION_IMPL_CALL_64()
	CALLFUNCTION_IMPL_RESULT_64()
	CALLFUNCTION_IMPL_RETURN()
CALLFUNCTION_IMPL_END()

// One Parameter
CALLFUNCTION_DECL_BEGIN_64(Q1D)
	CALLFUNCTION_DECL_PARAMETER(int32_t, p1)
CALLFUNCTION_DECL_END() CALLFUNCTION_IMPL_BEGIN()
	CALLFUNCTION_IMPL_SAFEGUARD()
	CALLFUNCTION_IMPL_PREPARE(1)
	CALLFUNCTION_IMPL_PARAMETER(0, p1)
	CALLFUNCTION_IMPL_CALL_64()
	CALLFUNCTION_IMPL_RESULT_64()
	CALLFUNCTION_IMPL_RETURN()
CALLFUNCTION_IMPL_END()

CALLFUNCTION_DECL_BEGIN_64(Q1Q)
	CALLFUNCTION_DECL_PARAMETER(int64_t, p1)
CALLFUNCTION_DECL_END() CALLFUNCTION_IMPL_BEGIN()
	CALLFUNCTION_IMPL_SAFEGUARD()
	CALLFUNCTION_IMPL_PREPARE(1)
	CALLFUNCTION_IMPL_PARAMETER_64(0, p1)
	CALLFUNCTION_IMPL_CALL_64()
	CALLFUNCTION_IMPL_RESULT_64()
	CALLFUNCTION_IMPL_RETURN()
CALLFUNCTION_IMPL_END()

// Two Parameters
CALLFUNCTION_DECL_BEGIN(D2DQ)
CALLFUNCTION_DECL_PARAMETER(int32_t, p1)
CALLFUNCTION_DECL_PARAMETER(int64_t, p2)
CALLFUNCTION_DECL_END() CALLFUNCTION_IMPL_BEGIN()
CALLFUNCTION_IMPL_SAFEGUARD()
CALLFUNCTION_IMPL_PREPARE(2)
CALLFUNCTION_IMPL_PARAMETER_64(1, p2)
CALLFUNCTION_IMPL_PARAMETER(0, p1)
CALLFUNCTION_IMPL_CALL()
CALLFUNCTION_IMPL_RESULT()
CALLFUNCTION_IMPL_RETURN()
CALLFUNCTION_IMPL_END()

CALLFUNCTION_DECL_BEGIN(D2QD)
CALLFUNCTION_DECL_PARAMETER(int64_t, p1)
CALLFUNCTION_DECL_PARAMETER(int32_t, p2)
CALLFUNCTION_DECL_END() CALLFUNCTION_IMPL_BEGIN()
CALLFUNCTION_IMPL_SAFEGUARD()
CALLFUNCTION_IMPL_PREPARE(2)
CALLFUNCTION_IMPL_PARAMETER(1, p2)
CALLFUNCTION_IMPL_PARAMETER_64(0, p1)
CALLFUNCTION_IMPL_CALL()
CALLFUNCTION_IMPL_RESULT()
CALLFUNCTION_IMPL_RETURN()
CALLFUNCTION_IMPL_END()

CALLFUNCTION_DECL_BEGIN(D2QQ)
CALLFUNCTION_DECL_PARAMETER(int64_t, p1)
CALLFUNCTION_DECL_PARAMETER(int64_t, p2)
CALLFUNCTION_DECL_END() CALLFUNCTION_IMPL_BEGIN()
CALLFUNCTION_IMPL_SAFEGUARD()
CALLFUNCTION_IMPL_PREPARE(2)
CALLFUNCTION_IMPL_PARAMETER_64(1, p2)
CALLFUNCTION_IMPL_PARAMETER_64(0, p1)
CALLFUNCTION_IMPL_CALL()
CALLFUNCTION_IMPL_RESULT()
CALLFUNCTION_IMPL_RETURN()
CALLFUNCTION_IMPL_END()

CALLFUNCTION_DECL_BEGIN_64(Q2DD)
CALLFUNCTION_DECL_PARAMETER(int32_t, p1)
CALLFUNCTION_DECL_PARAMETER(int64_t, p2)
CALLFUNCTION_DECL_END() CALLFUNCTION_IMPL_BEGIN()
CALLFUNCTION_IMPL_SAFEGUARD()
CALLFUNCTION_IMPL_PREPARE(2)
CALLFUNCTION_IMPL_PARAMETER_64(1, p2)
CALLFUNCTION_IMPL_PARAMETER(0, p1)
CALLFUNCTION_IMPL_CALL()
CALLFUNCTION_IMPL_RESULT_64()
CALLFUNCTION_IMPL_RETURN()
CALLFUNCTION_IMPL_END()

CALLFUNCTION_DECL_BEGIN_64(Q2DQ)
CALLFUNCTION_DECL_PARAMETER(int32_t, p1)
CALLFUNCTION_DECL_PARAMETER(int64_t, p2)
CALLFUNCTION_DECL_END() CALLFUNCTION_IMPL_BEGIN()
CALLFUNCTION_IMPL_SAFEGUARD()
CALLFUNCTION_IMPL_PREPARE(2)
CALLFUNCTION_IMPL_PARAMETER_64(1, p2)
CALLFUNCTION_IMPL_PARAMETER(0, p1)
CALLFUNCTION_IMPL_CALL()
CALLFUNCTION_IMPL_RESULT_64()
CALLFUNCTION_IMPL_RETURN()
CALLFUNCTION_IMPL_END()

CALLFUNCTION_DECL_BEGIN_64(Q2QD)
CALLFUNCTION_DECL_PARAMETER(int64_t, p1)
CALLFUNCTION_DECL_PARAMETER(int32_t, p2)
CALLFUNCTION_DECL_END() CALLFUNCTION_IMPL_BEGIN()
CALLFUNCTION_IMPL_SAFEGUARD()
CALLFUNCTION_IMPL_PREPARE(2)
CALLFUNCTION_IMPL_PARAMETER(1, p2)
CALLFUNCTION_IMPL_PARAMETER_64(0, p1)
CALLFUNCTION_IMPL_CALL()
CALLFUNCTION_IMPL_RESULT_64()
CALLFUNCTION_IMPL_RETURN()
CALLFUNCTION_IMPL_END()

CALLFUNCTION_DECL_BEGIN_64(Q2QQ)
CALLFUNCTION_DECL_PARAMETER(int64_t, p1)
CALLFUNCTION_DECL_PARAMETER(int64_t, p2)
CALLFUNCTION_DECL_END() CALLFUNCTION_IMPL_BEGIN()
CALLFUNCTION_IMPL_SAFEGUARD()
CALLFUNCTION_IMPL_PREPARE(2)
CALLFUNCTION_IMPL_PARAMETER_64(1, p2)
CALLFUNCTION_IMPL_PARAMETER_64(0, p1)
CALLFUNCTION_IMPL_CALL()
CALLFUNCTION_IMPL_RESULT_64()
CALLFUNCTION_IMPL_RETURN()
CALLFUNCTION_IMPL_END()

*/