Alien-LibJIT
view release on metacpan or search on metacpan
libjit/tools/gen-apply.c view on Meta::CPAN
}
if(num_word_regs > 0)
{
printf("\tjit_nint word_regs[%d];\n", num_word_regs);
}
else if(x86_fastcall)
{
printf("\tjit_nint word_regs[2];\n");
}
if(pad_float_regs)
{
printf("\tjit_nint pad[%d];\n", pad_float_regs);
}
if((num_float_regs > 0) ||
(num_double_regs > 0) ||
(num_nfloat_regs > 0))
{
printf("\tjit_reg_float_struct float_regs[%d];\n", num_float_regs);
}
printf("\n} jit_apply_struct;\n\n");
}
/*
* Dump macro definitions that are used to build the apply parameter block.
*/
void dump_apply_macros(void)
{
int apply_size;
const char *name;
const char *word_reg_limit;
char buf[32];
/* Declare the "jit_apply_builder" structure */
printf("typedef struct\n{\n");
printf("\tjit_apply_struct *apply_args;\n");
printf("\tunsigned int stack_used;\n");
if(num_word_regs > 0 || x86_fastcall)
{
printf("\tunsigned int word_used;\n");
if(x86_fastcall)
{
printf("\tunsigned int word_max;\n");
}
}
if(num_float_regs > 0)
{
printf("\tunsigned int float_used;\n");
}
printf("\tvoid *struct_return;\n");
printf("\n} jit_apply_builder;\n\n");
/* Include jit-apply-func.h here to allow the backend to add it's definitions */
printf("#include \"jit-apply-func.h\"\n\n");
printf("void\n_jit_builtin_apply_add_struct(jit_apply_builder *builder, void *value, jit_type_t struct_type);\n\n");
printf("void\n_jit_builtin_apply_get_struct(jit_apply_builder *builder, void *value, jit_type_t struct_type);\n\n");
printf("void\n_jit_builtin_apply_get_struct_return(jit_apply_builder *builder, void *return_value, jit_apply_return *apply_return, jit_type_t struct_type);\n\n");
/* Macro to initialize the apply builder */
printf("#define jit_apply_builder_init(builder,type)\t\\\n");
printf("\tdo { \\\n");
apply_size = max_apply_size;
printf("\t\t(builder)->apply_args = (jit_apply_struct *)alloca(sizeof(jit_apply_struct)); \\\n");
if(apply_size > sizeof(void *))
{
printf("\t\tjit_memset((builder)->apply_args, 0, %d); \\\n", apply_size);
}
printf("\t\t(builder)->apply_args->stack_args = (unsigned char *)alloca(jit_type_get_max_arg_size((type))); \\\n");
printf("\t\t(builder)->stack_used = 0; \\\n");
if(x86_fastcall)
{
printf("\t\t(builder)->word_used = 0; \\\n");
printf("\t\tif(jit_type_get_abi((type)) == jit_abi_fastcall) \\\n");
printf("\t\t\t(builder)->word_max = 2; \\\n");
printf("\t\telse; \\\n");
printf("\t\t\t(builder)->word_max = 0; \\\n");
word_reg_limit = "(builder)->word_max";
}
else if(num_word_regs > 0)
{
printf("\t\t(builder)->word_used = 0; \\\n");
sprintf(buf, "%d", num_word_regs);
word_reg_limit = buf;
}
else
{
word_reg_limit = "???";
}
if(num_float_regs > 0)
{
printf("\t\t(builder)->float_used = 0; \\\n");
}
printf("\t\t(builder)->struct_return = 0; \\\n");
printf("\t} while (0)\n\n");
/* Macro to initialize the apply builder in closure parse mode.
The "args" parameter is the result of calling "__builtin_apply_args" */
printf("#define jit_apply_parser_init(builder,type,args)\t\\\n");
printf("\tdo { \\\n");
printf("\t\t(builder)->apply_args = (jit_apply_struct *)(args); \\\n");
printf("\t\t(builder)->stack_used = 0; \\\n");
if(x86_fastcall)
{
printf("\t\t(builder)->word_used = 0; \\\n");
printf("\t\tif(jit_type_get_abi((type)) == jit_abi_fastcall) \\\n");
printf("\t\t\t(builder)->word_max = 2; \\\n");
printf("\t\telse; \\\n");
printf("\t\t\t(builder)->word_max = 0; \\\n");
}
else if(num_word_regs > 0)
{
printf("\t\t(builder)->word_used = 0; \\\n");
}
if(num_float_regs > 0)
{
printf("\t\t(builder)->float_used = 0; \\\n");
}
printf("\t\t(builder)->struct_return = 0; \\\n");
printf("\t} while (0)\n\n");
/* Macro to add a word argument to the apply parameters */
printf("#define jit_apply_builder_add_word(builder,value) \\\n");
printf("\tdo { \\\n");
if(num_word_regs > 0 || x86_fastcall)
{
printf("\t\tif((builder)->word_used < %s) \\\n", word_reg_limit);
printf("\t\t{ \\\n");
printf("\t\t\t(builder)->apply_args->word_regs[(builder)->word_used] = (jit_nint)(value); \\\n");
printf("\t\t\t++((builder)->word_used); \\\n");
if(struct_reg_overlaps_word_reg)
{
/* We need to set the struct register slot as well */
printf("\t\t\tif((builder)->word_used == 1) \\\n");
printf("\t\t\t{ \\\n");
printf("\t\t\t\t(builder)->apply_args->struct_ptr = (void *)(jit_nint)(value); \\\n");
printf("\t\t\t} \\\n");
}
printf("\t\t} \\\n");
printf("\t\telse \\\n");
printf("\t\t{ \\\n");
printf("\t\t\t*((jit_nint*)((builder)->apply_args->stack_args + (builder)->stack_used)) = (jit_nint)(value); \\\n");
printf("\t\t\t(builder)->stack_used += sizeof(jit_nint); \\\n");
printf("\t\t} \\\n");
}
else
{
printf("\t\t*((jit_nint*)((builder)->apply_args->stack_args + (builder)->stack_used)) = (jit_nint)(value); \\\n");
printf("\t\t(builder)->stack_used += sizeof(jit_nint); \\\n");
}
printf("\t} while (0)\n\n");
/* Macro to get a word argument from the apply parameters */
printf("#define jit_apply_parser_get_word(builder,type,value) \\\n");
printf("\tdo { \\\n");
if(num_word_regs > 0 || x86_fastcall)
{
printf("\t\tif((builder)->word_used < %s) \\\n", word_reg_limit);
printf("\t\t{ \\\n");
printf("\t\t\t(value) = (type)((builder)->apply_args->word_regs[(builder)->word_used]); \\\n");
printf("\t\t\t++((builder)->word_used); \\\n");
printf("\t\t} \\\n");
printf("\t\telse \\\n");
printf("\t\t{ \\\n");
printf("\t\t\t(value) = (type)(*((jit_nint*)((builder)->apply_args->stack_args + (builder)->stack_used))); \\\n");
printf("\t\t\t(builder)->stack_used += sizeof(jit_nint); \\\n");
printf("\t\t} \\\n");
}
else
{
printf("\t\t(value) = (type)(*((jit_nint*)((builder)->apply_args->stack_args + (builder)->stack_used))); \\\n");
printf("\t\t(builder)->stack_used += sizeof(jit_nint); \\\n");
}
printf("\t} while (0)\n\n");
/* Macro to align the word registers for a "long" value */
printf("#define jit_apply_builder_align_regs(builder,num_words,align) \\\n");
if((align_long_regs || !can_split_long) &&
(num_word_regs > 0 || x86_fastcall))
{
printf("\tdo { \\\n");
printf("\t\tif((align) > sizeof(jit_nint) && (num_words) > 1) \\\n");
printf("\t\t{ \\\n");
if(align_long_regs)
{
printf("\t\t\tif(((builder)->word_used %% 2) == 1) \\\n");
printf("\t\t\t{ \\\n");
printf("\t\t\t\t++((builder)->word_used); \\\n");
printf("\t\t\t} \\\n");
}
if(!can_split_long)
{
printf("\t\t\tif((%s - (builder)->word_used) < (num_words)) \\\n", word_reg_limit);
printf("\t\t\t{ \\\n");
printf("\t\t\t\t(builder)->word_used = %s; \\\n", word_reg_limit);
printf("\t\t\t} \\\n");
}
printf("\t\t} \\\n");
printf("\t} while (0)\n\n");
}
else
{
printf("\tdo { ; } while (0)\n\n");
}
/* Macro to align the stack for a "long" value */
printf("#define jit_apply_builder_align_stack(builder,num_words,align) \\\n");
if(align_long_stack)
{
printf("\tdo { \\\n");
printf("\t\tif((align) > sizeof(jit_nint) && (num_words) > 1) \\\n");
printf("\t\t{ \\\n");
printf("\t\t\tif(((builder)->stack_used %% 2) == 1) \\\n");
printf("\t\t\t{ \\\n");
printf("\t\t\t\t++((builder)->stack_used); \\\n");
printf("\t\t\t} \\\n");
printf("\t\t} \\\n");
printf("\t} while (0)\n\n");
}
else
{
printf("\tdo { ; } while (0)\n\n");
}
/* Macro to add a large (e.g. dword) argument to the apply parameters */
printf("#define jit_apply_builder_add_large_inner(builder,ptr,size,align) \\\n");
printf("\tdo { \\\n");
printf("\t\tunsigned int __num_words = ((size) + sizeof(jit_nint) - 1) / sizeof(jit_nint); \\\n");
if(num_word_regs > 0 || x86_fastcall)
{
printf("\t\tjit_apply_builder_align_regs((builder), __num_words, (align)); \\\n");
printf("\t\tif((%s - (builder)->word_used) >= __num_words) \\\n", word_reg_limit);
printf("\t\t{ \\\n");
printf("\t\t\tjit_memcpy((builder)->apply_args->word_regs + (builder)->word_used, (ptr), (size)); \\\n");
printf("\t\t\t(builder)->word_used += __num_words; \\\n");
printf("\t\t} \\\n");
printf("\t\telse if((builder)->word_used < %s) \\\n", word_reg_limit);
printf("\t\t{ \\\n");
printf("\t\t\tunsigned int __split = (%s - (builder)->word_used); \\\n", word_reg_limit);
printf("\t\t\tjit_memcpy((builder)->apply_args->word_regs + (builder)->word_used, (ptr), __split * sizeof(jit_nint)); \\\n");
printf("\t\t\tjit_memcpy((builder)->apply_args->stack_args, ((jit_nint *)(ptr)) + __split, (size) - __split * sizeof(jit_nint)); \\\n");
printf("\t\t\t(builder)->word_used = %s; \\\n", word_reg_limit);
printf("\t\t\t(builder)->stack_used = __num_words - __split; \\\n");
printf("\t\t} \\\n");
printf("\t\telse \\\n");
printf("\t\t{ \\\n");
printf("\t\t\tjit_apply_builder_align_stack((builder), __num_words, (align)); \\\n");
printf("\t\t\tjit_memcpy((builder)->apply_args->stack_args + (builder)->stack_used, (ptr), (size)); \\\n");
printf("\t\t\t(builder)->stack_used += __num_words * sizeof(jit_nint); \\\n");
printf("\t\t\t(builder)->word_used = %s; \\\n", word_reg_limit);
printf("\t\t} \\\n");
}
else
{
printf("\t\tjit_apply_builder_align_stack((builder), __num_words, (align)); \\\n");
printf("\t\tjit_memcpy((builder)->apply_args->stack_args + (builder)->stack_used, (ptr), (size)); \\\n");
printf("\t\t(builder)->stack_used += __num_words * sizeof(jit_nint); \\\n");
}
printf("\t} while (0)\n\n");
printf("#define jit_apply_builder_add_large(builder,type,value) \\\n");
printf("\tdo { \\\n");
printf("\t\ttype __temp = (type)(value); \\\n");
printf("\t\tjit_apply_builder_add_large_inner((builder), &__temp, sizeof(__temp), sizeof(jit_nint)); \\\n");
printf("\t} while (0)\n\n");
/* Macro to get a large (e.g. dword) argument from the apply parameters */
printf("#define jit_apply_parser_get_large(builder,type,finaltype,value) \\\n");
printf("\tdo { \\\n");
printf("\t\ttype __temp; \\\n");
printf("\t\tunsigned int __num_words = (sizeof(__temp) + sizeof(jit_nint) - 1) / sizeof(jit_nint); \\\n");
if(num_word_regs > 0 || x86_fastcall)
{
printf("\t\tjit_apply_builder_align_regs((builder), __num_words, sizeof(type)); \\\n");
printf("\t\tif((%s - (builder)->word_used) >= __num_words) \\\n", word_reg_limit);
printf("\t\t{ \\\n");
printf("\t\t\tjit_memcpy(&__temp, (builder)->apply_args->word_regs + (builder)->word_used, sizeof(__temp)); \\\n");
printf("\t\t\t(builder)->word_used += __num_words; \\\n");
printf("\t\t} \\\n");
printf("\t\telse if((builder)->word_used < %s) \\\n", word_reg_limit);
printf("\t\t{ \\\n");
printf("\t\t\tunsigned int __split = (%s - (builder)->word_used); \\\n", word_reg_limit);
printf("\t\t\tjit_memcpy(&__temp, (builder)->apply_args->word_regs + (builder)->word_used, __split * sizeof(jit_nint)); \\\n");
printf("\t\t\tjit_memcpy(((jit_nint *)&__temp) + __split, (builder)->apply_args->stack_args, (__num_words - __split) * sizeof(jit_nint)); \\\n");
printf("\t\t\t(builder)->word_used = %s; \\\n", word_reg_limit);
printf("\t\t\t(builder)->stack_used = __num_words - __split; \\\n");
printf("\t\t} \\\n");
printf("\t\telse \\\n");
printf("\t\t{ \\\n");
printf("\t\t\tjit_apply_builder_align_stack((builder), __num_words, sizeof(type)); \\\n");
printf("\t\t\tjit_memcpy(&__temp, (builder)->apply_args->stack_args + (builder)->stack_used, sizeof(__temp)); \\\n");
printf("\t\t\t(builder)->stack_used += __num_words * sizeof(jit_nint); \\\n");
printf("\t\t\t(builder)->word_used = %s; \\\n", word_reg_limit);
printf("\t\t} \\\n");
}
else
{
printf("\t\tjit_apply_builder_align_stack((builder), __num_words, sizeof(type)); \\\n");
printf("\t\tjit_memcpy(&__temp, (builder)->apply_args->stack_args + (builder)->stack_used, sizeof(__temp)); \\\n");
printf("\t\t(builder)->stack_used += __num_words * sizeof(jit_nint); \\\n");
}
printf("\t\t(value) = (finaltype)(__temp); \\\n");
printf("\t} while (0)\n\n");
/* Macro to add a large (e.g. dword) argument to the apply parameters
on the stack, ignoring word registers */
printf("#define jit_apply_builder_add_large_stack(builder,type,value) \\\n");
printf("\tdo { \\\n");
printf("\t\ttype __temp = (type)(value); \\\n");
printf("\t\tunsigned int __num_words = (sizeof(__temp) + sizeof(jit_nint) - 1) / sizeof(jit_nint); \\\n");
printf("\t\tjit_apply_builder_align_stack((builder), __num_words, sizeof(type)); \\\n");
printf("\t\tjit_memcpy((builder)->apply_args->stack_args + (builder)->stack_used, &__temp, sizeof(__temp)); \\\n");
printf("\t\t(builder)->stack_used += __num_words * sizeof(jit_nint); \\\n");
printf("\t} while (0)\n\n");
/* Macro to get a large (e.g. dword) argument from the apply parameters
on the stack, ignoring word registers */
printf("#define jit_apply_parser_get_large_stack(builder,type,finaltype,value) \\\n");
printf("\tdo { \\\n");
printf("\t\ttype __temp; \\\n");
printf("\t\tunsigned int __num_words = (sizeof(__temp) + sizeof(jit_nint) - 1) / sizeof(jit_nint); \\\n");
printf("\t\tjit_apply_builder_align_stack((builder), __num_words, sizeof(type)); \\\n");
printf("\t\tjit_memcpy(&__temp, (builder)->apply_args->stack_args + (builder)->stack_used, sizeof(__temp)); \\\n");
printf("\t\t(builder)->stack_used += __num_words * sizeof(jit_nint); \\\n");
printf("\t\t(value) = (finaltype)(__temp); \\\n");
printf("\t} while (0)\n\n");
/* Macro to set the structure return area */
printf("#define jit_apply_builder_add_struct_return(builder,size,return_buf) \\\n");
printf("\tdo { \\\n");
printf("\t\tunsigned int __struct_size = (unsigned int)(size); \\\n");
printf("\t\tif(__struct_size >= 1 && __struct_size <= 64 && \\\n");
printf("\t\t (_jit_apply_return_in_reg[(__struct_size - 1) / 8] \\\n");
printf("\t\t & (1 << ((__struct_size - 1) %% 8))) != 0) \\\n");
printf("\t\t{ \\\n");
printf("\t\t\t(builder)->struct_return = 0; \\\n");
printf("\t\t} \\\n");
printf("\t\telse \\\n");
printf("\t\t{ \\\n");
printf("\t\t\tif((return_buf) != 0) \\\n");
printf("\t\t\t\t(builder)->struct_return = (void *)(return_buf); \\\n");
printf("\t\t\telse \\\n");
printf("\t\t\t\t(builder)->struct_return = alloca(__struct_size); \\\n");
if(struct_return_special_reg && !struct_reg_overlaps_word_reg)
{
printf("\t\t\t(builder)->apply_args->struct_ptr = (builder)->struct_return; \\\n");
}
else
{
printf("\t\t\tjit_apply_builder_add_word((builder), (builder)->struct_return); \\\n");
}
printf("\t\t} \\\n");
printf("\t} while (0)\n\n");
/* Macro to extract the structure return value, if it is in registers */
printf("#define jit_apply_builder_get_struct_return(builder,size,return_buf,apply_return) \\\n");
printf("\tdo { \\\n");
printf("\t\tif(!((builder)->struct_return)) \\\n");
printf("\t\t{ \\\n");
printf("\t\t\tjit_memcpy((return_buf), (apply_return), (size)); \\\n");
printf("\t\t} \\\n");
printf("\t\telse if((builder)->struct_return != (void *)(return_buf)) \\\n");
printf("\t\t{ \\\n");
printf("\t\t\tjit_memcpy((return_buf), (builder)->struct_return, (size)); \\\n");
printf("\t\t} \\\n");
printf("\t} while (0)\n\n");
/* Macro to start the vararg area */
printf("#define jit_apply_builder_start_varargs(builder) \\\n");
printf("\tdo { \\\n");
if(varargs_on_stack)
{
if(num_word_regs > 0 || x86_fastcall)
{
printf("\t\t(builder)->word_used = %s; \\\n", word_reg_limit);
}
if(num_float_regs > 0)
{
printf("\t\t(builder)->float_used = %d; \\\n", num_float_regs);
}
}
printf("\t} while (0)\n\n");
/* Macro to start the vararg area when parsing a closure */
printf("#define jit_apply_parser_start_varargs(builder) \\\n");
printf("\tdo { \\\n");
if(varargs_on_stack)
{
if(num_word_regs > 0 || x86_fastcall)
{
printf("\t\t(builder)->word_used = %s; \\\n", word_reg_limit);
}
if(num_float_regs > 0)
{
printf("\t\t(builder)->float_used = %d; \\\n", num_float_regs);
}
}
printf("\t} while (0)\n\n");
/* Add parameter values of various types */
printf("#define jit_apply_builder_add_sbyte(builder,value) \\\n");
printf("\tjit_apply_builder_add_word((builder), (value));\n");
printf("#define jit_apply_builder_add_ubyte(builder,value) \\\n");
printf("\tjit_apply_builder_add_word((builder), (value));\n");
printf("#define jit_apply_builder_add_short(builder,value) \\\n");
printf("\tjit_apply_builder_add_word((builder), (value));\n");
printf("#define jit_apply_builder_add_ushort(builder,value) \\\n");
printf("\tjit_apply_builder_add_word((builder), (value));\n");
printf("#define jit_apply_builder_add_int(builder,value) \\\n");
printf("\tjit_apply_builder_add_word((builder), (value));\n");
printf("#define jit_apply_builder_add_uint(builder,value) \\\n");
printf("\tjit_apply_builder_add_word((builder), (jit_nuint)(value));\n");
printf("#define jit_apply_builder_add_nint(builder,value) \\\n");
printf("\tjit_apply_builder_add_word((builder), (value));\n");
printf("#define jit_apply_builder_add_nuint(builder,value) \\\n");
printf("\tjit_apply_builder_add_word((builder), (jit_nuint)(value));\n");
#ifdef JIT_NATIVE_INT32
printf("#define jit_apply_builder_add_long(builder,value) \\\n");
printf("\tjit_apply_builder_add_large((builder), jit_long, (value));\n");
printf("#define jit_apply_builder_add_ulong(builder,value) \\\n");
printf("\tjit_apply_builder_add_large((builder), jit_ulong, (value));\n");
#else
printf("#define jit_apply_builder_add_long(builder,value) \\\n");
printf("\tjit_apply_builder_add_word((builder), (value));\n");
printf("#define jit_apply_builder_add_ulong(builder,value) \\\n");
printf("\tjit_apply_builder_add_word((builder), (jit_nuint)(value));\n");
#endif
if(num_float_regs > 0)
{
/* Pass floating point values in registers, if possible */
printf("#define jit_apply_builder_add_float32(builder,value) \\\n");
printf("\tdo { \\\n");
printf("\t\tif((builder)->float_used < %d) \\\n", num_float_regs);
printf("\t\t{ \\\n");
printf("\t\t\t(builder)->apply_args->float_regs[(builder)->float_used].float_value = (jit_reg_float)(value); \\\n");
printf("\t\t\t++((builder)->float_used); \\\n");
printf("\t\t} \\\n");
printf("\t\telse \\\n");
printf("\t\t{ \\\n");
if(pass_stack_float_as_double)
name = "jit_float64";
else if(pass_stack_float_as_nfloat)
name = "jit_nfloat";
else
( run in 0.382 second using v1.01-cache-2.11-cpan-62a16548d74 )