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