Alexandre Julliard : winebuild: Make the cpu flag more generic to allow supporting a given entry point on multiple platforms .

Alexandre Julliard julliard at winehq.org
Tue Dec 9 06:23:57 CST 2008


Module: wine
Branch: master
Commit: fa616418add27e0036ff2e762fa7b6b5e161a7b6
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=fa616418add27e0036ff2e762fa7b6b5e161a7b6

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Dec  8 17:07:50 2008 +0100

winebuild: Make the cpu flag more generic to allow supporting a given entry point on multiple platforms.

---

 tools/winebuild/build.h          |   11 ++++++---
 tools/winebuild/main.c           |   26 +---------------------
 tools/winebuild/parser.c         |   43 +++++++++++++++++++++++++++++--------
 tools/winebuild/utils.c          |   26 +++++++++++++++++++++++
 tools/winebuild/winebuild.man.in |    6 ++--
 5 files changed, 71 insertions(+), 41 deletions(-)

diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h
index 326a838..45c75f7 100644
--- a/tools/winebuild/build.h
+++ b/tools/winebuild/build.h
@@ -127,14 +127,16 @@ extern enum target_platform target_platform;
 #define FLAG_NONAME    0x02  /* don't export function by name */
 #define FLAG_RET16     0x04  /* function returns a 16-bit value */
 #define FLAG_RET64     0x08  /* function returns a 64-bit value */
-#define FLAG_I386      0x10  /* function is i386 only */
-#define FLAG_REGISTER  0x20  /* use register calling convention */
-#define FLAG_PRIVATE   0x40  /* function is private (cannot be imported) */
-#define FLAG_ORDINAL   0x80  /* function should be imported by ordinal */
+#define FLAG_REGISTER  0x10  /* use register calling convention */
+#define FLAG_PRIVATE   0x20  /* function is private (cannot be imported) */
+#define FLAG_ORDINAL   0x40  /* function should be imported by ordinal */
 
 #define FLAG_FORWARD   0x100  /* function is a forwarded name */
 #define FLAG_EXT_LINK  0x200  /* function links to an external symbol */
 
+#define FLAG_CPU(cpu)  (0x01000 << (cpu))
+#define FLAG_CPU_MASK  0x1f000
+
 #define MAX_ORDINALS  65535
 
 /* global functions */
@@ -177,6 +179,7 @@ extern DLLSPEC *alloc_dll_spec(void);
 extern void free_dll_spec( DLLSPEC *spec );
 extern const char *make_c_identifier( const char *str );
 extern const char *get_stub_name( const ORDDEF *odp, const DLLSPEC *spec );
+extern enum target_cpu get_cpu_from_name( const char *name );
 extern unsigned int get_alignment(unsigned int align);
 extern unsigned int get_page_size(void);
 extern unsigned int get_ptr_size(void);
diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c
index 3f2dcf2..31ef8a0 100644
--- a/tools/winebuild/main.c
+++ b/tools/winebuild/main.c
@@ -104,23 +104,6 @@ static enum exec_mode_values exec_mode = MODE_NONE;
 static const struct
 {
     const char *name;
-    enum target_cpu cpu;
-} cpu_names[] =
-{
-    { "i386",    CPU_x86 },
-    { "i486",    CPU_x86 },
-    { "i586",    CPU_x86 },
-    { "i686",    CPU_x86 },
-    { "i786",    CPU_x86 },
-    { "x86_64",  CPU_x86_64 },
-    { "sparc",   CPU_SPARC },
-    { "alpha",   CPU_ALPHA },
-    { "powerpc", CPU_POWERPC }
-};
-
-static const struct
-{
-    const char *name;
     enum target_platform platform;
 } platform_names[] =
 {
@@ -182,13 +165,8 @@ static void set_target( const char *target )
 
     if (!(p = strchr( spec, '-' ))) fatal_error( "Invalid target specification '%s'\n", target );
     *p++ = 0;
-    for (i = 0; i < sizeof(cpu_names)/sizeof(cpu_names[0]); i++)
-    {
-        if (!strcmp( cpu_names[i].name, spec )) break;
-    }
-    if (i < sizeof(cpu_names)/sizeof(cpu_names[0])) target_cpu = cpu_names[i].cpu;
-    else fatal_error( "Unrecognized CPU '%s'\n", spec );
-
+    if ((target_cpu = get_cpu_from_name( spec )) == -1)
+        fatal_error( "Unrecognized CPU '%s'\n", spec );
     platform = p;
     if ((p = strrchr( p, '-' ))) platform = p + 1;
 
diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c
index bcbf951..84281c5 100644
--- a/tools/winebuild/parser.c
+++ b/tools/winebuild/parser.c
@@ -67,7 +67,6 @@ static const char * const FlagNames[] =
     "noname",      /* FLAG_NONAME */
     "ret16",       /* FLAG_RET16 */
     "ret64",       /* FLAG_RET64 */
-    "i386",        /* FLAG_I386 */
     "register",    /* FLAG_REGISTER */
     "private",     /* FLAG_PRIVATE */
     "ordinal",     /* FLAG_ORDINAL */
@@ -378,7 +377,7 @@ static int parse_spec_stub( ORDDEF *odp, DLLSPEC *spec )
 {
     odp->u.func.arg_types[0] = '\0';
     odp->link_name = xstrdup("");
-    odp->flags |= FLAG_I386;  /* don't bother generating stubs for Winelib */
+    odp->flags |= FLAG_CPU(CPU_x86); /* don't bother generating stubs for Winelib */
     return 1;
 }
 
@@ -428,14 +427,38 @@ static const char *parse_spec_flags( ORDDEF *odp )
     do
     {
         if (!(token = GetToken(0))) break;
-        for (i = 0; FlagNames[i]; i++)
-            if (!strcmp( FlagNames[i], token )) break;
-        if (!FlagNames[i])
+        if (!strncmp( token, "arch=", 5))
         {
-            error( "Unknown flag '%s'\n", token );
-            return NULL;
+            char *args = xstrdup( token + 5 );
+            char *cpu_name = strtok( args, "," );
+            while (cpu_name)
+            {
+                enum target_cpu cpu = get_cpu_from_name( cpu_name );
+                if (cpu == -1)
+                {
+                    error( "Unknown architecture '%s'\n", cpu_name );
+                    return NULL;
+                }
+                odp->flags |= FLAG_CPU( cpu );
+                cpu_name = strtok( NULL, "," );
+            }
+            free( args );
+        }
+        else if (!strcmp( token, "i386" ))  /* backwards compatibility */
+        {
+            odp->flags |= FLAG_CPU(CPU_x86);
+        }
+        else
+        {
+            for (i = 0; FlagNames[i]; i++)
+                if (!strcmp( FlagNames[i], token )) break;
+            if (!FlagNames[i])
+            {
+                error( "Unknown flag '%s'\n", token );
+                return NULL;
+            }
+            odp->flags |= 1 << i;
         }
-        odp->flags |= 1 << i;
         token = GetToken(0);
     } while (token && *token == '-');
 
@@ -506,9 +529,9 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec )
         assert( 0 );
     }
 
-    if ((target_cpu != CPU_x86) && (odp->flags & FLAG_I386))
+    if ((odp->flags & FLAG_CPU_MASK) && !(odp->flags & FLAG_CPU(target_cpu)))
     {
-        /* ignore this entry point on non-Intel archs */
+        /* ignore this entry point */
         spec->nb_entry_points--;
         return 1;
     }
diff --git a/tools/winebuild/utils.c b/tools/winebuild/utils.c
index 8f137d8..39162fa 100644
--- a/tools/winebuild/utils.c
+++ b/tools/winebuild/utils.c
@@ -39,6 +39,23 @@
 static const char *tmp_files[MAX_TMP_FILES];
 static unsigned int nb_tmp_files;
 
+static const struct
+{
+    const char *name;
+    enum target_cpu cpu;
+} cpu_names[] =
+{
+    { "i386",    CPU_x86 },
+    { "i486",    CPU_x86 },
+    { "i586",    CPU_x86 },
+    { "i686",    CPU_x86 },
+    { "i786",    CPU_x86 },
+    { "x86_64",  CPU_x86_64 },
+    { "sparc",   CPU_SPARC },
+    { "alpha",   CPU_ALPHA },
+    { "powerpc", CPU_POWERPC }
+};
+
 /* atexit handler to clean tmp files */
 static void cleanup_tmp_files(void)
 {
@@ -417,6 +434,15 @@ const char *get_stub_name( const ORDDEF *odp, const DLLSPEC *spec )
     return buffer;
 }
 
+/* parse a cpu name and return the corresponding value */
+enum target_cpu get_cpu_from_name( const char *name )
+{
+    unsigned int i;
+
+    for (i = 0; i < sizeof(cpu_names)/sizeof(cpu_names[0]); i++)
+        if (!strcmp( cpu_names[i].name, name )) return cpu_names[i].cpu;
+    return -1;
+}
 
 /*****************************************************************
  *  Function:    get_alignment
diff --git a/tools/winebuild/winebuild.man.in b/tools/winebuild/winebuild.man.in
index d135968..2e8aa75 100644
--- a/tools/winebuild/winebuild.man.in
+++ b/tools/winebuild/winebuild.man.in
@@ -269,9 +269,6 @@ The function returns a 16-bit value (Win16 only).
 .B -ret64
 The function returns a 64-bit value (Win32 only).
 .TP
-.B -i386
-The entry point is only available on i386 platforms.
-.TP
 .B -register
 The function uses CPU register to pass arguments.
 .TP
@@ -282,6 +279,9 @@ accessed through GetProcAddress.
 .B -ordinal
 The entry point will be imported by ordinal instead of by name. The
 name is still exported.
+.TP
+.BI -arch= cpu[,cpu]
+The entry point is only available on the specified CPU architecture(s).
 .SS "Function ordinals"
 Syntax:
 .br




More information about the wine-cvs mailing list