From fa616418add27e0036ff2e762fa7b6b5e161a7b6 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 8 Dec 2008 17:07:50 +0100 Subject: [PATCH] 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 326a8380b53..45c75f7df05 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 3f2dcf214e5..31ef8a0d25d 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 bcbf9510be9..84281c51b6a 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 8f137d87fe5..39162fa6fa9 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 d13596812fc..2e8aa75a7f5 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 -- 2.11.4.GIT