]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Allow different float types at different offsets in the apply return struct.
authorKlaus Treichel <ktreichel@web.de>
Mon, 26 May 2008 21:06:29 +0000 (21:06 +0000)
committerKlaus Treichel <ktreichel@web.de>
Mon, 26 May 2008 21:06:29 +0000 (21:06 +0000)
ChangeLog
jit/jit-apply-func.h
jit/jit-apply-x86-64.h
jit/jit-apply-x86.h
jit/jit-apply.c
tools/gen-apply.c

index 67f37e5cfc82d1d3a38372dd5088a572c5062b6b..95476af3fd9cce5f49c52ed8594a26d5e04204c0 100644 (file)
--- 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  <juanj.g_soria@grupobbva.com>
 
        * include/jit/jit-defs.h.in: define JIT_EXPORT_DATA macro to support
index 97bc95d89bac5882f357a4872bfe39d588b68994..707e2af1c5b820ff10c10e2396a1d33f2e22e229 100644 (file)
                        __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
 
 /*
index 1a5305bff824f9829299e907f9888c692c2a1762..cbcbfb5458c85a5933563afb98ffa46c7b3449e4 100644 (file)
@@ -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" \
index 5dd2324daef0dce971e7d544d7b6761cd24cfaee..7ee461a157752d042947256126c2864585caf108 100644 (file)
                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__ ( \
                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__ ( \
                        { \
                                __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 \
                                } \
                        } \
 
 #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 \
 
 #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.
index e05312f4eb02e6b1530a7273ccf02fd2299234e7..91c8c67bbada59a01f0cf4d4b7b81563bd5dfa38 100644 (file)
@@ -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);
+               }
        }
 }
 
index 9abd802aca8d9366d101cdf291d0a7740740d45c..d8fc6d6ded6b0eab8e18427278b50d051d401da5 100644 (file)
@@ -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",