Browse Source

Allow different float types at different offsets in the apply return struct.

cache-refactoring
Klaus Treichel 17 years ago
parent
commit
44859d7672
  1. 20
      ChangeLog
  2. 15
      jit/jit-apply-func.h
  3. 21
      jit/jit-apply-x86-64.h
  4. 22
      jit/jit-apply-x86.h
  5. 47
      jit/jit-apply.c
  6. 169
      tools/gen-apply.c

20
ChangeLog

@ -3,6 +3,26 @@
* tools/gen-rules-parser.y, tools/gen-rules-scanner-l: Add the imms32
and immu32 keywords for 32bit signed and unsigned immediate values.
* tools/gen-apply.c: Add support for apply return structs where
different float types are at different offsets in the return struct.
* jit/jit-apply.c (closure_handler): Handle return of different float
types with different macros.
* jit/jit-apply-x86.h (jit_builtin_return_float): Adjust macro to
the new apply return struct layout.
Add the new jit_builtin_return_double and jit_builtin_return_nfloat
macros.
Fix jit_builtin_return_float macro for MS cl.
* jit/jit-apply-x86-64.h (jit_builtin_return_float): Adjust macro
to the new apply return struct layout.
Add the new jit_builtin_return_double and jit_builtin_return_nfloat
macros.
* jit/jit-apply-func.h: Add the new jit_builtin_return_double,
jit_builtin_return_nfloat and jit_builtin_return_long macros.
2008-05-26 Juan Jesus Garcia de Soria <juanj.g_soria@grupobbva.com>
* include/jit/jit-defs.h.in: define JIT_EXPORT_DATA macro to support

15
jit/jit-apply-func.h

@ -59,11 +59,26 @@
__builtin_return((return_buf)); \
} while (0)
#define jit_builtin_return_long(return_buf) \
do { \
__builtin_return((return_buf)); \
} while (0)
#define jit_builtin_return_float(return_buf) \
do { \
__builtin_return((return_buf)); \
} while (0)
#define jit_builtin_return_double(return_buf) \
do { \
__builtin_return((return_buf)); \
} while (0)
#define jit_builtin_return_nfloat(return_buf) \
do { \
__builtin_return((return_buf)); \
} while (0)
#endif
/*

21
jit/jit-apply-x86-64.h

@ -249,6 +249,27 @@ _jit_classify_struct(jit_param_passing_t *passing,
__asm__ ( \
"lea %0, %%rcx\n\t" \
"movaps 0x10(%%rcx), %%xmm0\n\t" \
: : "m"(*(return_buf)) \
: "rcx", "xmm0", "st" \
); \
return; \
} while (0)
#define jit_builtin_return_double(return_buf) \
do { \
__asm__ ( \
"lea %0, %%rcx\n\t" \
"movaps 0x10(%%rcx), %%xmm0\n\t" \
: : "m"(*(return_buf)) \
: "rcx", "xmm0", "st" \
); \
return; \
} while (0)
#define jit_builtin_return_nfloat(return_buf) \
do { \
__asm__ ( \
"lea %0, %%rcx\n\t" \
"fldt 0x20(%%rcx)\n\t" \
: : "m"(*(return_buf)) \
: "rcx", "xmm0", "st" \

22
jit/jit-apply-x86.h

@ -119,7 +119,7 @@
do { \
jit_nfloat __value = \
((jit_apply_return *)(return_buf))-> \
f_value.inner_value.nfloat_value; \
nfloat_value.f_value; \
if(sizeof(jit_nfloat) == sizeof(double)) \
{ \
__asm__ ( \
@ -229,7 +229,7 @@
do { \
jit_nfloat __value = \
((jit_apply_return *)(return_buf))-> \
f_value.inner_value.nfloat_value; \
nfloat_value.f_value; \
if(sizeof(jit_nfloat) == sizeof(double)) \
{ \
__asm__ ( \
@ -289,9 +289,9 @@
{ \
__asm { \
__asm mov ecx, dword ptr __return_buf \
/*__asm fstpt [ecx + 8]*/ \
__asm _emit 0xDB \
__asm _emit 0x79 \
/*__asm fstpl [ecx + 8]*/ \
__asm _emit 0xDD \
__asm _emit 0x59 \
__asm _emit 0x08 \
} \
} \
@ -323,11 +323,11 @@
#define jit_builtin_return_float(return_buf) \
do { \
double __value = \
double __dvalue = \
((jit_apply_return *)(return_buf))-> \
f_value.inner_value.nfloat_value; \
nfloat_value.f_value; \
__asm { \
__asm lea ecx, dword ptr __value \
__asm lea ecx, dword ptr __dvalue \
/* __asm fldl [ecx] */ \
__asm _emit 0xDD \
__asm _emit 0x01 \
@ -337,6 +337,12 @@
#endif /* MSC_VER */
#define jit_builtin_return_double(return_buf) \
jit_builtin_return_float((return_buf))
#define jit_builtin_return_nfloat(return_buf) \
jit_builtin_return_float((return_buf))
/*
* The maximum number of bytes that are needed to represent a closure,
* and the alignment to use for the closure.

47
jit/jit-apply.c

@ -61,6 +61,14 @@ performed with @code{jit_closure_create}.
@*/
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.
*/
@ -568,7 +576,7 @@ static void closure_handler(jit_closure_t closure, void *apply_args)
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);
@ -710,7 +718,7 @@ static void closure_handler(jit_closure_t closure, void *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)
@ -775,7 +783,7 @@ static void closure_handler(jit_closure_t closure, void *apply_args)
{
jit_apply_return_set_float32
(&apply_return, *((jit_float32 *)return_buffer));
is_float_return = 1;
return_type = _JIT_APPLY_RETURN_TYPE_FLOAT32;
}
break;
@ -783,7 +791,7 @@ static void closure_handler(jit_closure_t closure, void *apply_args)
{
jit_apply_return_set_float64
(&apply_return, *((jit_float64 *)return_buffer));
is_float_return = 1;
return_type = _JIT_APPLY_RETURN_TYPE_FLOAT64;
}
break;
@ -791,7 +799,7 @@ static void closure_handler(jit_closure_t closure, void *apply_args)
{
jit_apply_return_set_nfloat
(&apply_return, *((jit_nfloat *)return_buffer));
is_float_return = 1;
return_type = _JIT_APPLY_RETURN_TYPE_NFLOAT;
}
break;
@ -809,13 +817,30 @@ static void closure_handler(jit_closure_t closure, void *apply_args)
}
/* 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);
}
}
}

169
tools/gen-apply.c

@ -59,13 +59,20 @@ the "jit-apply-rules.h" file.
#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
@ -103,6 +110,8 @@ int floats_in_word_regs = 0;
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;
@ -138,6 +147,8 @@ int floats_in_word_regs = JIT_APPLY_FLOATS_IN_WORD_REGS;
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;
@ -789,9 +800,9 @@ void detect_float_return(void)
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;
@ -803,6 +814,7 @@ void detect_float_return(void)
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)
{
@ -819,86 +831,102 @@ void detect_float_return(void)
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;
@ -1487,8 +1515,7 @@ void dump_return_union(void)
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";
@ -1517,10 +1544,6 @@ void dump_return_union(void)
{
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");
@ -1530,12 +1553,30 @@ void dump_return_union(void)
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)
{
@ -1565,11 +1606,11 @@ void dump_return_union(void)
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");
@ -1592,13 +1633,13 @@ void dump_return_union(void)
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");
}
@ -2601,6 +2642,8 @@ int main(int argc, char *argv[])
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",

Loading…
Cancel
Save