@*/
+typedef enum
+{
+ _JIT_APPLY_RETURN_TYPE_OTHER = 0,
+ _JIT_APPLY_RETURN_TYPE_FLOAT32 = 1,
+ _JIT_APPLY_RETURN_TYPE_FLOAT64 = 2,
+ _JIT_APPLY_RETURN_TYPE_NFLOAT = 3
+} _jit_apply_return_type;
+
/*
* Flags that indicate which structure sizes are returned in registers.
*/
unsigned int num_params;
unsigned int param;
jit_apply_return apply_return;
- int is_float_return;
+ _jit_apply_return_type return_type;
/* Initialize the argument parser */
jit_apply_parser_init(&parser, closure->signature, apply_args);
/* Set up the "apply return" buffer */
jit_memzero(&apply_return, sizeof(apply_return));
type = jit_type_normalize(jit_type_get_return(signature));
- is_float_return = 0;
+ return_type = _JIT_APPLY_RETURN_TYPE_OTHER;
if(type)
{
switch(type->kind)
{
jit_apply_return_set_float32
(&apply_return, *((jit_float32 *)return_buffer));
- is_float_return = 1;
+ return_type = _JIT_APPLY_RETURN_TYPE_FLOAT32;
}
break;
{
jit_apply_return_set_float64
(&apply_return, *((jit_float64 *)return_buffer));
- is_float_return = 1;
+ return_type = _JIT_APPLY_RETURN_TYPE_FLOAT64;
}
break;
{
jit_apply_return_set_nfloat
(&apply_return, *((jit_nfloat *)return_buffer));
- is_float_return = 1;
+ return_type = _JIT_APPLY_RETURN_TYPE_NFLOAT;
}
break;
}
/* Return the result to the caller */
- if(!is_float_return)
- {
- jit_builtin_return_int(&apply_return);
- }
- else
+ switch(return_type)
{
- jit_builtin_return_float(&apply_return);
+ case _JIT_APPLY_RETURN_TYPE_FLOAT32:
+ {
+ jit_builtin_return_float(&apply_return);
+ }
+ break;
+
+ case _JIT_APPLY_RETURN_TYPE_FLOAT64:
+ {
+ jit_builtin_return_double(&apply_return);
+ }
+ break;
+
+ case _JIT_APPLY_RETURN_TYPE_NFLOAT:
+ {
+ jit_builtin_return_nfloat(&apply_return);
+ }
+ break;
+
+ default:
+ {
+ jit_builtin_return_int(&apply_return);
+ }
}
}
#define PLATFORM_IS_X86_64 1
#endif
+#if PLATFORM_IS_X86
/*
* On x86 the extended precision numbers are 10 bytes long. However certain
* ABIs define the long double size equal to 12 bytes. The extra 2 bytes are
* for alignment purposes only and has no significance in computations.
*/
-#if PLATFORM_IS_X86
#define NFLOAT_SIGNIFICANT_BYTES (sizeof(jit_nfloat) != 12 ? sizeof(jit_nfloat) : 10)
+#elif PLATFORM_IS_X86_64
+/*
+ * On x86_64 the extended precision numbers are 10 bytes long. However certain
+ * ABIs define the long double size equal to 16 bytes. The extra 6 bytes are
+ * for alignment purposes only and has no significance in computations.
+ */
+#define NFLOAT_SIGNIFICANT_BYTES (sizeof(jit_nfloat) != 16 ? sizeof(jit_nfloat) : 10)
#else
#define NFLOAT_SIGNIFICANT_BYTES sizeof(jit_nfloat)
#endif
int doubles_in_word_regs = 0;
int nfloats_in_word_regs = 0;
int return_floats_after = 0;
+int return_doubles_after = 0;
+int return_nfloats_after = 0;
int varargs_on_stack = 0;
int struct_return_special_reg = 0;
int struct_reg_overlaps_word_reg = 0;
int doubles_in_word_regs = JIT_APPLY_DOUBLES_IN_WORD_REGS;
int nfloats_in_word_regs = JIT_APPLY_NFLOATS_IN_WORD_REGS;
int return_floats_after = JIT_APPLY_RETURN_FLOATS_AFTER;
+int return_doubles_after = JIT_APPLY_RETURN_DOUBLES_AFTER;
+int return_nfloats_after = JIT_APPLY_RETURN_NFLOATS_AFTER;
int varargs_on_stack = JIT_APPLY_VARARGS_ON_STACK;
int struct_return_special_reg = JIT_APPLY_STRUCT_RETURN_SPECIAL_REG;
int struct_reg_overlaps_word_reg = JIT_APPLY_STRUCT_REG_OVERLAPS_WORD_REG;
float float_value;
double double_value;
jit_nfloat nfloat_value;
- int float_size;
- int double_size;
- int nfloat_size;
+ int float_size = 0;
+ int double_size = 0;
+ int nfloat_size = 0;
float temp_float;
double temp_double;
jit_nfloat temp_nfloat;
jit_builtin_apply(return_float, args, 0, 1, return_value);
/* Find the location of the return value */
+ /* and determine the size of the "float" return value */
offset = 0;
while(offset < 64)
{
temp_nfloat = (jit_nfloat)123.0;
if(!mem_cmp(&nfloat_value, &temp_nfloat, NFLOAT_SIGNIFICANT_BYTES))
{
+ float_size = 3;
break;
}
}
else
{
+ float_size = 2;
break;
}
}
else
{
+ float_size = 1;
break;
}
offset += sizeof(void *);
}
- /* Determine the size of the "float" return value */
- mem_copy(&float_value, return_value + offset, sizeof(float));
- temp_float = (float)123.0;
- if(!mem_cmp(&float_value, &temp_float, sizeof(float)))
+ /* Use the offset and size information to set the final parameters */
+ return_floats_after = offset;
+ if(float_size == 2)
{
- float_size = 1;
+ return_float_as_double = 1;
}
- else
+ else if(float_size == 3)
+ {
+ return_float_as_nfloat = 1;
+ }
+
+ /* Call "return_double" and get its return structure */
+ jit_builtin_apply(return_double, args, 0, 1, return_value);
+
+ /* Find the location of the return value */
+ /* and determine the size of the "double" return value */
+ offset = 0;
+ while(offset < 64)
{
mem_copy(&double_value, return_value + offset, sizeof(double));
- temp_double = (double)123.0;
- if(!mem_cmp(&double_value, &temp_double, sizeof(double)))
+ temp_double = (double)456.7;
+ if(mem_cmp(&double_value, &temp_double, sizeof(double)))
{
- float_size = 2;
+ mem_copy(&nfloat_value, return_value + offset,
+ sizeof(jit_nfloat));
+ temp_nfloat = (jit_nfloat)456.7;
+ if(!mem_cmp(&nfloat_value, &temp_nfloat, NFLOAT_SIGNIFICANT_BYTES))
+ {
+ double_size = 3;
+ break;
+ }
}
else
{
- float_size = 3;
+ double_size = 2;
+ break;
}
+ offset += sizeof(void *);
}
- /* Call "return_double" and get its return structure */
- jit_builtin_apply(return_double, args, 0, 1, return_value);
-
- /* Determine the size of the "double" return value */
- mem_copy(&double_value, return_value + offset, sizeof(double));
- temp_double = (double)456.7;
- if(!mem_cmp(&double_value, &temp_double, sizeof(double)))
- {
- double_size = 2;
- }
- else
+ /* Use the offset and size information to set the final parameters */
+ return_doubles_after = offset;
+ if(double_size == 3)
{
- double_size = 3;
+ return_double_as_nfloat = 1;
}
/* Call "return_nfloat" and get its return structure */
jit_builtin_apply(return_nfloat, args, 0, 1, return_value);
- /* Determine the size of the "nfloat" return value */
- mem_copy(&double_value, return_value + offset, sizeof(double));
- temp_double = (double)8901.2;
- if(!mem_cmp(&double_value, &temp_double, sizeof(double)))
- {
- nfloat_size = 2;
- }
- else
+ /* Find the location of the return value */
+ /* and determine the size of the "nfloat" return value */
+ offset = 0;
+ while(offset < 64)
{
- nfloat_size = 3;
+ mem_copy(&double_value, return_value + offset, sizeof(double));
+ temp_double = (double)8901.2;
+ if(mem_cmp(&double_value, &temp_double, sizeof(double)))
+ {
+ mem_copy(&nfloat_value, return_value + offset,
+ sizeof(jit_nfloat));
+ temp_nfloat = (jit_nfloat)8901.2;
+ if(!mem_cmp(&nfloat_value, &temp_nfloat, NFLOAT_SIGNIFICANT_BYTES))
+ {
+ nfloat_size = 3;
+ break;
+ }
+ }
+ else
+ {
+ nfloat_size = 2;
+ break;
+ }
+ offset += sizeof(void *);
}
/* Use the offset and size information to set the final parameters */
- return_floats_after = offset;
- if(float_size == 2)
- {
- return_float_as_double = 1;
- }
- else if(float_size == 3)
- {
- return_float_as_nfloat = 1;
- }
- if(double_size == 3)
- {
- return_double_as_nfloat = 1;
- }
+ return_nfloats_after = offset;
if(nfloat_size == 2)
{
return_nfloat_as_double = 1;
const char *double_type;
const char *nfloat_type;
- /* Dump the definition of "jit_apply_float" */
- printf("typedef union\n{\n");
+ /* Determine the float return types */
if(return_float_as_nfloat)
{
float_type = "jit_nfloat";
{
nfloat_type = "jit_nfloat";
}
- printf("\t%s float_value;\n", float_type);
- printf("\t%s double_value;\n", double_type);
- printf("\t%s nfloat_value;\n", nfloat_type);
- printf("\n} jit_apply_float;\n");
/* Dump the definition of "jit_apply_return" */
printf("typedef union\n{\n");
printf("\tjit_ulong ulong_value;\n");
if(return_floats_after)
{
- printf("\tstruct { jit_ubyte pad[%d]; jit_apply_float inner_value; } f_value;\n",
- return_floats_after);
+ printf("\tstruct { jit_ubyte pad[%d]; %s f_value; } float_value;\n",
+ return_floats_after, float_type);
+ }
+ else
+ {
+ printf("\tstruct { %s f_value; } float_value;\n", float_type);
+ }
+ if(return_doubles_after)
+ {
+ printf("\tstruct { jit_ubyte pad[%d]; %s f_value; } double_value;\n",
+ return_doubles_after, double_type);
+ }
+ else
+ {
+ printf("\tstruct { %s f_value; } double_value;\n", double_type);
+ }
+ if(return_nfloats_after)
+ {
+ printf("\tstruct { jit_ubyte pad[%d]; %s f_value; } nfloat_value;\n",
+ return_nfloats_after, nfloat_type);
}
else
{
- printf("\tstruct { jit_apply_float inner_value; } f_value;\n");
+ printf("\tstruct { %s f_value; } nfloat_value;\n", nfloat_type);
}
if(max_struct_in_reg > 0)
{
printf("#define jit_apply_return_get_ulong(result)\t\\\n");
printf("\t((jit_ulong)((result)->ulong_value))\n");
printf("#define jit_apply_return_get_float32(result)\t\\\n");
- printf("\t((jit_float32)((result)->f_value.inner_value.float_value))\n");
+ printf("\t((jit_float32)((result)->float_value.f_value))\n");
printf("#define jit_apply_return_get_float64(result)\t\\\n");
- printf("\t((jit_float64)((result)->f_value.inner_value.double_value))\n");
+ printf("\t((jit_float64)((result)->double_value.f_value))\n");
printf("#define jit_apply_return_get_nfloat(result)\t\\\n");
- printf("\t((jit_nfloat)((result)->f_value.inner_value.nfloat_value))\n");
+ printf("\t((jit_nfloat)((result)->nfloat_value.f_value))\n");
printf("\n");
printf("#define jit_apply_return_set_sbyte(result,value)\t\\\n");
printf("\t(((result)->int_value) = ((jit_nint)(value)))\n");
printf("#define jit_apply_return_set_ulong(result,value)\t\\\n");
printf("\t(((result)->ulong_value) = ((jit_ulong)(value)))\n");
printf("#define jit_apply_return_set_float32(result,value)\t\\\n");
- printf("\t(((result)->f_value.inner_value.float_value) = ((%s)(value)))\n",
+ printf("\t(((result)->float_value.f_value) = ((%s)(value)))\n",
float_type);
printf("#define jit_apply_return_set_float64(result,value)\t\\\n");
- printf("\t(((result)->f_value.inner_value.double_value) = ((%s)(value)))\n",
+ printf("\t(((result)->double_value.f_value) = ((%s)(value)))\n",
double_type);
printf("#define jit_apply_return_set_nfloat(result,value)\t\\\n");
- printf("\t(((result)->f_value.inner_value.nfloat_value) = ((%s)(value)))\n",
+ printf("\t(((result)->nfloat_value.f_value) = ((%s)(value)))\n",
nfloat_type);
printf("\n");
}
printf("#define JIT_APPLY_DOUBLES_IN_WORD_REGS %d\n", doubles_in_word_regs);
printf("#define JIT_APPLY_NFLOATS_IN_WORD_REGS %d\n", nfloats_in_word_regs);
printf("#define JIT_APPLY_RETURN_FLOATS_AFTER %d\n", return_floats_after);
+ printf("#define JIT_APPLY_RETURN_DOUBLES_AFTER %d\n", return_doubles_after);
+ printf("#define JIT_APPLY_RETURN_NFLOATS_AFTER %d\n", return_nfloats_after);
printf("#define JIT_APPLY_VARARGS_ON_STACK %d\n", varargs_on_stack);
printf("#define JIT_APPLY_STRUCT_RETURN_SPECIAL_REG %d\n", struct_return_special_reg);
printf("#define JIT_APPLY_STRUCT_REG_OVERLAPS_WORD_REG %d\n",