Commit 803c8d96 authored by Alexandre Julliard's avatar Alexandre Julliard

Beginnings of an infrastructure to allow specifying the target CPU and

platform at run-time.
parent 51bb3f60
......@@ -109,6 +109,19 @@ typedef struct
struct resource *resources; /* array of dll resources (format differs between Win16/Win32) */
} DLLSPEC;
enum target_cpu
{
CPU_x86, CPU_SPARC, CPU_ALPHA, CPU_POWERPC
};
enum target_platform
{
PLATFORM_UNSPECIFIED, PLATFORM_APPLE, PLATFORM_SVR4, PLATFORM_WINDOWS
};
extern enum target_cpu target_cpu;
extern enum target_platform target_platform;
/* entry point flags */
#define FLAG_NORELAY 0x01 /* don't use relay debugging for this function */
#define FLAG_NONAME 0x02 /* don't import function by name */
......@@ -166,7 +179,11 @@ extern int remove_stdcall_decoration( char *name );
extern DLLSPEC *alloc_dll_spec(void);
extern void free_dll_spec( DLLSPEC *spec );
extern const char *make_c_identifier( const char *str );
extern int get_alignment(int alignBoundary);
extern unsigned int get_alignment(unsigned int align);
extern unsigned int get_page_size(void);
extern const char *func_name( const char *func );
extern const char *func_declaration( const char *func );
extern const char *func_size( const char *func );
extern void add_import_dll( const char *name, const char *filename );
extern void add_delayed_import( const char *name );
......
......@@ -46,12 +46,28 @@ int nb_lib_paths = 0;
int nb_errors = 0;
int display_warnings = 0;
int kill_at = 0;
int debugging = 0;
/* we only support relay debugging on i386 */
#ifdef __i386__
int debugging = 1;
enum target_cpu target_cpu = CPU_x86;
#elif defined(__sparc__)
enum target_cpu target_cpu = CPU_SPARC;
#elif defined(__ALPHA__)
enum target_cpu target_cpu = CPU_ALPHA;
#elif defined(__powerpc__)
enum target_cpu target_cpu = CPU_POWERPC;
#else
int debugging = 0;
#error Unsupported CPU
#endif
#ifdef __APPLE__
enum target_platform target_platform = PLATFORM_APPLE;
#elif defined(__svr4__)
enum target_platform target_platform = PLATFORM_SVR4;
#elif defined(_WINDOWS)
enum target_platform target_platform = PLATFORM_WINDOWS;
#else
enum target_platform target_platform = PLATFORM_UNSPECIFIED;
#endif
char **debug_channels = NULL;
......@@ -447,6 +463,9 @@ int main(int argc, char **argv)
output_file = stdout;
argv = parse_options( argc, argv, spec );
/* we only support relay debugging on i386 */
debugging = (target_cpu == CPU_x86);
switch(exec_mode)
{
case MODE_DLL:
......
......@@ -487,14 +487,12 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec )
assert( 0 );
}
#ifndef __i386__
if (odp->flags & FLAG_I386)
if ((target_cpu != CPU_x86) && (odp->flags & FLAG_I386))
{
/* ignore this entry point on non-Intel archs */
spec->nb_entry_points--;
return 1;
}
#endif
if (ordinal != -1)
{
......
......@@ -32,12 +32,10 @@
#include "build.h"
#ifdef __i386__
static void function_header( FILE *outfile, const char *name )
{
fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
fprintf( outfile, "\t" __ASM_FUNC("%s") "\n", name );
fprintf( outfile, "\t%s\n", func_declaration(name) );
fprintf( outfile, "\t.globl " __ASM_NAME("%s") "\n", name );
fprintf( outfile, __ASM_NAME("%s") ":\n", name );
}
......@@ -45,9 +43,13 @@ static void function_header( FILE *outfile, const char *name )
static void function_footer( FILE *outfile, const char *name )
{
#ifdef HAVE_ASM_DOT_SIZE
fprintf( outfile, "\t.size " __ASM_NAME("%s") ", . - " __ASM_NAME("%s") "\n", name, name );
#endif
const char *size = func_size( name );
if (size[0]) fprintf( outfile, "\t%s\n", size );
}
static inline const char *data16_prefix(void)
{
return (target_platform == PLATFORM_SVR4) ? "\tdata16\n" : "";
}
/*******************************************************************
......@@ -157,14 +159,8 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int sho
fprintf( outfile, "\t.byte 0x2e\n\tmovl " __ASM_NAME("CallTo16_DataSelector") ",%%edx\n" );
/* Load 32-bit segment registers */
#ifdef __svr4__
fprintf( outfile, "\tdata16\n");
#endif
fprintf( outfile, "\tmovw %%dx, %%ds\n" );
#ifdef __svr4__
fprintf( outfile, "\tdata16\n");
#endif
fprintf( outfile, "\tmovw %%dx, %%es\n" );
fprintf( outfile, "%s\tmovw %%dx, %%ds\n", data16_prefix() );
fprintf( outfile, "%s\tmovw %%dx, %%es\n", data16_prefix() );
if ( UsePIC )
{
......@@ -198,10 +194,7 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk, int sho
fprintf( outfile, "\tpushl %%ebp\n" );
/* Switch stacks */
#ifdef __svr4__
fprintf( outfile,"\tdata16\n");
#endif
fprintf( outfile, "\t.byte 0x64\n\tmovw %%ss, (%d)\n", STACKOFFSET + 2 );
fprintf( outfile, "%s\t.byte 0x64\n\tmovw %%ss, (%d)\n", data16_prefix(), STACKOFFSET + 2 );
fprintf( outfile, "\t.byte 0x64\n\tmovw %%sp, (%d)\n", STACKOFFSET );
fprintf( outfile, "\tpushl %%ds\n" );
fprintf( outfile, "\tpopl %%ss\n" );
......@@ -548,10 +541,7 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func )
/* Switch to the 16-bit stack */
fprintf( outfile, "\tmovl %%esp,%%edx\n" );
#ifdef __svr4__
fprintf( outfile,"\tdata16\n");
#endif
fprintf( outfile, "\t.byte 0x64\n\tmovw (%d),%%ss\n", STACKOFFSET + 2);
fprintf( outfile, "%s\t.byte 0x64\n\tmovw (%d),%%ss\n", data16_prefix(), STACKOFFSET + 2);
fprintf( outfile, "\t.byte 0x64\n\tmovw (%d),%%sp\n", STACKOFFSET );
fprintf( outfile, "\t.byte 0x64\n\tmovl %%edx,(%d)\n", STACKOFFSET );
......@@ -629,14 +619,8 @@ static void BuildRet16Func( FILE *outfile )
/* Restore 32-bit segment registers */
fprintf( outfile, "\t.byte 0x2e\n\tmovl " __ASM_NAME("CallTo16_DataSelector") "-" __ASM_NAME("Call16_Ret_Start") ",%%edi\n" );
#ifdef __svr4__
fprintf( outfile, "\tdata16\n");
#endif
fprintf( outfile, "\tmovw %%di,%%ds\n" );
#ifdef __svr4__
fprintf( outfile, "\tdata16\n");
#endif
fprintf( outfile, "\tmovw %%di,%%es\n" );
fprintf( outfile, "%s\tmovw %%di,%%ds\n", data16_prefix() );
fprintf( outfile, "%s\tmovw %%di,%%es\n", data16_prefix() );
fprintf( outfile, "\t.byte 0x2e\n\tmov " __ASM_NAME("CallTo16_TebSelector") "-" __ASM_NAME("Call16_Ret_Start") ",%%fs\n" );
......@@ -644,10 +628,7 @@ static void BuildRet16Func( FILE *outfile )
/* Restore the 32-bit stack */
#ifdef __svr4__
fprintf( outfile, "\tdata16\n");
#endif
fprintf( outfile, "\tmovw %%di,%%ss\n" );
fprintf( outfile, "%s\tmovw %%di,%%ss\n", data16_prefix() );
fprintf( outfile, "\t.byte 0x64\n\tmovl (%d),%%esp\n", STACKOFFSET );
/* Return to caller */
......@@ -1141,6 +1122,12 @@ static void BuildPendingEventCheck( FILE *outfile )
*/
void BuildRelays16( FILE *outfile )
{
if (target_cpu != CPU_x86)
{
fprintf( outfile, "/* File not used with this architecture. Do not edit! */\n\n" );
return;
}
/* File header */
fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
......@@ -1211,6 +1198,12 @@ void BuildRelays16( FILE *outfile )
*/
void BuildRelays32( FILE *outfile )
{
if (target_cpu != CPU_x86)
{
fprintf( outfile, "/* File not used with this architecture. Do not edit! */\n\n" );
return;
}
/* File header */
fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
......@@ -1222,17 +1215,3 @@ void BuildRelays32( FILE *outfile )
function_footer( outfile, "__wine_spec_thunk_text_32" );
}
#else /* __i386__ */
void BuildRelays16( FILE *outfile )
{
fprintf( outfile, "/* File not used with this architecture. Do not edit! */\n\n" );
}
void BuildRelays32( FILE *outfile )
{
fprintf( outfile, "/* File not used with this architecture. Do not edit! */\n\n" );
}
#endif /* __i386__ */
......@@ -21,6 +21,7 @@
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
......@@ -339,81 +340,70 @@ const char *make_c_identifier( const char *str )
*
*
* Parameters:
* alignBoundary -- the number of bytes to align to.
* If we're on an architecture where
* the assembler requires a 'number
* of low-order zero bits' as a
* .align argument, then this number
* must be a power of 2.
*
* align -- the number of bytes to align to. Must be a power of 2.
*/
int get_alignment(int alignBoundary)
unsigned int get_alignment(unsigned int align)
{
#if defined(__powerpc__) || defined(__ALPHA__) || defined(__APPLE__)
unsigned int n;
int n = 0;
assert( !(align & (align - 1)) );
switch(alignBoundary)
switch(target_cpu)
{
case 2:
n = 1;
break;
case 4:
n = 2;
break;
case 8:
n = 3;
break;
case 16:
n = 4;
break;
case 32:
n = 5;
break;
case 64:
n = 6;
break;
case 128:
n = 7;
break;
case 256:
n = 8;
break;
case 512:
n = 9;
break;
case 1024:
n = 10;
break;
case 2048:
n = 11;
break;
case 4096:
n = 12;
break;
case 8192:
n = 13;
break;
case 16384:
n = 14;
break;
case 32768:
n = 15;
break;
case 65536:
n = 16;
break;
default:
fatal_error("Alignment to %d-byte boundary not supported on this architecture.\n",
alignBoundary);
case CPU_x86:
case CPU_SPARC:
if (target_platform != PLATFORM_APPLE) return align;
/* fall through */
case CPU_POWERPC:
case CPU_ALPHA:
n = 0;
while ((1 << n) != align) n++;
return n;
}
return n;
/* unreached */
assert(0);
return 0;
}
#elif defined(__i386__) || defined(__sparc__)
/* return the page size for the target CPU */
unsigned int get_page_size(void)
{
switch(target_cpu)
{
case CPU_x86: return 4096;
case CPU_POWERPC: return 4096;
case CPU_SPARC: return 8192;
case CPU_ALPHA: return 8192;
}
/* unreached */
assert(0);
return 0;
}
/* return the assembly name for a C function name */
const char *func_name( const char *func )
{
static char buffer[256];
sprintf( buffer, __ASM_NAME("%s"), func );
return buffer;
}
return alignBoundary;
/* return an assembly function declaration for a C function name */
const char *func_declaration( const char *func )
{
static char buffer[256];
sprintf( buffer, __ASM_FUNC("%s"), func );
return buffer;
}
/* return a size declaration for an assembly function */
const char *func_size( const char *func )
{
#ifdef HAVE_ASM_DOT_SIZE
static char buffer[256];
sprintf( buffer, ".size " __ASM_NAME("%s") ", .-" __ASM_NAME("%s"), func, func );
return buffer;
#else
#error "How does the '.align' assembler directive work on your architecture?"
return "";
#endif
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment