/* This file was auto-generated by "gen-apply" - DO NOT EDIT */

#ifndef _JIT_APPLY_RULES_H
#define _JIT_APPLY_RULES_H

#define JIT_APPLY_NUM_WORD_REGS 8
#define JIT_APPLY_NUM_FLOAT_REGS 0
#define JIT_APPLY_NUM_DOUBLE_REGS 8
#define JIT_APPLY_NUM_NFLOAT_REGS 8
#define JIT_APPLY_PASS_STACK_FLOAT_AS_DOUBLE 0
#define JIT_APPLY_PASS_STACK_FLOAT_AS_NFLOAT 1
#define JIT_APPLY_PASS_STACK_DOUBLE_AS_NFLOAT 1
#define JIT_APPLY_PASS_STACK_NFLOAT_AS_DOUBLE 0
#define JIT_APPLY_PASS_REG_FLOAT_AS_DOUBLE 0
#define JIT_APPLY_PASS_REG_FLOAT_AS_NFLOAT 0
#define JIT_APPLY_PASS_REG_DOUBLE_AS_NFLOAT 0
#define JIT_APPLY_PASS_REG_NFLOAT_AS_DOUBLE 0
#define JIT_APPLY_RETURN_FLOAT_AS_DOUBLE 0
#define JIT_APPLY_RETURN_FLOAT_AS_NFLOAT 0
#define JIT_APPLY_RETURN_DOUBLE_AS_NFLOAT 0
#define JIT_APPLY_RETURN_NFLOAT_AS_DOUBLE 0
#define JIT_APPLY_FLOATS_IN_WORD_REGS 0
#define JIT_APPLY_DOUBLES_IN_WORD_REGS 0
#define JIT_APPLY_NFLOATS_IN_WORD_REGS 0
#define JIT_APPLY_RETURN_FLOATS_AFTER 64
#define JIT_APPLY_RETURN_DOUBLES_AFTER 24
#define JIT_APPLY_RETURN_NFLOATS_AFTER 16
#define JIT_APPLY_VARARGS_ON_STACK 0
#define JIT_APPLY_STRUCT_RETURN_SPECIAL_REG 1
#define JIT_APPLY_STRUCT_REG_OVERLAPS_WORD_REG 0
#define JIT_APPLY_ALIGN_LONG_REGS 0
#define JIT_APPLY_ALIGN_LONG_STACK 0
#define JIT_APPLY_CAN_SPLIT_LONG 0
#define JIT_APPLY_STRUCT_RETURN_IN_REG_INIT \
	{0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
#define JIT_APPLY_MAX_STRUCT_IN_REG 16
#define JIT_APPLY_MAX_APPLY_SIZE 80
#define JIT_APPLY_X86_FASTCALL 0
#define JIT_APPLY_PARENT_FRAME_OFFSET 0
#define JIT_APPLY_RETURN_ADDRESS_OFFSET 8
#define JIT_APPLY_BROKEN_FRAME_BUILTINS 0
#define JIT_APPLY_X86_POP_STRUCT_RETURN 0
#define JIT_APPLY_PAD_FLOAT_REGS 0

typedef union
{
	jit_nint int_value;
	jit_nuint uint_value;
	jit_long long_value;
	jit_ulong ulong_value;
	struct { jit_ubyte pad[64]; float f_value; } float_value;
	struct { jit_ubyte pad[24]; double f_value; } double_value;
	struct { jit_ubyte pad[16]; jit_nfloat f_value; } nfloat_value;
	jit_ubyte small_struct_value[16];

} jit_apply_return;

#define jit_apply_return_get_sbyte(result)	\
	((jit_sbyte)((result)->int_value))
#define jit_apply_return_get_ubyte(result)	\
	((jit_ubyte)((result)->int_value))
#define jit_apply_return_get_short(result)	\
	((jit_short)((result)->int_value))
#define jit_apply_return_get_ushort(result)	\
	((jit_ushort)((result)->int_value))
#define jit_apply_return_get_int(result)	\
	((jit_int)((result)->int_value))
#define jit_apply_return_get_uint(result)	\
	((jit_uint)((result)->uint_value))
#define jit_apply_return_get_nint(result)	\
	((jit_nint)((result)->int_value))
#define jit_apply_return_get_nuint(result)	\
	((jit_nuint)((result)->uint_value))
#define jit_apply_return_get_long(result)	\
	((jit_long)((result)->long_value))
#define jit_apply_return_get_ulong(result)	\
	((jit_ulong)((result)->ulong_value))
#define jit_apply_return_get_float32(result)	\
	((jit_float32)((result)->float_value.f_value))
#define jit_apply_return_get_float64(result)	\
	((jit_float64)((result)->double_value.f_value))
#define jit_apply_return_get_nfloat(result)	\
	((jit_nfloat)((result)->nfloat_value.f_value))

#define jit_apply_return_set_sbyte(result,value)	\
	(((result)->int_value) = ((jit_nint)(value)))
#define jit_apply_return_set_ubyte(result,value)	\
	(((result)->int_value) = ((jit_nint)(value)))
#define jit_apply_return_set_short(result,value)	\
	(((result)->int_value) = ((jit_nint)(value)))
#define jit_apply_return_set_ushort(result,value)	\
	(((result)->int_value) = ((jit_nint)(value)))
#define jit_apply_return_set_int(result,value)	\
	(((result)->int_value) = ((jit_nint)(value)))
#define jit_apply_return_set_uint(result,value)	\
	(((result)->uint_value) = ((jit_nuint)(value)))
#define jit_apply_return_set_nint(result,value)	\
	(((result)->int_value) = ((jit_nint)(value)))
#define jit_apply_return_set_nuint(result,value)	\
	(((result)->uint_value) = ((jit_nuint)(value)))
#define jit_apply_return_set_long(result,value)	\
	(((result)->long_value) = ((jit_long)(value)))
#define jit_apply_return_set_ulong(result,value)	\
	(((result)->ulong_value) = ((jit_ulong)(value)))
#define jit_apply_return_set_float32(result,value)	\
	(((result)->float_value.f_value) = ((float)(value)))
#define jit_apply_return_set_float64(result,value)	\
	(((result)->double_value.f_value) = ((double)(value)))
#define jit_apply_return_set_nfloat(result,value)	\
	(((result)->nfloat_value.f_value) = ((jit_nfloat)(value)))

typedef jit_float64 jit_reg_double;

typedef jit_nfloat jit_reg_nfloat;

typedef union
{
	jit_reg_double double_value;
	jit_reg_nfloat nfloat_value;
} jit_reg_float_struct;

typedef struct
{
	unsigned char *stack_args;
	void *struct_ptr;
	jit_nint word_regs[8];
	jit_reg_float_struct float_regs[0];

} jit_apply_struct;

typedef struct
{
	jit_apply_struct *apply_args;
	unsigned int stack_used;
	unsigned int word_used;
	void *struct_return;

} jit_apply_builder;

#include "jit-apply-func.h"

void
_jit_builtin_apply_add_struct(jit_apply_builder *builder, void *value, jit_type_t struct_type);

void
_jit_builtin_apply_get_struct(jit_apply_builder *builder, void *value, jit_type_t struct_type);

void
_jit_builtin_apply_get_struct_return(jit_apply_builder *builder, void *return_value, jit_apply_return *apply_return, jit_type_t struct_type);

#define jit_apply_builder_init(builder,type)	\
	do { \
		(builder)->apply_args = (jit_apply_struct *)alloca(sizeof(jit_apply_struct)); \
		jit_memset((builder)->apply_args, 0, 80); \
		(builder)->apply_args->stack_args = (unsigned char *)alloca(jit_type_get_max_arg_size((type))); \
		(builder)->stack_used = 0; \
		(builder)->word_used = 0; \
		(builder)->struct_return = 0; \
	} while (0)

#define jit_apply_parser_init(builder,type,args)	\
	do { \
		(builder)->apply_args = (jit_apply_struct *)(args); \
		(builder)->stack_used = 0; \
		(builder)->word_used = 0; \
		(builder)->struct_return = 0; \
	} while (0)

#define jit_apply_builder_add_word(builder,value) \
	do { \
		if((builder)->word_used < 8) \
		{ \
			(builder)->apply_args->word_regs[(builder)->word_used] = (jit_nint)(value); \
			++((builder)->word_used); \
		} \
		else \
		{ \
			*((jit_nint*)((builder)->apply_args->stack_args + (builder)->stack_used)) = (jit_nint)(value); \
			(builder)->stack_used += sizeof(jit_nint); \
		} \
	} while (0)

#define jit_apply_parser_get_word(builder,type,value) \
	do { \
		if((builder)->word_used < 8) \
		{ \
			(value) = (type)((builder)->apply_args->word_regs[(builder)->word_used]); \
			++((builder)->word_used); \
		} \
		else \
		{ \
			(value) = (type)(*((jit_nint*)((builder)->apply_args->stack_args + (builder)->stack_used))); \
			(builder)->stack_used += sizeof(jit_nint); \
		} \
	} while (0)

#define jit_apply_builder_align_regs(builder,num_words,align) \
	do { \
		if((align) > sizeof(jit_nint) && (num_words) > 1) \
		{ \
			if((8 - (builder)->word_used) < (num_words)) \
			{ \
				(builder)->word_used = 8; \
			} \
		} \
	} while (0)

#define jit_apply_builder_align_stack(builder,num_words,align) \
	do { ; } while (0)

#define jit_apply_builder_add_large_inner(builder,ptr,size,align) \
	do { \
		unsigned int __num_words = ((size) + sizeof(jit_nint) - 1) / sizeof(jit_nint); \
		jit_apply_builder_align_regs((builder), __num_words, (align)); \
		if((8 - (builder)->word_used) >= __num_words) \
		{ \
			jit_memcpy((builder)->apply_args->word_regs + (builder)->word_used, (ptr), (size)); \
			(builder)->word_used += __num_words; \
		} \
		else if((builder)->word_used < 8) \
		{ \
			unsigned int __split = (8 - (builder)->word_used); \
			jit_memcpy((builder)->apply_args->word_regs + (builder)->word_used, (ptr), __split * sizeof(jit_nint)); \
			jit_memcpy((builder)->apply_args->stack_args, ((jit_nint *)(ptr)) + __split, (size) - __split * sizeof(jit_nint)); \
			(builder)->word_used = 8; \
			(builder)->stack_used = __num_words - __split; \
		} \
		else \
		{ \
			jit_apply_builder_align_stack((builder), __num_words, (align)); \
			jit_memcpy((builder)->apply_args->stack_args + (builder)->stack_used, (ptr), (size)); \
			(builder)->stack_used += __num_words * sizeof(jit_nint); \
			(builder)->word_used = 8; \
		} \
	} while (0)

#define jit_apply_builder_add_large(builder,type,value) \
	do { \
		type __temp = (type)(value); \
		jit_apply_builder_add_large_inner((builder), &__temp, sizeof(__temp), sizeof(jit_nint)); \
	} while (0)

#define jit_apply_parser_get_large(builder,type,finaltype,value) \
	do { \
		type __temp; \
		unsigned int __num_words = (sizeof(__temp) + sizeof(jit_nint) - 1) / sizeof(jit_nint); \
		jit_apply_builder_align_regs((builder), __num_words, sizeof(type)); \
		if((8 - (builder)->word_used) >= __num_words) \
		{ \
			jit_memcpy(&__temp, (builder)->apply_args->word_regs + (builder)->word_used, sizeof(__temp)); \
			(builder)->word_used += __num_words; \
		} \
		else if((builder)->word_used < 8) \
		{ \
			unsigned int __split = (8 - (builder)->word_used); \
			jit_memcpy(&__temp, (builder)->apply_args->word_regs + (builder)->word_used, __split * sizeof(jit_nint)); \
			jit_memcpy(((jit_nint *)&__temp) + __split, (builder)->apply_args->stack_args, (__num_words - __split) * sizeof(jit_nint)); \
			(builder)->word_used = 8; \
			(builder)->stack_used = __num_words - __split; \
		} \
		else \
		{ \
			jit_apply_builder_align_stack((builder), __num_words, sizeof(type)); \
			jit_memcpy(&__temp, (builder)->apply_args->stack_args + (builder)->stack_used, sizeof(__temp)); \
			(builder)->stack_used += __num_words * sizeof(jit_nint); \
			(builder)->word_used = 8; \
		} \
		(value) = (finaltype)(__temp); \
	} while (0)

#define jit_apply_builder_add_large_stack(builder,type,value) \
	do { \
		type __temp = (type)(value); \
		unsigned int __num_words = (sizeof(__temp) + sizeof(jit_nint) - 1) / sizeof(jit_nint); \
		jit_apply_builder_align_stack((builder), __num_words, sizeof(type)); \
		jit_memcpy((builder)->apply_args->stack_args + (builder)->stack_used, &__temp, sizeof(__temp)); \
		(builder)->stack_used += __num_words * sizeof(jit_nint); \
	} while (0)

#define jit_apply_parser_get_large_stack(builder,type,finaltype,value) \
	do { \
		type __temp; \
		unsigned int __num_words = (sizeof(__temp) + sizeof(jit_nint) - 1) / sizeof(jit_nint); \
		jit_apply_builder_align_stack((builder), __num_words, sizeof(type)); \
		jit_memcpy(&__temp, (builder)->apply_args->stack_args + (builder)->stack_used, sizeof(__temp)); \
		(builder)->stack_used += __num_words * sizeof(jit_nint); \
		(value) = (finaltype)(__temp); \
	} while (0)

#define jit_apply_builder_add_struct_return(builder,size,return_buf) \
	do { \
		unsigned int __struct_size = (unsigned int)(size); \
		if(__struct_size >= 1 && __struct_size <= 64 && \
		   (_jit_apply_return_in_reg[(__struct_size - 1) / 8] \
		       & (1 << ((__struct_size - 1) % 8))) != 0) \
		{ \
			(builder)->struct_return = 0; \
		} \
		else \
		{ \
			if((return_buf) != 0) \
				(builder)->struct_return = (void *)(return_buf); \
			else \
				(builder)->struct_return = alloca(__struct_size); \
			(builder)->apply_args->struct_ptr = (builder)->struct_return; \
		} \
	} while (0)

#define jit_apply_builder_get_struct_return(builder,size,return_buf,apply_return) \
	do { \
		if(!((builder)->struct_return)) \
		{ \
			jit_memcpy((return_buf), (apply_return), (size)); \
		} \
		else if((builder)->struct_return != (void *)(return_buf)) \
		{ \
			jit_memcpy((return_buf), (builder)->struct_return, (size)); \
		} \
	} while (0)

#define jit_apply_builder_start_varargs(builder) \
	do { \
	} while (0)

#define jit_apply_parser_start_varargs(builder) \
	do { \
	} while (0)

#define jit_apply_builder_add_sbyte(builder,value) \
	jit_apply_builder_add_word((builder), (value));
#define jit_apply_builder_add_ubyte(builder,value) \
	jit_apply_builder_add_word((builder), (value));
#define jit_apply_builder_add_short(builder,value) \
	jit_apply_builder_add_word((builder), (value));
#define jit_apply_builder_add_ushort(builder,value) \
	jit_apply_builder_add_word((builder), (value));
#define jit_apply_builder_add_int(builder,value) \
	jit_apply_builder_add_word((builder), (value));
#define jit_apply_builder_add_uint(builder,value) \
	jit_apply_builder_add_word((builder), (jit_nuint)(value));
#define jit_apply_builder_add_nint(builder,value) \
	jit_apply_builder_add_word((builder), (value));
#define jit_apply_builder_add_nuint(builder,value) \
	jit_apply_builder_add_word((builder), (jit_nuint)(value));
#define jit_apply_builder_add_long(builder,value) \
	jit_apply_builder_add_word((builder), (value));
#define jit_apply_builder_add_ulong(builder,value) \
	jit_apply_builder_add_word((builder), (jit_nuint)(value));
#define jit_apply_builder_add_float32(builder,value) \
	jit_apply_builder_add_large_stack((builder), jit_nfloat, (value));
#define jit_apply_builder_add_float64(builder,value) \
	do { \
		if((builder)->float_used < 8) \
		{ \
			(builder)->apply_args->float_regs[(builder)->float_used].double_value = (jit_reg_double)(value); \
			++((builder)->float_used); \
		} \
		else \
		{ \
			jit_nfloat __temp = (jit_nfloat)(value); \
			jit_memcpy((builder)->apply_args->stack_args + (builder)->stack_used, &__temp, sizeof(__temp)); \
			(builder)->stack_used += (sizeof(jit_nfloat) + sizeof(jit_nint) - 1) & ~(sizeof(jit_nint) - 1); \
		} \
	} while (0)
#define jit_apply_builder_add_nfloat(builder,value) \
	do { \
		if((builder)->float_used < 8) \
		{ \
			(builder)->apply_args->float_regs[(builder)->float_used].nfloat_value = (jit_reg_nfloat)(value); \
			++((builder)->float_used); \
		} \
		else \
		{ \
			jit_nfloat __temp = (jit_nfloat)(value); \
			jit_memcpy((builder)->apply_args->stack_args + (builder)->stack_used, &__temp, sizeof(__temp)); \
			(builder)->stack_used += (sizeof(jit_nfloat) + sizeof(jit_nint) - 1) & ~(sizeof(jit_nint) - 1); \
		} \
	} while (0)
#define jit_apply_builder_add_struct(builder,value,size,align) \
	do { \
		unsigned int __size = (size); \
		unsigned int __align; __align = (align); \
		jit_apply_builder_add_large_inner((builder), (value), __size, __align); \
	} while (0)


#define jit_apply_parser_get_sbyte(builder,value) \
	jit_apply_parser_get_word((builder), jit_sbyte, (value));
#define jit_apply_parser_get_ubyte(builder,value) \
	jit_apply_parser_get_word((builder), jit_ubyte, (value));
#define jit_apply_parser_get_short(builder,value) \
	jit_apply_parser_get_word((builder), jit_short, (value));
#define jit_apply_parser_get_ushort(builder,value) \
	jit_apply_parser_get_word((builder), jit_ushort, (value));
#define jit_apply_parser_get_int(builder,value) \
	jit_apply_parser_get_word((builder), jit_int, (value));
#define jit_apply_parser_get_uint(builder,value) \
	jit_apply_parser_get_word((builder), jit_uint, (value));
#define jit_apply_parser_get_nint(builder,value) \
	jit_apply_parser_get_word((builder), jit_nint, (value));
#define jit_apply_parser_get_nuint(builder,value) \
	jit_apply_parser_get_word((builder), jit_nuint, (value));
#define jit_apply_parser_get_long(builder,value) \
	jit_apply_parser_get_word((builder), jit_long, (value));
#define jit_apply_parser_get_ulong(builder,value) \
	jit_apply_parser_get_word((builder), jit_ulong, (value));
#define jit_apply_parser_get_float32(builder,value) \
	jit_apply_parser_get_large_stack((builder), jit_nfloat, jit_float32, (value));
#define jit_apply_parser_get_float64(builder,value) \
	do { \
		if((builder)->float_used < 8) \
		{ \
			(value) = (jit_float64)((builder)->apply_args->float_regs[(builder)->float_used].double_value); \
			++((builder)->float_used); \
		} \
		else \
		{ \
			jit_nfloat __temp; \
			jit_memcpy(&__temp, (builder)->apply_args->stack_args + (builder)->stack_used, sizeof(__temp)); \
			(builder)->stack_used += (sizeof(jit_nfloat) + sizeof(jit_nint) - 1) & ~(sizeof(jit_nint) - 1); \
			(value) = (jit_float64)__temp; \
		} \
	} while (0)
#define jit_apply_parser_get_nfloat(builder,value) \
	do { \
		if((builder)->float_used < 8) \
		{ \
			(value) = (jit_nfloat)((builder)->apply_args->float_regs[(builder)->float_used].nfloat_value); \
			++((builder)->float_used); \
		} \
		else \
		{ \
			jit_nfloat __temp; \
			jit_memcpy(&__temp, (builder)->apply_args->stack_args + (builder)->stack_used, sizeof(__temp)); \
			(builder)->stack_used += (sizeof(jit_nfloat) + sizeof(jit_nint) - 1) & ~(sizeof(jit_nint) - 1); \
			(value) = (jit_nfloat)__temp; \
		} \
	} while (0)
#define jit_apply_parser_get_struct_return(builder,value) \
	do { \
		(value) = (builder)->apply_args->struct_ptr; \
	} while (0)
#define jit_apply_parser_get_struct(builder,size,align,value) \
	do { \
		unsigned int __size = (size); \
		unsigned int __num_words = (__size + sizeof(jit_nint) - 1) / sizeof(jit_nint); \
		if((8 - (builder)->word_used) >= __num_words) \
		{ \
			jit_memcpy((value), (builder)->apply_args->word_regs + (builder)->word_used, __size); \
			(builder)->word_used += __num_words; \
		} \
		else \
		{ \
			jit_memcpy((value), (builder)->apply_args->stack_args + (builder)->stack_used, __size); \
			(builder)->stack_used += __num_words * sizeof(jit_nint); \
			(builder)->word_used = 8; \
		} \
	} while (0)

#endif /* _JIT_APPLY_RULES_H */
