From: Klaus Treichel Date: Mon, 26 May 2008 21:06:29 +0000 (+0000) Subject: Allow different float types at different offsets in the apply return struct. X-Git-Tag: before.move.to.git~69 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=44859d7672d774b6f961877fa3c459f654f44fd8;p=francis%2Flibjit.git Allow different float types at different offsets in the apply return struct. --- diff --git a/ChangeLog b/ChangeLog index 67f37e5..95476af 100644 --- a/ChangeLog +++ b/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 * include/jit/jit-defs.h.in: define JIT_EXPORT_DATA macro to support diff --git a/jit/jit-apply-func.h b/jit/jit-apply-func.h index 97bc95d..707e2af 100644 --- a/jit/jit-apply-func.h +++ b/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 /* diff --git a/jit/jit-apply-x86-64.h b/jit/jit-apply-x86-64.h index 1a5305b..cbcbfb5 100644 --- a/jit/jit-apply-x86-64.h +++ b/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" \ diff --git a/jit/jit-apply-x86.h b/jit/jit-apply-x86.h index 5dd2324..7ee461a 100644 --- a/jit/jit-apply-x86.h +++ b/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. diff --git a/jit/jit-apply.c b/jit/jit-apply.c index e05312f..91c8c67 100644 --- a/jit/jit-apply.c +++ b/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); + } } } diff --git a/tools/gen-apply.c b/tools/gen-apply.c index 9abd802..d8fc6d6 100644 --- a/tools/gen-apply.c +++ b/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",