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

This commit is contained in:
Alexandre Julliard 2008-12-08 17:07:50 +01:00
parent 7fdadbb377
commit fa616418ad
5 changed files with 71 additions and 41 deletions

View File

@ -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);

View File

@ -101,23 +101,6 @@ enum exec_mode_values
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;
@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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