#if defined(__i386__) || defined(__x86_64__)
#ifndef _I386_PLATFUNC_H
#define _I386_PLATFUNC_H
#ifndef __ASSEMBLER__
#include <stdint.h>
#endif
#define PLATFUNC_DESCRIPTOR_NAME(name, variant) \
PLATFUNC_VARIANT_NAME(platfunc_ ## name, variant)
#ifdef __ASSEMBLER__
#define MP_SPIN_TRIES 1000
#define PLATFUNC_VARIANT_NAME(name, variant) _ ## name ## $VARIANT$ ## variant
#if defined (__i386__)
#define PLATFUNC_DESCRIPTOR_FIELD_POINTER .long
#define PLATFUNC_DESCRIPTOR_REFERENCE(name, variant) \
.long PLATFUNC_DESCRIPTOR_NAME(name, variant)
#elif defined (__x86_64__)
#define PLATFUNC_DESCRIPTOR_FIELD_POINTER .quad
#define PLATFUNC_DESCRIPTOR_REFERENCE(name, variant) \
.quad PLATFUNC_DESCRIPTOR_NAME(name, variant)
#else
#error unsupported architecture
#endif
#ifdef VARIANT_DYLD
#define PLATFUNC_FUNCTION_START_GENERIC(name, variant, codetype, alignment) \
PLATFUNC_FUNCTION_START(name, variant, codetype, alignment) \
.globl _ ## name ;\
_ ## name ## :
#define PLATFUNC_DESCRIPTOR(name, variant, must, cant)
#else
#define PLATFUNC_FUNCTION_START_GENERIC PLATFUNC_FUNCTION_START
#define PLATFUNC_DESCRIPTOR(name, variant, must, cant) \
.const_data ;\
.private_extern PLATFUNC_DESCRIPTOR_NAME(name, variant) ;\
PLATFUNC_DESCRIPTOR_NAME(name, variant) ## : ;\
PLATFUNC_DESCRIPTOR_FIELD_POINTER PLATFUNC_VARIANT_NAME(name, variant) ;\
.long must ;\
.long cant ;\
.text
#endif
#define PLATFUNC_FUNCTION_START(name, variant, codetype, alignment) \
.text ;\
.align alignment, 0x90 ;\
.private_extern PLATFUNC_VARIANT_NAME(name, variant) ;\
PLATFUNC_VARIANT_NAME(name, variant) ## :
#else
#define PLATFUNC_VARIANT_NAME(name, variant) name ## $VARIANT$ ## variant
#define PLATFUNC_DESCRIPTOR_PROTOTYPE(name, variant) extern const platfunc_descriptor PLATFUNC_DESCRIPTOR_NAME(name, variant);
#define PLATFUNC_DESCRIPTOR_REFERENCE(name, variant) &PLATFUNC_DESCRIPTOR_NAME(name, variant)
#define PLATFUNC_DESCRIPTOR(name, variant, must, cant) \
extern void PLATFUNC_VARIANT_NAME(name, variant) (void); \
const platfunc_descriptor PLATFUNC_DESCRIPTOR_NAME(name, variant) = { \
.address = PLATFUNC_VARIANT_NAME(name, variant), \
.musthave = must, \
.canthave = cant \
}
typedef struct platfunc_descriptor {
void *address; uint32_t musthave; uint32_t canthave; } platfunc_descriptor;
void *find_platform_function(const platfunc_descriptor *descriptors[]);
#endif
#endif
#endif