Commit 9f498891 authored by Alexandre Julliard's avatar Alexandre Julliard

Now that everything is done in assembly in the spec file, directly

generate a .s file to bypass gcc inefficiency with large data structures.
parent a861f4df
...@@ -67,7 +67,7 @@ lib$(BASEMODULE).a: $(SPEC_DEF) $(IMPLIB_OBJS) ...@@ -67,7 +67,7 @@ lib$(BASEMODULE).a: $(SPEC_DEF) $(IMPLIB_OBJS)
$(WIN16_FILES:%=__checklink16__%): checklink16 $(WIN16_FILES:%=__checklink16__%): checklink16
checklink16:: $(MAINSPEC).o $(OBJS) $(MODULE).dbg.o dummy checklink16:: $(MAINSPEC).o $(OBJS) $(MODULE).dbg.o dummy
$(CC) -o checklink -Wl,-rpath,$(TOPOBJDIR)/libs $(TOPSRCDIR)/dlls/checklink.c $(MAINSPEC).o $(OBJS) $(MODULE).dbg.o -L$(DLLDIR) $(ALL_LIBS) -lwinecrt0 -lm && $(RM) checklink $(MAINSPEC).c $(MAINSPEC).o $(CC) -o checklink -Wl,-rpath,$(TOPOBJDIR)/libs $(TOPSRCDIR)/dlls/checklink.c $(MAINSPEC).o $(OBJS) $(MODULE).dbg.o -L$(DLLDIR) $(ALL_LIBS) -lwinecrt0 -lm && $(RM) checklink $(MAINSPEC).s $(MAINSPEC).o
checklink:: $(WIN16_FILES:%=__checklink16__%) checklink:: $(WIN16_FILES:%=__checklink16__%)
...@@ -79,7 +79,7 @@ crosstest:: $(SUBDIRS:%=%/__crosstest__) ...@@ -79,7 +79,7 @@ crosstest:: $(SUBDIRS:%=%/__crosstest__)
# Rule to explicitly generate the .spec.c for debugging # Rule to explicitly generate the .spec.c for debugging
$(MAINSPEC).c: $(MAINSPEC) $(ALL_OBJS) $(MAINSPEC).s: $(MAINSPEC) $(ALL_OBJS)
$(WINEBUILD) $(DEFS) $(DLLFLAGS) --dll -o $@ --export $(SRCDIR)/$(MAINSPEC) $(SUBSYSTEM:%=--subsystem %) $(ALL_OBJS) $(DLL_LDPATH) $(ALL_IMPORTS:%=-l%) $(DELAYIMPORTS:%=-d%) $(DLLDIR)/libwinecrt0.a $(WINEBUILD) $(DEFS) $(DLLFLAGS) --dll -o $@ --export $(SRCDIR)/$(MAINSPEC) $(SUBSYSTEM:%=--subsystem %) $(ALL_OBJS) $(DLL_LDPATH) $(ALL_IMPORTS:%=-l%) $(DELAYIMPORTS:%=-d%) $(DLLDIR)/libwinecrt0.a
# Rules for auto documentation # Rules for auto documentation
......
...@@ -319,9 +319,9 @@ static void free_resource_tree( struct res_tree *tree ) ...@@ -319,9 +319,9 @@ static void free_resource_tree( struct res_tree *tree )
static void output_string( FILE *outfile, const WCHAR *name ) static void output_string( FILE *outfile, const WCHAR *name )
{ {
int i, len = strlenW(name); int i, len = strlenW(name);
fprintf( outfile, " \"\\t%s 0x%04x", get_asm_short_keyword(), len ); fprintf( outfile, "\t%s 0x%04x", get_asm_short_keyword(), len );
for (i = 0; i < len; i++) fprintf( outfile, ",0x%04x", name[i] ); for (i = 0; i < len; i++) fprintf( outfile, ",0x%04x", name[i] );
fprintf( outfile, "\\n\" /* " ); fprintf( outfile, " /* " );
for (i = 0; i < len; i++) fprintf( outfile, "%c", isprint((char)name[i]) ? (char)name[i] : '?' ); for (i = 0; i < len; i++) fprintf( outfile, "%c", isprint((char)name[i]) ? (char)name[i] : '?' );
fprintf( outfile, " */\n" ); fprintf( outfile, " */\n" );
} }
...@@ -329,11 +329,11 @@ static void output_string( FILE *outfile, const WCHAR *name ) ...@@ -329,11 +329,11 @@ static void output_string( FILE *outfile, const WCHAR *name )
/* output a resource directory */ /* output a resource directory */
static inline void output_res_dir( FILE *outfile, unsigned int nb_names, unsigned int nb_ids ) static inline void output_res_dir( FILE *outfile, unsigned int nb_names, unsigned int nb_ids )
{ {
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* Characteristics */ fprintf( outfile, "\t.long 0\n" ); /* Characteristics */
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* TimeDateStamp */ fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */
fprintf( outfile, " \"\\t%s 0,0\\n\"\n", /* Major/MinorVersion */ fprintf( outfile, "\t%s 0,0\n", /* Major/MinorVersion */
get_asm_short_keyword() ); get_asm_short_keyword() );
fprintf( outfile, " \"\\t%s %u,%u\\n\"\n", /* NumberOfNamed/IdEntries */ fprintf( outfile, "\t%s %u,%u\n", /* NumberOfNamed/IdEntries */
get_asm_short_keyword(), nb_names, nb_ids ); get_asm_short_keyword(), nb_names, nb_ids );
} }
...@@ -388,8 +388,10 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) ...@@ -388,8 +388,10 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
/* output the resource directories */ /* output the resource directories */
fprintf( outfile, "asm(\".data\\n\\t.align %d\\n\"\n", get_alignment(get_ptr_size()) ); fprintf( outfile, "\n/* resources */\n\n" );
fprintf( outfile, " \".L__wine_spec_resources:\\n\"\n" ); fprintf( outfile, "\t.data\n" );
fprintf( outfile, "\t.align %d\n", get_alignment(get_ptr_size()) );
fprintf( outfile, ".L__wine_spec_resources:\n" );
output_res_dir( outfile, tree->nb_types - nb_id_types, nb_id_types ); output_res_dir( outfile, tree->nb_types - nb_id_types, nb_id_types );
...@@ -398,7 +400,7 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) ...@@ -398,7 +400,7 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
offset = RESDIR_SIZE( tree->nb_types ); offset = RESDIR_SIZE( tree->nb_types );
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++) for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{ {
fprintf( outfile, " \"\\t.long 0x%08x,0x%08x\\n\"\n", fprintf( outfile, "\t.long 0x%08x,0x%08x\n",
type->name_offset, offset | 0x80000000 ); type->name_offset, offset | 0x80000000 );
offset += RESDIR_SIZE( type->nb_names ); offset += RESDIR_SIZE( type->nb_names );
for (n = 0, name = type->names; n < type->nb_names; n++, name++) for (n = 0, name = type->names; n < type->nb_names; n++, name++)
...@@ -416,7 +418,7 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) ...@@ -416,7 +418,7 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
offset += RESDIR_SIZE( type->nb_names ); offset += RESDIR_SIZE( type->nb_names );
for (n = 0, name = type->names; n < type->nb_names; n++, name++) for (n = 0, name = type->names; n < type->nb_names; n++, name++)
{ {
fprintf( outfile, " \"\\t.long 0x%08x,0x%08x\\n\"\n", fprintf( outfile, "\t.long 0x%08x,0x%08x\n",
name->name_offset, offset | 0x80000000 ); name->name_offset, offset | 0x80000000 );
offset += RESDIR_SIZE( name->nb_languages ); offset += RESDIR_SIZE( name->nb_languages );
} }
...@@ -426,7 +428,7 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) ...@@ -426,7 +428,7 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
output_res_dir( outfile, 0, name->nb_languages ); output_res_dir( outfile, 0, name->nb_languages );
for (k = 0, res = name->res; k < name->nb_languages; k++, res++) for (k = 0, res = name->res; k < name->nb_languages; k++, res++)
{ {
fprintf( outfile, " \"\\t.long 0x%08x,0x%08x\\n\"\n", res->lang, fprintf( outfile, "\t.long 0x%08x,0x%08x\n", res->lang,
data_offset + (res - spec->resources) * sizeof(IMAGE_RESOURCE_DATA_ENTRY) ); data_offset + (res - spec->resources) * sizeof(IMAGE_RESOURCE_DATA_ENTRY) );
} }
} }
...@@ -435,7 +437,7 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) ...@@ -435,7 +437,7 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
/* dump the resource data entries */ /* dump the resource data entries */
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
fprintf( outfile, " \"\\t.long .L__wine_spec_res_%d,%u,0,0\\n\"\n", fprintf( outfile, "\t.long .L__wine_spec_res_%d,%u,0,0\n",
i, res->data_size ); i, res->data_size );
/* dump the name strings */ /* dump the name strings */
...@@ -446,28 +448,24 @@ void output_resources( FILE *outfile, DLLSPEC *spec ) ...@@ -446,28 +448,24 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
for (n = 0, name = type->names; n < type->nb_names; n++, name++) for (n = 0, name = type->names; n < type->nb_names; n++, name++)
if (name->name->str) output_string( outfile, name->name->str ); if (name->name->str) output_string( outfile, name->name->str );
} }
fprintf( outfile, ");\n" );
/* resource data */ /* resource data */
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
{ {
const unsigned char *p = res->data; const unsigned char *p = res->data;
fprintf( outfile, "asm(\".data\\n\\t.align %d\\n\"\n", get_alignment(get_ptr_size()) ); fprintf( outfile, "\n\t.align %d\n", get_alignment(get_ptr_size()) );
fprintf( outfile, " \".L__wine_spec_res_%d:\\n\"\n", i ); fprintf( outfile, ".L__wine_spec_res_%d:\n", i );
fprintf( outfile, " \"\\t.byte " ); fprintf( outfile, "\t.byte " );
for (j = 0; j < res->data_size - 1; j++, p++) for (j = 0; j < res->data_size - 1; j++, p++)
{ {
if ((j % 16) == 15) fprintf( outfile, "0x%02x\\n\"\n \"\\t.byte ", *p ); if ((j % 16) == 15) fprintf( outfile, "0x%02x\n\t.byte ", *p );
else fprintf( outfile, "0x%02x,", *p ); else fprintf( outfile, "0x%02x,", *p );
} }
fprintf( outfile, "0x%02x\\n\"\n", *p ); fprintf( outfile, "0x%02x\n", *p );
fprintf( outfile, ");\n" );
} }
fprintf( outfile, "asm(\".data\\n\"\n" ); fprintf( outfile, ".L__wine_spec_resources_end:\n" );
fprintf( outfile, " \".L__wine_spec_resources_end:\\n\"\n" ); fprintf( outfile, "\t.byte 0\n" );
fprintf( outfile, " \"\\t.byte 0\\n\"\n" );
fprintf( outfile, ");\n" );
free_resource_tree( tree ); free_resource_tree( tree );
} }
...@@ -4,6 +4,7 @@ DEFS = \ ...@@ -4,6 +4,7 @@ DEFS = \
-DLIBDIR="\"$(libdir)\"" \ -DLIBDIR="\"$(libdir)\"" \
-DDLLFLAGS="\"@DLLFLAGS@\"" \ -DDLLFLAGS="\"@DLLFLAGS@\"" \
-DLDDLLFLAGS="\"@LDDLLFLAGS@\"" \ -DLDDLLFLAGS="\"@LDDLLFLAGS@\"" \
-DAS="\"$(AS)\"" \
-DCC="\"$(CC)\"" \ -DCC="\"$(CC)\"" \
-DCPP="\"@CPPBIN@\"" \ -DCPP="\"@CPPBIN@\"" \
-DCXX="\"$(CXX)\"" \ -DCXX="\"$(CXX)\"" \
......
...@@ -142,9 +142,11 @@ static strarray* tmp_files; ...@@ -142,9 +142,11 @@ static strarray* tmp_files;
static sigset_t signal_mask; static sigset_t signal_mask;
#endif #endif
enum processor { proc_cc, proc_cxx, proc_cpp, proc_as };
struct options struct options
{ {
enum { proc_cc = 0, proc_cxx = 1, proc_cpp = 2} processor; enum processor processor;
int shared; int shared;
int use_msvcrt; int use_msvcrt;
int nostdinc; int nostdinc;
...@@ -209,13 +211,14 @@ static char* get_temp_file(const char* prefix, const char* suffix) ...@@ -209,13 +211,14 @@ static char* get_temp_file(const char* prefix, const char* suffix)
return tmp; return tmp;
} }
static const strarray* get_translator(struct options* opts) static const strarray* get_translator(enum processor processor)
{ {
static strarray* cpp = 0; static strarray* cpp = 0;
static strarray* as = 0;
static strarray* cc = 0; static strarray* cc = 0;
static strarray* cxx = 0; static strarray* cxx = 0;
switch(opts->processor) switch(processor)
{ {
case proc_cpp: case proc_cpp:
if (!cpp) cpp = strarray_fromstring(CPP, " "); if (!cpp) cpp = strarray_fromstring(CPP, " ");
...@@ -226,6 +229,9 @@ static const strarray* get_translator(struct options* opts) ...@@ -226,6 +229,9 @@ static const strarray* get_translator(struct options* opts)
case proc_cxx: case proc_cxx:
if (!cxx) cxx = strarray_fromstring(CXX, " "); if (!cxx) cxx = strarray_fromstring(CXX, " ");
return cxx; return cxx;
case proc_as:
if (!as) as = strarray_fromstring(AS, " ");
return as;
} }
error("Unknown processor"); error("Unknown processor");
} }
...@@ -247,8 +253,9 @@ static void compile(struct options* opts, const char* lang) ...@@ -247,8 +253,9 @@ static void compile(struct options* opts, const char* lang)
case proc_cc: gcc_defs = 0; break; case proc_cc: gcc_defs = 0; break;
case proc_cxx: gcc_defs = 0; break; case proc_cxx: gcc_defs = 0; break;
#endif #endif
case proc_as: gcc_defs = 0; break;
} }
strarray_addall(comp_args, get_translator(opts)); strarray_addall(comp_args, get_translator(opts->processor));
if (opts->processor != proc_cpp) if (opts->processor != proc_cpp)
{ {
...@@ -366,6 +373,48 @@ static const char* compile_to_object(struct options* opts, const char* file, con ...@@ -366,6 +373,48 @@ static const char* compile_to_object(struct options* opts, const char* file, con
return copts.output_name; return copts.output_name;
} }
static void assemble(struct options* opts)
{
int i;
for (i = 0; i < opts->files->size; i++ )
{
if (opts->files->base[i][0] != '-')
{
strarray* as_args = strarray_alloc();
strarray_addall(as_args, get_translator(proc_as));
if (opts->output_name)
{
strarray_add(as_args, "-o");
strarray_add(as_args, opts->output_name);
}
strarray_add(as_args, opts->files->base[i]);
spawn(opts->prefix, as_args, 0);
strarray_free(as_args);
}
}
}
static const char* assemble_to_object(struct options* opts, const char* file)
{
struct options copts;
char* base_name;
/* make a copy so we don't change any of the initial stuff */
/* a shallow copy is exactly what we want in this case */
base_name = get_basename(file);
copts = *opts;
copts.output_name = get_temp_file(base_name, ".o");
copts.files = strarray_alloc();
strarray_add(copts.files, file);
assemble(&copts);
strarray_free(copts.files);
free(base_name);
return copts.output_name;
}
/* check if there is a static lib associated to a given dll */ /* check if there is a static lib associated to a given dll */
static char *find_static_lib( const char *dll ) static char *find_static_lib( const char *dll )
{ {
...@@ -381,11 +430,10 @@ static void build(struct options* opts) ...@@ -381,11 +430,10 @@ static void build(struct options* opts)
strarray *lib_dirs, *files; strarray *lib_dirs, *files;
strarray *spec_args, *link_args; strarray *spec_args, *link_args;
char *output_file; char *output_file;
const char *spec_c_name, *spec_o_name; const char *spec_s_name, *spec_o_name;
const char *output_name, *spec_file, *lang; const char *output_name, *spec_file, *lang;
const char* winebuild = getenv("WINEBUILD"); const char* winebuild = getenv("WINEBUILD");
int generate_app_loader = 1; int generate_app_loader = 1;
int old_processor;
int j; int j;
/* NOTE: for the files array we'll use the following convention: /* NOTE: for the files array we'll use the following convention:
...@@ -540,14 +588,14 @@ static void build(struct options* opts) ...@@ -540,14 +588,14 @@ static void build(struct options* opts)
/* run winebuild to generate the .spec.c file */ /* run winebuild to generate the .spec.c file */
spec_args = strarray_alloc(); spec_args = strarray_alloc();
spec_c_name = get_temp_file(output_name, ".spec.c"); spec_s_name = get_temp_file(output_name, ".spec.s");
strarray_add(spec_args, winebuild); strarray_add(spec_args, winebuild);
strarray_add(spec_args, "--ld-cmd"); strarray_add(spec_args, "--ld-cmd");
strarray_add(spec_args, LD); strarray_add(spec_args, LD);
strarray_addall(spec_args, strarray_fromstring(DLLFLAGS, " ")); strarray_addall(spec_args, strarray_fromstring(DLLFLAGS, " "));
strarray_add(spec_args, opts->shared ? "--dll" : "--exe"); strarray_add(spec_args, opts->shared ? "--dll" : "--exe");
strarray_add(spec_args, "-o"); strarray_add(spec_args, "-o");
strarray_add(spec_args, spec_c_name); strarray_add(spec_args, spec_s_name);
if (spec_file) if (spec_file)
{ {
strarray_add(spec_args, "-E"); strarray_add(spec_args, "-E");
...@@ -593,16 +641,12 @@ static void build(struct options* opts) ...@@ -593,16 +641,12 @@ static void build(struct options* opts)
spawn(opts->prefix, spec_args, 0); spawn(opts->prefix, spec_args, 0);
/* compile the .spec.c file into a .spec.o file */ /* assemble the .spec.s file into a .spec.o file */
old_processor = opts->processor; spec_o_name = assemble_to_object(opts, spec_s_name);
/* Always compile spec.c as c, even if linking with g++ */
opts->processor = proc_cc;
spec_o_name = compile_to_object(opts, spec_c_name, 0);
opts->processor = old_processor;
/* link everything together now */ /* link everything together now */
link_args = strarray_alloc(); link_args = strarray_alloc();
strarray_addall(link_args, get_translator(opts)); strarray_addall(link_args, get_translator(opts->processor));
strarray_addall(link_args, strarray_fromstring(LDDLLFLAGS, " ")); strarray_addall(link_args, strarray_fromstring(LDDLLFLAGS, " "));
strarray_add(link_args, "-o"); strarray_add(link_args, "-o");
...@@ -679,7 +723,7 @@ static void forward(int argc, char **argv, struct options* opts) ...@@ -679,7 +723,7 @@ static void forward(int argc, char **argv, struct options* opts)
strarray* args = strarray_alloc(); strarray* args = strarray_alloc();
int j; int j;
strarray_addall(args, get_translator(opts)); strarray_addall(args, get_translator(opts->processor));
for( j = 1; j < argc; j++ ) for( j = 1; j < argc; j++ )
strarray_add(args, argv[j]); strarray_add(args, argv[j]);
......
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