diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index b942934aedf..65163f34b5a 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -119,7 +119,7 @@ typedef struct enum target_cpu { - CPU_x86, CPU_x86_64, CPU_SPARC, CPU_ALPHA, CPU_POWERPC + CPU_x86, CPU_x86_64, CPU_SPARC, CPU_ALPHA, CPU_POWERPC, CPU_ARM }; enum target_platform diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index bb9d6d1d27c..d41a754ac41 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -699,6 +699,10 @@ static void output_import_thunk( const char *name, const char *table, int pos ) output( "\tlda $0,%d($0)\n", pos ); output( "\tjmp $31,($0)\n" ); break; + case CPU_ARM: + output( "\tmov r4, #%s\n", table ); + output( "\tldr r15, [r4, #%d]\n", pos ); + break; case CPU_POWERPC: output( "\tmr %s, %s\n", ppc_reg(0), ppc_reg(31) ); if (target_platform == PLATFORM_APPLE) @@ -1005,6 +1009,11 @@ static void output_delayed_import_thunks( const DLLSPEC *spec ) output( "\tjsr $26,%s\n", asm_name("__wine_spec_delay_load") ); output( "\tjmp $31,($0)\n" ); break; + case CPU_ARM: + output( "\tstmfd sp!, {r4, r5, r6, r7, r8, r9, r10, lr}\n" ); + output( "\tblx %s\n", asm_name("__wine_spec_delay_load") ); + output( "\tldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, pc}\n" ); + break; case CPU_POWERPC: if (target_platform == PLATFORM_APPLE) extra_stack_storage = 56; @@ -1088,6 +1097,9 @@ static void output_delayed_import_thunks( const DLLSPEC *spec ) output( "\tldah $0,%d($0)\n", idx); output( "\tjmp $31,%s\n", asm_name("__wine_delay_load_asm") ); break; + case CPU_ARM: + output( "\tb %s\n", asm_name("__wine_delay_load_asm") ); + break; case CPU_POWERPC: switch(target_platform) { diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c index 4dfa63f08a5..14c168994b2 100644 --- a/tools/winebuild/main.c +++ b/tools/winebuild/main.c @@ -58,6 +58,8 @@ enum target_cpu target_cpu = CPU_SPARC; enum target_cpu target_cpu = CPU_ALPHA; #elif defined(__powerpc__) enum target_cpu target_cpu = CPU_POWERPC; +#elif defined(__arm__) +enum target_cpu target_cpu = CPU_ARM; #else #error Unsupported CPU #endif diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 09e69f575a1..c2b11af8474 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -37,6 +37,7 @@ #define IMAGE_FILE_MACHINE_ALPHA 0x0184 #define IMAGE_FILE_MACHINE_POWERPC 0x01f0 #define IMAGE_FILE_MACHINE_AMD64 0x8664 +#define IMAGE_FILE_MACHINE_ARM 0x01C0 #define IMAGE_SIZEOF_NT_OPTIONAL32_HEADER 224 #define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 240 @@ -369,6 +370,9 @@ static void output_asm_constructor( const char *constructor ) case CPU_ALPHA: output( "\tjsr $26,%s\n", asm_name(constructor) ); break; + case CPU_ARM: + output( "\tblx %s\n", asm_name(constructor) ); + break; case CPU_POWERPC: output( "\tbl %s\n", asm_name(constructor) ); break; @@ -412,6 +416,7 @@ void output_module( DLLSPEC *spec ) case CPU_SPARC: output( "\tjmp 1f\n" ); break; + case CPU_ARM: case CPU_POWERPC: output( "\tb 1f\n" ); break; @@ -434,6 +439,7 @@ void output_module( DLLSPEC *spec ) { case CPU_x86: machine = IMAGE_FILE_MACHINE_I386; break; case CPU_x86_64: machine = IMAGE_FILE_MACHINE_AMD64; break; + case CPU_ARM: machine = IMAGE_FILE_MACHINE_ARM; break; case CPU_POWERPC: machine = IMAGE_FILE_MACHINE_POWERPC; break; case CPU_ALPHA: machine = IMAGE_FILE_MACHINE_ALPHA; break; case CPU_SPARC: machine = IMAGE_FILE_MACHINE_UNKNOWN; break; @@ -623,6 +629,7 @@ void output_fake_module( DLLSPEC *spec ) case CPU_POWERPC: put_word( IMAGE_FILE_MACHINE_POWERPC ); break; case CPU_ALPHA: put_word( IMAGE_FILE_MACHINE_ALPHA ); break; case CPU_SPARC: put_word( IMAGE_FILE_MACHINE_UNKNOWN ); break; + case CPU_ARM: put_word( IMAGE_FILE_MACHINE_ARM ); break; } put_word( nb_sections ); /* NumberOfSections */ put_dword( 0 ); /* TimeDateStamp */ diff --git a/tools/winebuild/utils.c b/tools/winebuild/utils.c index bbf23f4dd95..c0b93710e6c 100644 --- a/tools/winebuild/utils.c +++ b/tools/winebuild/utils.c @@ -57,7 +57,8 @@ static const struct { "x86_64", CPU_x86_64 }, { "sparc", CPU_SPARC }, { "alpha", CPU_ALPHA }, - { "powerpc", CPU_POWERPC } + { "powerpc", CPU_POWERPC }, + { "arm", CPU_ARM } }; /* atexit handler to clean tmp files */ @@ -795,6 +796,7 @@ unsigned int get_alignment(unsigned int align) case CPU_x86: case CPU_x86_64: case CPU_SPARC: + case CPU_ARM: if (target_platform != PLATFORM_APPLE) return align; /* fall through */ case CPU_POWERPC: @@ -816,6 +818,7 @@ unsigned int get_page_size(void) case CPU_x86: return 4096; case CPU_x86_64: return 4096; case CPU_POWERPC: return 4096; + case CPU_ARM: return 4096; case CPU_SPARC: return 8192; case CPU_ALPHA: return 8192; } @@ -833,6 +836,7 @@ unsigned int get_ptr_size(void) case CPU_POWERPC: case CPU_SPARC: case CPU_ALPHA: + case CPU_ARM: return 4; case CPU_x86_64: return 8; @@ -873,7 +877,15 @@ const char *func_declaration( const char *func ) sprintf( buffer, ".def _%s; .scl 2; .type 32; .endef", func ); break; default: - sprintf( buffer, ".type %s,@function", func ); + switch(target_cpu) + { + case CPU_ARM: + sprintf( buffer, ".type %s,%%function", func ); + break; + default: + sprintf( buffer, ".type %s,@function", func ); + break; + } break; } return buffer; @@ -902,7 +914,15 @@ void output_gnu_stack_note(void) case PLATFORM_APPLE: break; default: - output( "\t.section .note.GNU-stack,\"\",@progbits\n" ); + switch(target_cpu) + { + case CPU_ARM: + output( "\t.section .note.GNU-stack,\"\",%%progbits\n" ); + break; + default: + output( "\t.section .note.GNU-stack,\"\",@progbits\n" ); + break; + } break; } }