// EFI definitions
// Copyright (C) Florian Negele

// This file is part of the Eigen Compiler Suite.

// The ECS is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// The ECS is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of the GNU General Public License version 3,
// the copyright holder grants you additional permissions to use
// this file as described in the ECS Runtime Support Exception.

// You should have received a copy of the GNU General Public License
// and a copy of the ECS Runtime Support Exception along with
// the ECS.  If not, see <https://www.gnu.org/licenses/>.

#ifndef ECS_DEF_EFI_HEADER_INCLUDED
#define ECS_DEF_EFI_HEADER_INCLUDED

#include "assembly"

#if defined __amd32__

	#define FUNCTION(pointer, name, offset, index, parameters) asm ( \
		CODE (name) SHARED INSTR (pop ebx) INSTR (mov eax, [@pointer]) INSTR (call dword [eax + index * 4 + offset]) \
		IF (parameters > 0) INSTR (sub esp, parameters * 4) ENDIF \
		INSTR (jmp ebx) \
		);

#elif defined __amd64__

	#define FUNCTION(pointer, name, offset, index, parameters) asm ( \
		CODE (name) SHARED INSTR (pop rbx) INSTR (mov rax, [@pointer]) INSTR (mov rdi, rsp) INSTR (and rsp, ~1111b) \
		IF (parameters > 4 & parameters & 1) INSTR (sub rsp, 8) ENDIF \
		REPEAT (parameters) IF (__ >= 4) INSTR (push qword [rdi + (parameters - __ - 1) * 8 + 32]) ENDIF ENDREP \
		IF (parameters > 3) INSTR (mov r9, [rdi + 24]) ENDIF \
		IF (parameters > 2) INSTR (mov r8, [rdi + 16]) ENDIF \
		IF (parameters > 1) INSTR (mov rdx, [rdi + 8]) ENDIF \
		IF (parameters > 0) INSTR (mov rcx, [rdi]) ENDIF \
		INSTR (sub rsp, 32) INSTR (call qword [rax + index * 8 + offset]) INSTR (mov rsp, rdi) INSTR (jmp rbx) \
		);

#else

	#error platform not supported

#endif

#endif // ECS_DEF_EFI_HEADER_INCLUDED
