Commit 94588343 authored by Alexandre Julliard's avatar Alexandre Julliard

winebuild: Add a helper to output an asm function header.

parent 3bb75273
......@@ -288,7 +288,6 @@ extern unsigned int get_alignment(unsigned int align);
extern unsigned int get_page_size(void);
extern unsigned int get_args_size( const ORDDEF *odp );
extern const char *asm_name( const char *func );
extern const char *func_declaration( const char *func );
extern const char *asm_globl( const char *func );
extern const char *get_asm_ptr_keyword(void);
extern const char *get_asm_string_keyword(void);
......@@ -298,6 +297,7 @@ extern const char *get_asm_rsrc_section(void);
extern const char *get_asm_string_section(void);
extern const char *arm64_page( const char *sym );
extern const char *arm64_pageoff( const char *sym );
extern void output_function_header( const char *func, int global );
extern void output_function_size( const char *name );
extern void output_gnu_stack_note(void);
......
......@@ -752,10 +752,7 @@ int is_undefined( const char *name )
void output_get_pc_thunk(void)
{
assert( target.cpu == CPU_i386 );
output( "\n\t.text\n" );
output( "\t.align %d\n", get_alignment(4) );
output( "\t%s\n", func_declaration("__wine_spec_get_pc_thunk_eax") );
output( "%s:\n", asm_name("__wine_spec_get_pc_thunk_eax") );
output_function_header( "__wine_spec_get_pc_thunk_eax", 0 );
output( "\tmovl (%%esp),%%eax\n" );
output( "\tret\n" );
output_function_size( "__wine_spec_get_pc_thunk_eax" );
......@@ -764,9 +761,7 @@ void output_get_pc_thunk(void)
/* output a single import thunk */
static void output_import_thunk( const char *name, const char *table, int pos )
{
output( "\n\t.align %d\n", get_alignment(4) );
output( "\t%s\n", func_declaration(name) );
output( "%s\n", asm_globl(name) );
output_function_header( name, 1 );
switch (target.cpu)
{
......@@ -1030,9 +1025,7 @@ static void output_delayed_import_thunks( const DLLSPEC *spec )
LIST_FOR_EACH_ENTRY( import, &dll_delayed, struct import, entry )
{
char *module_func = strmake( "__wine_delay_load_asm_%s", import->c_name );
output( "\t.align %d\n", get_alignment(4) );
output( "\t%s\n", func_declaration(module_func) );
output( "%s:\n", asm_name(module_func) );
output_function_header( module_func, 0 );
output_cfi( ".cfi_startproc" );
switch (target.cpu)
{
......@@ -1249,7 +1242,6 @@ void output_stubs( DLLSPEC *spec )
if (!has_stubs( spec )) return;
output( "\n/* stub functions */\n\n" );
output( "\t.text\n" );
for (i = 0; i < spec->nb_entry_points; i++)
{
......@@ -1258,9 +1250,7 @@ void output_stubs( DLLSPEC *spec )
name = get_stub_name( odp, spec );
exp_name = odp->name ? odp->name : odp->export_name;
output( "\t.align %d\n", get_alignment(4) );
output( "\t%s\n", func_declaration(name) );
output( "%s:\n", asm_name(name) );
output_function_header( name, 0 );
switch (target.cpu)
{
......@@ -1413,7 +1403,6 @@ void output_syscalls( DLLSPEC *spec )
count = sort_func_list( syscalls, count, cmp_link_name );
output( "\n/* system calls */\n\n" );
output( "\t.text\n" );
for (i = 0; i < count; i++)
{
......@@ -1421,9 +1410,7 @@ void output_syscalls( DLLSPEC *spec )
const char *name = get_link_name(odp);
unsigned int id = (spec->syscall_table << 12) + i;
output( "\t.align %d\n", get_alignment(16) );
output( "\t%s\n", func_declaration(name) );
output( "%s\n", asm_globl(name) );
output_function_header( name, 1 );
switch (target.cpu)
{
case CPU_i386:
......@@ -1501,16 +1488,12 @@ void output_syscalls( DLLSPEC *spec )
{
case CPU_i386:
if (UsePIC) break;
output( "\t.align %d\n", get_alignment(16) );
output( "\t%s\n", func_declaration("__wine_syscall") );
output( "%s:\n", asm_name("__wine_syscall") );
output_function_header( "__wine_syscall", 0 );
output( "\tjmp *(%s)\n", asm_name("__wine_syscall_dispatcher") );
output_function_size( "__wine_syscall" );
break;
case CPU_ARM:
output( "\t.align %d\n", get_alignment(16) );
output( "\t%s\n", func_declaration("__wine_syscall") );
output( "%s:\n", asm_name("__wine_syscall") );
output_function_header( "__wine_syscall", 0 );
if (UsePIC)
{
output( "\tldr r0, 2f\n");
......@@ -1675,10 +1658,7 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struc
if (is_delay)
{
output( "\n\t.text\n" );
output( "\t.align %d\n", get_alignment( get_ptr_size() ));
output( "%s\n", asm_globl( delay_load ) );
output( "\t%s\n", func_declaration( delay_load ) );
output_function_header( delay_load, 1 );
switch (target.cpu)
{
......@@ -1848,11 +1828,7 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struc
asm_name( abi_name ) );
new_output_as_file();
output( "\n\t.text\n" );
output( "\t.align %d\n", get_alignment( get_ptr_size() ) );
output( "%s\n", asm_globl( abi_name ) );
output( "\t%s\n", func_declaration( abi_name ) );
output_function_header( abi_name, 1 );
switch (target.cpu)
{
......@@ -1977,10 +1953,7 @@ static void build_unix_import_lib( DLLSPEC *spec, struct strarray files )
case TYPE_STDCALL:
prefix = (!odp->name || (odp->flags & FLAG_ORDINAL)) ? import_ord_prefix : import_func_prefix;
new_output_as_file();
output( "\t.text\n" );
output( "\n\t.align %d\n", get_alignment( get_ptr_size() ));
output( "\t%s\n", func_declaration( name ) );
output( "%s\n", asm_globl( name ) );
output_function_header( name, 1 );
output( "\t%s %s%s$%u$%s\n", get_asm_ptr_keyword(),
asm_name( prefix ), dll_name, odp->ordinal, name );
output_function_size( name );
......
......@@ -36,14 +36,6 @@
#define GS_OFFSET 0x1d8 /* FIELD_OFFSET(TEB,SystemReserved2) + FIELD_OFFSET(struct x86_thread_data,gs) */
static void function_header( const char *name )
{
output( "\n\t.align %d\n", get_alignment(4) );
output( "\t%s\n", func_declaration(name) );
output( "%s\n", asm_globl(name) );
}
/*******************************************************************
* BuildCallFrom16Core
*
......@@ -114,9 +106,9 @@ static void function_header( const char *name )
static void BuildCallFrom16Core( int reg_func, int thunk )
{
/* Function header */
if (thunk) function_header( "__wine_call_from_16_thunk" );
else if (reg_func) function_header( "__wine_call_from_16_regs" );
else function_header( "__wine_call_from_16" );
if (thunk) output_function_header( "__wine_call_from_16_thunk", 1 );
else if (reg_func) output_function_header( "__wine_call_from_16_regs", 1 );
else output_function_header( "__wine_call_from_16", 1 );
/* Create STACK16FRAME (except STACK32FRAME link) */
output( "\tpushw %%gs\n" );
......@@ -381,7 +373,7 @@ static void BuildCallTo16Core( int reg_func )
const char *func_name = is_pe() ? strmake( "%s@12", name ) : name;
/* Function header */
function_header( func_name );
output_function_header( func_name, 1 );
/* Function entry sequence */
output_cfi( ".cfi_startproc" );
......@@ -533,7 +525,7 @@ static void BuildCallTo16Core( int reg_func )
*/
static void BuildRet16Func(void)
{
function_header( "__wine_call_to_16_ret" );
output_function_header( "__wine_call_to_16_ret", 1 );
/* Save %esp into %esi */
output( "\tmovl %%esp,%%esi\n" );
......
......@@ -338,9 +338,7 @@ static void output_call16_function( ORDDEF *odp )
name = strmake( ".L__wine_spec_call16_%s", get_relay_name(odp) );
output( "\t.align %d\n", get_alignment(4) );
output( "\t%s\n", func_declaration(name) );
output( "%s:\n", name );
output_function_header( name, 0 );
output_cfi( ".cfi_startproc" );
output( "\tpushl %%ebp\n" );
output_cfi( ".cfi_adjust_cfa_offset 4" );
......
......@@ -876,38 +876,42 @@ const char *asm_name( const char *sym )
}
/* return an assembly function declaration for a C function name */
const char *func_declaration( const char *func )
void output_function_header( const char *func, int global )
{
static char *buffer;
const char *name = asm_name( func );
output( "\t.text\n" );
switch (target.platform)
{
case PLATFORM_APPLE:
return "";
if (global) output( "\t.globl %s\n\t.private_extern %s\n", name, name );
break;
case PLATFORM_MINGW:
case PLATFORM_WINDOWS:
free( buffer );
buffer = strmake( ".def %s\n\t.scl 2\n\t.type 32\n\t.endef%s", asm_name(func),
thumb_mode ? "\n\t.thumb_func" : "" );
output( "\t.def %s\n\t.scl 2\n\t.type 32\n\t.endef\n", name );
if (global) output( "\t.globl %s\n", name );
if (thumb_mode) output( "\t.thumb_func\n" );
break;
default:
free( buffer );
switch (target.cpu)
{
case CPU_ARM:
buffer = strmake( ".type %s,%%function%s", func,
thumb_mode ? "\n\t.thumb_func" : "" );
output( "\t.type %s,%%function\n", name );
if (thumb_mode) output( "\t.thumb_func\n" );
break;
case CPU_ARM64:
buffer = strmake( ".type %s,%%function", func );
output( "\t.type %s,%%function\n", name );
break;
default:
buffer = strmake( ".type %s,@function", func );
output( "\t.type %s,@function\n", name );
break;
}
if (global) output( "\t.globl %s\n\t.hidden %s\n", name, name );
break;
}
return buffer;
output( "\t.align %u\n", get_alignment(4) );
output( "%s:\n", name );
}
/* output a size declaration for an assembly function */
......
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