Author: cwittich
Date: Tue Jan 20 05:44:30 2009
New Revision: 38972
URL:
http://svn.reactos.org/svn/reactos?rev=38972&view=rev
Log:
sync winebuild with wine 1.1.13
Modified:
trunk/reactos/tools/winebuild/build.h
trunk/reactos/tools/winebuild/import.c
trunk/reactos/tools/winebuild/main.c
trunk/reactos/tools/winebuild/parser.c
trunk/reactos/tools/winebuild/relay.c
trunk/reactos/tools/winebuild/spec32.c
trunk/reactos/tools/winebuild/utils.c
Modified: trunk/reactos/tools/winebuild/build.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/winebuild/build.h?re…
==============================================================================
--- trunk/reactos/tools/winebuild/build.h [iso-8859-1] (original)
+++ trunk/reactos/tools/winebuild/build.h [iso-8859-1] Tue Jan 20 05:44:30 2009
@@ -128,13 +128,15 @@
#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
@@ -178,6 +180,7 @@
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);
@@ -230,6 +233,7 @@
extern int verbose;
extern int save_temps;
extern int link_ext_symbols;
+extern int force_pointer_size;
extern char *input_file_name;
extern char *spec_file_name;
Modified: trunk/reactos/tools/winebuild/import.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/winebuild/import.c?r…
==============================================================================
--- trunk/reactos/tools/winebuild/import.c [iso-8859-1] (original)
+++ trunk/reactos/tools/winebuild/import.c [iso-8859-1] Tue Jan 20 05:44:30 2009
@@ -970,22 +970,22 @@
output( "\tjmp *%%eax\n" );
break;
case CPU_x86_64:
- output( "\tpushq %%rdi\n" );
- output( "\tpushq %%rsi\n" );
output( "\tpushq %%rdx\n" );
output( "\tpushq %%rcx\n" );
output( "\tpushq %%r8\n" );
output( "\tpushq %%r9\n" );
- output( "\tsubq $8,%%rsp\n" );
- output( "\tmovq %%r11,%%rdi\n" );
+ output( "\tpushq %%r10\n" );
+ output( "\tpushq %%r11\n" );
+ output( "\tsubq $40,%%rsp\n" );
+ output( "\tmovq %%rax,%%rcx\n" );
output( "\tcall %s\n", asm_name("__wine_spec_delay_load") );
- output( "\taddq $8,%%rsp\n" );
+ output( "\taddq $40,%%rsp\n" );
+ output( "\tpopq %%r11\n" );
+ output( "\tpopq %%r10\n" );
output( "\tpopq %%r9\n" );
output( "\tpopq %%r8\n" );
output( "\tpopq %%rcx\n" );
output( "\tpopq %%rdx\n" );
- output( "\tpopq %%rsi\n" );
- output( "\tpopq %%rdi\n" );
output( "\tjmp *%%rax\n" );
break;
case CPU_SPARC:
@@ -1068,7 +1068,7 @@
output( "\tjmp %s\n",
asm_name("__wine_delay_load_asm") );
break;
case CPU_x86_64:
- output( "\tmovq $%d,%%r11\n", (idx << 16) | j );
+ output( "\tmovq $%d,%%rax\n", (idx << 16) | j );
output( "\tjmp %s\n",
asm_name("__wine_delay_load_asm") );
break;
case CPU_SPARC:
@@ -1191,45 +1191,64 @@
output( "\t%s\n", func_declaration(name) );
output( "%s:\n", asm_name(name) );
- /* flesh out the stub a bit to make safedisc happy */
- output(" \tnop\n" );
- output(" \tnop\n" );
- output(" \tnop\n" );
- output(" \tnop\n" );
- output(" \tnop\n" );
- output(" \tnop\n" );
- output(" \tnop\n" );
- output(" \tnop\n" );
- output(" \tnop\n" );
-
- output( "\tsubl $4,%%esp\n" );
- if (UsePIC)
- {
- output( "\tcall %s\n",
asm_name("__wine_spec_get_pc_thunk_eax") );
- output( "1:" );
+ switch (target_cpu)
+ {
+ case CPU_x86:
+ /* flesh out the stub a bit to make safedisc happy */
+ output(" \tnop\n" );
+ output(" \tnop\n" );
+ output(" \tnop\n" );
+ output(" \tnop\n" );
+ output(" \tnop\n" );
+ output(" \tnop\n" );
+ output(" \tnop\n" );
+ output(" \tnop\n" );
+ output(" \tnop\n" );
+
+ output( "\tsubl $4,%%esp\n" );
+ if (UsePIC)
+ {
+ output( "\tcall %s\n",
asm_name("__wine_spec_get_pc_thunk_eax") );
+ output( "1:" );
+ if (exp_name)
+ {
+ output( "\tleal .L%s_string-1b(%%eax),%%ecx\n", name );
+ output( "\tpushl %%ecx\n" );
+ count++;
+ }
+ else
+ output( "\tpushl $%d\n", odp->ordinal );
+ output( "\tleal .L__wine_spec_file_name-1b(%%eax),%%ecx\n" );
+ output( "\tpushl %%ecx\n" );
+ }
+ else
+ {
+ if (exp_name)
+ {
+ output( "\tpushl $.L%s_string\n", name );
+ count++;
+ }
+ else
+ output( "\tpushl $%d\n", odp->ordinal );
+ output( "\tpushl $.L__wine_spec_file_name\n" );
+ }
+ output( "\tcall %s\n",
asm_name("__wine_spec_unimplemented_stub") );
+ break;
+ case CPU_x86_64:
+ output( "\tleaq .L__wine_spec_file_name(%%rip),%%rdi\n" );
if (exp_name)
{
- output( "\tleal .L%s_string-1b(%%eax),%%ecx\n", name );
- output( "\tpushl %%ecx\n" );
+ output( "leaq .L%s_string(%%rip),%%rsi\n", name );
count++;
}
else
- output( "\tpushl $%d\n", odp->ordinal );
- output( "\tleal .L__wine_spec_file_name-1b(%%eax),%%ecx\n" );
- output( "\tpushl %%ecx\n" );
- }
- else
- {
- if (exp_name)
- {
- output( "\tpushl $.L%s_string\n", name );
- count++;
- }
- else
- output( "\tpushl $%d\n", odp->ordinal );
- output( "\tpushl $.L__wine_spec_file_name\n" );
- }
- output( "\tcall %s\n",
asm_name("__wine_spec_unimplemented_stub") );
+ output( "\tmovq $%d,%%rsi\n", odp->ordinal );
+ output( "\tsubq $8,%%rsp\n" );
+ output( "\tcall %s\n",
asm_name("__wine_spec_unimplemented_stub") );
+ break;
+ default:
+ assert(0);
+ }
output_function_size( name );
}
Modified: trunk/reactos/tools/winebuild/main.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/winebuild/main.c?rev…
==============================================================================
--- trunk/reactos/tools/winebuild/main.c [iso-8859-1] (original)
+++ trunk/reactos/tools/winebuild/main.c [iso-8859-1] Tue Jan 20 05:44:30 2009
@@ -47,6 +47,7 @@
int verbose = 0;
int save_temps = 0;
int link_ext_symbols = 0;
+int force_pointer_size = 0;
#if defined(TARGET_i386)
enum target_cpu target_cpu = CPU_x86;
@@ -98,23 +99,6 @@
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[] =
{
@@ -176,13 +160,8 @@
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;
@@ -239,6 +218,7 @@
"Usage: winebuild [OPTIONS] [FILES]\n\n"
"Options:\n"
" --as-cmd=AS Command to use for assembling (default: as)\n"
+" -b, --target=TARGET Specify target CPU and platform for
cross-compiling\n"
" -d, --delay-lib=LIB Import the specified library in delayed mode\n"
" -D SYM Ignored for C flags compatibility\n"
" -e, --entry=FUNC Set the DLL entry point function (default:
DllMain)\n"
@@ -255,6 +235,7 @@
" --ld-cmd=LD Command to use for linking (default: ld)\n"
" -l, --library=LIB Import the specified library\n"
" -L, --library-path=DIR Look for imports libraries in DIR\n"
+" -m32, -m64 Force building 32-bit resp. 64-bit code\n"
" -M, --main-module=MODULE Set the name of the main module for a Win16
dll\n"
" --nm-cmd=NM Command to use to get undefined symbols (default:
nm)\n"
" --nxcompat=y|n Set the NX compatibility flag (default: yes)\n"
@@ -263,7 +244,6 @@
" -r, --res=RSRC.RES Load resources from RSRC.RES\n"
" --save-temps Do not delete the generated intermediate files\n"
" --subsystem=SUBSYS Set the subsystem (one of native, windows,
console)\n"
-" --target=TARGET Specify target CPU and platform for
cross-compiling\n"
" -u, --undefined=SYMBOL Add an undefined reference to SYMBOL when
linking\n"
" -v, --verbose Display the programs invoked\n"
" --version Print the version and exit\n"
@@ -291,12 +271,11 @@
LONG_OPT_RELAY32,
LONG_OPT_SAVE_TEMPS,
LONG_OPT_SUBSYSTEM,
- LONG_OPT_TARGET,
LONG_OPT_VERSION,
LONG_OPT_PEDLL
};
-static const char short_options[] =
"C:D:E:F:H:I:K:L:M:N:d:e:f:hi:kl:m:o:r:u:vw";
+static const char short_options[] =
"C:D:E:F:H:I:K:L:M:N:b:d:e:f:hi:kl:m:o:r:u:vw";
static const struct option long_options[] =
{
@@ -312,10 +291,10 @@
{ "relay32", 0, 0, LONG_OPT_RELAY32 },
{ "save-temps", 0, 0, LONG_OPT_SAVE_TEMPS },
{ "subsystem", 1, 0, LONG_OPT_SUBSYSTEM },
- { "target", 1, 0, LONG_OPT_TARGET },
{ "version", 0, 0, LONG_OPT_VERSION },
{ "pedll", 1, 0, LONG_OPT_PEDLL },
/* aliases for short options */
+ { "target", 1, 0, 'b' },
{ "delay-lib", 1, 0, 'd' },
{ "export", 1, 0, 'E' },
{ "entry", 1, 0, 'e' },
@@ -385,11 +364,20 @@
lib_path = xrealloc( lib_path, (nb_lib_paths+1) * sizeof(*lib_path) );
lib_path[nb_lib_paths++] = xstrdup( optarg );
break;
+ case 'm':
+ if (strcmp( optarg, "32" ) && strcmp( optarg,
"64" ))
+ fatal_error( "Invalid -m option '%s', expected -m32 or
-m64\n", optarg );
+ if (!strcmp( optarg, "32" )) force_pointer_size = 4;
+ else force_pointer_size = 8;
+ break;
case 'M':
spec->type = SPEC_WIN16;
break;
case 'N':
spec->dll_name = xstrdup( optarg );
+ break;
+ case 'b':
+ set_target( optarg );
break;
case 'd':
add_delayed_import( optarg );
@@ -495,9 +483,6 @@
case LONG_OPT_SUBSYSTEM:
set_subsystem( optarg, spec );
break;
- case LONG_OPT_TARGET:
- set_target( optarg );
- break;
case LONG_OPT_VERSION:
printf( "winebuild version " PACKAGE_VERSION "\n" );
exit(0);
@@ -514,6 +499,20 @@
if (spec->file_name && !strchr( spec->file_name, '.' ))
strcat( spec->file_name, exec_mode == MODE_EXE ? ".exe" :
".dll" );
+
+ switch (target_cpu)
+ {
+ case CPU_x86:
+ if (force_pointer_size == 8) target_cpu = CPU_x86_64;
+ break;
+ case CPU_x86_64:
+ if (force_pointer_size == 4) target_cpu = CPU_x86;
+ break;
+ default:
+ if (force_pointer_size == 8)
+ fatal_error( "Cannot build 64-bit code for this CPU\n" );
+ break;
+ }
return &argv[optind];
}
Modified: trunk/reactos/tools/winebuild/parser.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/winebuild/parser.c?r…
==============================================================================
--- trunk/reactos/tools/winebuild/parser.c [iso-8859-1] (original)
+++ trunk/reactos/tools/winebuild/parser.c [iso-8859-1] Tue Jan 20 05:44:30 2009
@@ -67,7 +67,6 @@
"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 @@
{
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) | FLAG_CPU(CPU_x86_64); /* don't bother
generating stubs for Winelib */
return 1;
}
@@ -428,14 +427,38 @@
do
{
if (!(token = GetToken(0))) break;
- 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;
+ if (!strncmp( token, "arch=", 5))
+ {
+ 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;
+ }
token = GetToken(0);
} while (token && *token == '-');
@@ -507,9 +530,9 @@
assert( 0 );
}
- if ((target_cpu != CPU_x86) && (odp->flags & FLAG_I386))
- {
- /* ignore this entry point on non-Intel archs */
+ if ((odp->flags & FLAG_CPU_MASK) && !(odp->flags &
FLAG_CPU(target_cpu)))
+ {
+ /* ignore this entry point */
spec->nb_entry_points--;
return 1;
}
Modified: trunk/reactos/tools/winebuild/relay.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/winebuild/relay.c?re…
==============================================================================
--- trunk/reactos/tools/winebuild/relay.c [iso-8859-1] (original)
+++ trunk/reactos/tools/winebuild/relay.c [iso-8859-1] Tue Jan 20 05:44:30 2009
@@ -741,9 +741,10 @@
*
* Stack layout:
* ...
- * (ebp+16) first arg
- * (ebp+12) ret addr to user code
- * (ebp+8) eax saved by relay code
+ * (ebp+20) first arg
+ * (ebp+16) ret addr to user code
+ * (ebp+12) func to call (relative to relay code ret addr)
+ * (ebp+8) number of args
* (ebp+4) ret addr to relay code
* (ebp+0) saved ebp
* (ebp-128) buffer area to allow stack frame manipulation
@@ -770,17 +771,16 @@
output( "\tpushl %%ebp\n" );
output( "\tmovl %%esp,%%ebp\n ");
- output( "\tleal -%d(%%esp), %%esp\n", STACK_SPACE + 4 /* for context arg
*/);
+ output( "\tleal -%d(%%esp),%%esp\n", STACK_SPACE );
/* Build the context structure */
+ output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(Eax) - STACK_SPACE );
output( "\tpushfl\n" );
output( "\tpopl %%eax\n" );
output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(EFlags) - STACK_SPACE );
output( "\tmovl 0(%%ebp),%%eax\n" );
output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(Ebp) - STACK_SPACE );
- output( "\tmovl 8(%%ebp),%%eax\n" );
- output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(Eax) - STACK_SPACE );
output( "\tmovl %%ebx,%d(%%ebp)\n", CONTEXTOFFSET(Ebx) - STACK_SPACE );
output( "\tmovl %%ecx,%d(%%ebp)\n", CONTEXTOFFSET(Ecx) - STACK_SPACE );
output( "\tmovl %%edx,%d(%%ebp)\n", CONTEXTOFFSET(Edx) - STACK_SPACE );
@@ -805,31 +805,30 @@
output( "\tmovl $0x%x,%%eax\n", CONTEXT86_FULL );
output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(ContextFlags) -
STACK_SPACE );
- output( "\tmovl 12(%%ebp),%%eax\n" ); /* Get %eip at time of call */
+ output( "\tmovl 16(%%ebp),%%eax\n" ); /* Get %eip at time of call */
output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(Eip) - STACK_SPACE );
/* Transfer the arguments */
- output( "\tmovl 4(%%ebp),%%ebx\n" ); /* get relay code addr */
- output( "\tmovzbl 4(%%ebx),%%ecx\n" ); /* fetch number of args to copy */
- output( "\tsubl %%ecx,%%esp\n" );
+ output( "\tmovl 8(%%ebp),%%ecx\n" ); /* fetch number of args to copy */
+ output( "\tleal 4(,%%ecx,4),%%edx\n" ); /* add 4 for context arg */
+ output( "\tsubl %%edx,%%esp\n" );
output( "\tandl $~15,%%esp\n" );
- output( "\tleal 16(%%ebp),%%esi\n" ); /* get %esp at time of call */
+ output( "\tleal 20(%%ebp),%%esi\n" ); /* get %esp at time of call */
output( "\tmovl %%esp,%%edi\n" );
- output( "\tshrl $2,%%ecx\n" );
+ output( "\ttest %%ecx,%%ecx\n" );
output( "\tjz 1f\n" );
output( "\tcld\n" );
output( "\trep\n\tmovsl\n" ); /* copy args */
output( "1:\tleal %d(%%ebp),%%eax\n", -STACK_SPACE ); /* get addr of
context struct */
output( "\tmovl %%eax,(%%edi)\n" ); /* and pass it as extra arg */
- output( "\tmovzbl 5(%%ebx),%%eax\n" ); /* fetch number of args to remove
*/
- output( "\tleal 16(%%ebp,%%eax),%%eax\n" );
- output( "\tmovl %%eax,%d(%%ebp)\n", CONTEXTOFFSET(Esp) - STACK_SPACE );
+ output( "\tmovl %%esi,%d(%%ebp)\n", CONTEXTOFFSET(Esp) - STACK_SPACE );
/* Call the entry point */
- output( "\taddl (%%ebx),%%ebx\n" );
- output( "\tcall *%%ebx\n" );
+ output( "\tmovl 4(%%ebp),%%eax\n" ); /* get relay code addr */
+ output( "\taddl 12(%%ebp),%%eax\n" );
+ output( "\tcall *%%eax\n" );
output( "\tleal -%d(%%ebp),%%ecx\n", STACK_SPACE );
/* Restore the context structure */
@@ -975,8 +974,181 @@
output( "%s\n\t.long 0\n", asm_globl("CallTo16_DataSelector") );
output( "%s\n\t.long 0\n", asm_globl("CallTo16_TebSelector") );
if (UsePIC) output( "wine_ldt_copy_ptr:\t.long %s\n",
asm_name("wine_ldt_copy") );
+
+ output( "\t.text\n" );
+ output( "%s:\n\n", asm_name("__wine_spec_thunk_text_32") );
+ BuildCallFrom32Regs();
+ output_function_size( "__wine_spec_thunk_text_32" );
+
output_gnu_stack_note();
}
+
+
+/*******************************************************************
+ * build_call_from_regs_x86_64
+ *
+ * Build the register saving code for a 'register' entry point.
+ *
+ * Stack layout:
+ * ...
+ * (rsp+16) first arg
+ * (rsp+8) ret addr to user code
+ * (rsp) ret addr to relay code
+ * (rsp-128) buffer area to allow stack frame manipulation
+ *
+ * Parameters:
+ * %rcx number of args
+ * %rdx entry point
+ */
+static void build_call_from_regs_x86_64(void)
+{
+ static const int STACK_SPACE = 128 + 0x4d0; /* size of x86_64 context */
+
+ /* Function header */
+
+ function_header( "__wine_call_from_regs" );
+
+ output( "\tsubq $%u,%%rsp\n", STACK_SPACE );
+
+ /* save registers into the context */
+
+ output( "\tmovq %%rax,0x78(%%rsp)\n" );
+ output( "\tmovq %u(%%rsp),%%rax\n", STACK_SPACE + 16 ); /* saved %rcx on
stack */
+ output( "\tmovq %%rax,0x80(%%rsp)\n" );
+ output( "\tmovq %u(%%rsp),%%rax\n", STACK_SPACE + 24 ); /* saved %rdx on
stack */
+ output( "\tmovq %%rax,0x88(%%rsp)\n" );
+ output( "\tmovq %%rbx,0x90(%%rsp)\n" );
+ output( "\tleaq %u(%%rsp),%%rax\n", STACK_SPACE + 16 );
+ output( "\tmovq %%rax,0x98(%%rsp)\n" );
+ output( "\tmovq %%rbp,0xa0(%%rsp)\n" );
+ output( "\tmovq %%rsi,0xa8(%%rsp)\n" );
+ output( "\tmovq %%rdi,0xb0(%%rsp)\n" );
+ output( "\tmovq %%r8,0xb8(%%rsp)\n" );
+ output( "\tmovq %%r9,0xc0(%%rsp)\n" );
+ output( "\tmovq %%r10,0xc8(%%rsp)\n" );
+ output( "\tmovq %%r11,0xd0(%%rsp)\n" );
+ output( "\tmovq %%r12,0xd8(%%rsp)\n" );
+ output( "\tmovq %%r13,0xe0(%%rsp)\n" );
+ output( "\tmovq %%r14,0xe8(%%rsp)\n" );
+ output( "\tmovq %%r15,0xf0(%%rsp)\n" );
+ output( "\tmovq %u(%%rsp),%%rax\n", STACK_SPACE + 8 );
+ output( "\tmovq %%rax,0xf8(%%rsp)\n" );
+
+ output( "\tstmxcsr 0x34(%%rsp)\n" );
+ output( "\tfxsave 0x100(%%rsp)\n" );
+ output( "\tmovdqa %%xmm0,0x1a0(%%rsp)\n" );
+ output( "\tmovdqa %%xmm1,0x1b0(%%rsp)\n" );
+ output( "\tmovdqa %%xmm2,0x1c0(%%rsp)\n" );
+ output( "\tmovdqa %%xmm3,0x1d0(%%rsp)\n" );
+ output( "\tmovdqa %%xmm4,0x1e0(%%rsp)\n" );
+ output( "\tmovdqa %%xmm5,0x1f0(%%rsp)\n" );
+ output( "\tmovdqa %%xmm6,0x200(%%rsp)\n" );
+ output( "\tmovdqa %%xmm7,0x210(%%rsp)\n" );
+ output( "\tmovdqa %%xmm8,0x220(%%rsp)\n" );
+ output( "\tmovdqa %%xmm9,0x230(%%rsp)\n" );
+ output( "\tmovdqa %%xmm10,0x240(%%rsp)\n" );
+ output( "\tmovdqa %%xmm11,0x250(%%rsp)\n" );
+ output( "\tmovdqa %%xmm12,0x260(%%rsp)\n" );
+ output( "\tmovdqa %%xmm13,0x270(%%rsp)\n" );
+ output( "\tmovdqa %%xmm14,0x280(%%rsp)\n" );
+ output( "\tmovdqa %%xmm15,0x290(%%rsp)\n" );
+
+ output( "\tmovw %%cs,0x38(%%rsp)\n" );
+ output( "\tmovw %%ds,0x3a(%%rsp)\n" );
+ output( "\tmovw %%es,0x3c(%%rsp)\n" );
+ output( "\tmovw %%fs,0x3e(%%rsp)\n" );
+ output( "\tmovw %%gs,0x40(%%rsp)\n" );
+ output( "\tmovw %%ss,0x42(%%rsp)\n" );
+ output( "\tpushfq\n" );
+ output( "\tpopq %%rax\n" );
+ output( "\tmovl %%eax,0x44(%%rsp)\n" );
+
+ output( "\tmovl $0x%x,0x30(%%rsp)\n", 0x0010000f );
+
+ /* transfer the arguments */
+
+ output( "\tmovq %%r8,%u(%%rsp)\n", STACK_SPACE + 32 );
+ output( "\tmovq %%r9,%u(%%rsp)\n", STACK_SPACE + 40 );
+ output( "\tmovq $4,%%rax\n" );
+ output( "\tleaq %u(%%rsp),%%rsi\n", STACK_SPACE + 16 );
+ output( "\tcmpq %%rax,%%rcx\n" );
+ output( "\tcmovgq %%rcx,%%rax\n" );
+ output( "\tmovq %%rsp,%%rbx\n" );
+ output( "\tleaq 16(,%%rax,8),%%rax\n" ); /* add 8 for context arg and 8
for rounding */
+ output( "\tandq $~15,%%rax\n" );
+ output( "\tsubq %%rax,%%rsp\n" );
+ output( "\tmovq %%rsp,%%rdi\n" );
+ output( "\tjrcxz 1f\n" );
+ output( "\tcld\n" );
+ output( "\trep\n\tmovsq\n" );
+ output( "1:\tmovq %%rbx,0(%%rdi)\n" ); /* context arg */
+
+ /* call the entry point */
+
+ output( "\tmovq %%rdx,%%rax\n" );
+ output( "\tmovq 0(%%rsp),%%rcx\n" );
+ output( "\tmovq 8(%%rsp),%%rdx\n" );
+ output( "\tmovq 16(%%rsp),%%r8\n" );
+ output( "\tmovq 24(%%rsp),%%r9\n" );
+ output( "\tcallq *%%rax\n" );
+
+ /* restore the context structure */
+
+ output( "1:\tmovq 0x80(%%rbx),%%rcx\n" );
+ output( "\tmovq 0x88(%%rbx),%%rdx\n" );
+ output( "\tmovq 0xa0(%%rbx),%%rbp\n" );
+ output( "\tmovq 0xa8(%%rbx),%%rsi\n" );
+ output( "\tmovq 0xb0(%%rbx),%%rdi\n" );
+ output( "\tmovq 0xb8(%%rbx),%%r8\n" );
+ output( "\tmovq 0xc0(%%rbx),%%r9\n" );
+ output( "\tmovq 0xc8(%%rbx),%%r10\n" );
+ output( "\tmovq 0xd0(%%rbx),%%r11\n" );
+ output( "\tmovq 0xd8(%%rbx),%%r12\n" );
+ output( "\tmovq 0xe0(%%rbx),%%r13\n" );
+ output( "\tmovq 0xe8(%%rbx),%%r14\n" );
+ output( "\tmovq 0xf0(%%rbx),%%r15\n" );
+
+ output( "\tmovdqa 0x1a0(%%rbx),%%xmm0\n" );
+ output( "\tmovdqa 0x1b0(%%rbx),%%xmm1\n" );
+ output( "\tmovdqa 0x1c0(%%rbx),%%xmm2\n" );
+ output( "\tmovdqa 0x1d0(%%rbx),%%xmm3\n" );
+ output( "\tmovdqa 0x1e0(%%rbx),%%xmm4\n" );
+ output( "\tmovdqa 0x1f0(%%rbx),%%xmm5\n" );
+ output( "\tmovdqa 0x200(%%rbx),%%xmm6\n" );
+ output( "\tmovdqa 0x210(%%rbx),%%xmm7\n" );
+ output( "\tmovdqa 0x220(%%rbx),%%xmm8\n" );
+ output( "\tmovdqa 0x230(%%rbx),%%xmm9\n" );
+ output( "\tmovdqa 0x240(%%rbx),%%xmm10\n" );
+ output( "\tmovdqa 0x250(%%rbx),%%xmm11\n" );
+ output( "\tmovdqa 0x260(%%rbx),%%xmm12\n" );
+ output( "\tmovdqa 0x270(%%rbx),%%xmm13\n" );
+ output( "\tmovdqa 0x280(%%rbx),%%xmm14\n" );
+ output( "\tmovdqa 0x290(%%rbx),%%xmm15\n" );
+ output( "\tfxrstor 0x100(%%rbx)\n" );
+ output( "\tldmxcsr 0x34(%%rbx)\n" );
+
+ output( "\tmovl 0x44(%%rbx),%%eax\n" );
+ output( "\tpushq %%rax\n" );
+ output( "\tpopfq\n" );
+
+ output( "\tmovq 0x98(%%rbx),%%rax\n" ); /* stack pointer */
+ output( "\tpushq 0xf8(%%rbx)\n" ); /* return address */
+ output( "\tpopq -8(%%rax)\n" );
+ output( "\tpushq 0x78(%%rbx)\n" ); /* rax */
+ output( "\tpopq -16(%%rax)\n" );
+ output( "\tmovq 0x90(%%rbx),%%rbx\n" );
+ output( "\tleaq -16(%%rax),%%rsp\n" );
+ output( "\tpopq %%rax\n" );
+ output( "\tret\n" );
+
+ output_function_size( "__wine_call_from_regs" );
+
+ function_header( "__wine_restore_regs" );
+ output( "\tmovq %%rcx,%%rbx\n" );
+ output( "\tjmp 1b\n" );
+ output_function_size( "__wine_restore_regs" );
+}
+
/*******************************************************************
* BuildRelays32
@@ -985,21 +1157,29 @@
*/
void BuildRelays32(void)
{
- if (target_cpu != CPU_x86)
- {
+ switch (target_cpu)
+ {
+ case CPU_x86:
+ output( "/* File generated automatically. Do not edit! */\n\n" );
+ output( "\t.text\n" );
+ output( "%s:\n\n", asm_name("__wine_spec_thunk_text_32") );
+
+ /* 32-bit register entry point */
+ BuildCallFrom32Regs();
+
+ output_function_size( "__wine_spec_thunk_text_32" );
+ output_gnu_stack_note();
+ break;
+
+ case CPU_x86_64:
+ output( "/* File generated automatically. Do not edit! */\n\n" );
+ output( "\t.text\n" );
+ build_call_from_regs_x86_64();
+ output_gnu_stack_note();
+ break;
+
+ default:
output( "/* File not used with this architecture. Do not edit! */\n\n"
);
return;
}
-
- /* File header */
-
- output( "/* File generated automatically. Do not edit! */\n\n" );
- output( "\t.text\n" );
- output( "%s:\n\n", asm_name("__wine_spec_thunk_text_32") );
-
- /* 32-bit register entry point */
- BuildCallFrom32Regs();
-
- output_function_size( "__wine_spec_thunk_text_32" );
- output_gnu_stack_note();
}
Modified: trunk/reactos/tools/winebuild/spec32.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/winebuild/spec32.c?r…
==============================================================================
--- trunk/reactos/tools/winebuild/spec32.c [iso-8859-1] (original)
+++ trunk/reactos/tools/winebuild/spec32.c [iso-8859-1] Tue Jan 20 05:44:30 2009
@@ -52,7 +52,7 @@
{
int i;
- if (target_cpu != CPU_x86) return 0;
+ if (target_cpu != CPU_x86 && target_cpu != CPU_x86_64) return 0;
for (i = spec->base; i <= spec->limit; i++)
{
@@ -146,36 +146,58 @@
output( "\t.align %d\n", get_alignment(4) );
output( ".L__wine_spec_relay_entry_point_%d:\n", i );
- if (odp->flags & FLAG_REGISTER)
- output( "\tpushl %%eax\n" );
- else
- output( "\tpushl %%esp\n" );
-
args = strlen(odp->u.func.arg_types);
flags = 0;
- if (odp->flags & FLAG_RET64) flags |= 1;
- if (odp->type == TYPE_STDCALL) flags |= 2;
- output( "\tpushl $%u\n", (flags << 24) | (args << 16) | (i
- spec->base) );
-
- if (UsePIC)
- {
- output( "\tcall %s\n",
asm_name("__wine_spec_get_pc_thunk_eax") );
- output( "1:\tleal .L__wine_spec_relay_descr-1b(%%eax),%%eax\n" );
- }
- else output( "\tmovl $.L__wine_spec_relay_descr,%%eax\n" );
- output( "\tpushl %%eax\n" );
-
- if (odp->flags & FLAG_REGISTER)
- {
- output( "\tcall *8(%%eax)\n" );
- }
- else
- {
- output( "\tcall *4(%%eax)\n" );
- if (odp->type == TYPE_STDCALL)
- output( "\tret $%u\n", args * get_ptr_size() );
+
+ switch (target_cpu)
+ {
+ case CPU_x86:
+ if (odp->flags & FLAG_REGISTER)
+ output( "\tpushl %%eax\n" );
else
- output( "\tret\n" );
+ output( "\tpushl %%esp\n" );
+
+ if (odp->flags & FLAG_RET64) flags |= 1;
+ output( "\tpushl $%u\n", (flags << 24) | (args << 16) |
(i - spec->base) );
+
+ if (UsePIC)
+ {
+ output( "\tcall %s\n",
asm_name("__wine_spec_get_pc_thunk_eax") );
+ output( "1:\tleal .L__wine_spec_relay_descr-1b(%%eax),%%eax\n"
);
+ }
+ else output( "\tmovl $.L__wine_spec_relay_descr,%%eax\n" );
+ output( "\tpushl %%eax\n" );
+
+ if (odp->flags & FLAG_REGISTER)
+ {
+ output( "\tcall *8(%%eax)\n" );
+ }
+ else
+ {
+ output( "\tcall *4(%%eax)\n" );
+ if (odp->type == TYPE_STDCALL)
+ output( "\tret $%u\n", args * get_ptr_size() );
+ else
+ output( "\tret\n" );
+ }
+ break;
+
+ case CPU_x86_64:
+ output( "\tmovq %%rcx,8(%%rsp)\n" );
+ output( "\tmovq %%rdx,16(%%rsp)\n" );
+ output( "\tmovq %%r8,24(%%rsp)\n" );
+ output( "\tmovq %%r9,32(%%rsp)\n" );
+ output( "\tmovq %%rsp,%%r8\n" );
+ output( "\tmovq $%u,%%rdx\n", (flags << 24) | (args <<
16) | (i - spec->base) );
+ output( "\tleaq .L__wine_spec_relay_descr(%%rip),%%rcx\n" );
+ output( "\tsubq $40,%%rsp\n" );
+ output( "\tcallq *%u(%%rcx)\n", (odp->flags & FLAG_REGISTER)
? 16 : 8 );
+ output( "\taddq $40,%%rsp\n" );
+ output( "\tret\n" );
+ break;
+
+ default:
+ assert(0);
}
}
}
@@ -307,8 +329,8 @@
/* output relays */
- /* we only support relay debugging on i386 */
- if (target_cpu != CPU_x86)
+ /* we only support relay debugging on i386 and x86_64 */
+ if (target_cpu != CPU_x86 && target_cpu != CPU_x86_64)
{
output( "\t%s 0\n", get_asm_ptr_keyword() );
return;
@@ -605,11 +627,8 @@
switch(odp->type)
{
case TYPE_EXTERN:
- output( " %s", name );
is_data = 1;
- if(strcmp(name, odp->link_name) || (odp->flags & FLAG_FORWARD))
- output( "=%s", odp->link_name );
- break;
+ /* fall through */
case TYPE_VARARGS:
case TYPE_CDECL:
/* try to reduce output */
@@ -621,7 +640,7 @@
{
int at_param = strlen(odp->u.func.arg_types) * get_ptr_size();
output( " %s", name );
- if (!kill_at) output( "@%d", at_param );
+ if (!kill_at && target_cpu == CPU_x86) output( "@%d",
at_param );
if (odp->flags & FLAG_FORWARD)
{
output( "=%s", odp->link_name );
@@ -629,7 +648,7 @@
else if (strcmp(name, odp->link_name)) /* try to reduce output */
{
output( "=%s", odp->link_name );
- if (!kill_at) output( "@%d", at_param );
+ if (!kill_at && target_cpu == CPU_x86) output( "@%d",
at_param );
}
break;
}
Modified: trunk/reactos/tools/winebuild/utils.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/winebuild/utils.c?re…
==============================================================================
--- trunk/reactos/tools/winebuild/utils.c [iso-8859-1] (original)
+++ trunk/reactos/tools/winebuild/utils.c [iso-8859-1] Tue Jan 20 05:44:30 2009
@@ -37,6 +37,23 @@
#define MAX_TMP_FILES 8
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)
@@ -416,6 +433,15 @@
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