Module: wine Branch: master Commit: 3f393a65527d8483c4c8607f2e79d49bcf26c33a URL: http://source.winehq.org/git/wine.git/?a=commit;h=3f393a65527d8483c4c8607f2e...
Author: André Hentschel nerv@dawncrow.de Date: Wed Jan 16 00:43:01 2013 +0100
winebuild: Add ARM64 support.
---
tools/winebuild/build.h | 4 ++-- tools/winebuild/import.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ tools/winebuild/main.c | 2 ++ tools/winebuild/spec32.c | 5 +++++ tools/winebuild/utils.c | 9 ++++++++- 5 files changed, 61 insertions(+), 3 deletions(-)
diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index 05adf31..3fbf89d 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -140,7 +140,7 @@ typedef struct
enum target_cpu { - CPU_x86, CPU_x86_64, CPU_SPARC, CPU_POWERPC, CPU_ARM, CPU_LAST = CPU_ARM + CPU_x86, CPU_x86_64, CPU_SPARC, CPU_POWERPC, CPU_ARM, CPU_ARM64, CPU_LAST = CPU_ARM64 };
enum target_platform @@ -178,7 +178,7 @@ struct strarray
#define FLAG_CPU(cpu) (0x01000 << (cpu)) #define FLAG_CPU_MASK (FLAG_CPU(CPU_LAST + 1) - FLAG_CPU(0)) -#define FLAG_CPU_WIN64 (FLAG_CPU(CPU_x86_64)) +#define FLAG_CPU_WIN64 (FLAG_CPU(CPU_x86_64) | FLAG_CPU(CPU_ARM64)) #define FLAG_CPU_WIN32 (FLAG_CPU_MASK & ~FLAG_CPU_WIN64)
#define MAX_ORDINALS 65535 diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index c73b86c..81325e9 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -675,6 +675,17 @@ static void output_import_thunk( const char *name, const char *table, int pos ) output( "\tldr PC,[IP,#%d]\n", pos); output( "\t.long %s\n", table ); break; + case CPU_ARM64: + output( "\tadr x9, 1f\n" ); + output( "\tldur x9, [x9, #0]\n" ); + if (pos & 0xf000) output( "\tadd x9, x9, #%u\n", pos & 0xf000 ); + if (pos & 0x0f00) output( "\tadd x9, x9, #%u\n", pos & 0x0f00 ); + if (pos & 0x00f0) output( "\tadd x9, x9, #%u\n", pos & 0x00f0 ); + if (pos & 0x000f) output( "\tadd x9, x9, #%u\n", pos & 0x000f ); + output( "\tldur x9, [x9, #0]\n" ); + output( "\tbr x9\n" ); + output( "1:\t.quad %s\n", table ); + break; case CPU_POWERPC: output( "\tmr %s, %s\n", ppc_reg(0), ppc_reg(31) ); if (target_platform == PLATFORM_APPLE) @@ -994,6 +1005,21 @@ static void output_delayed_import_thunks( const DLLSPEC *spec ) output( "\tldmfd SP!, {r0-r3}\n" ); output( "\tmov PC,IP\n"); break; + case CPU_ARM64: + output( "\tstp x29, x30, [sp,#-16]!\n" ); + output( "\tmov x29, sp\n" ); + output( "\tadr x9, 1f\n" ); + output( "\tldur x9, [x9, #0]\n" ); + output( "\tblr x9\n" ); + output( "\tmov x9, x0\n" ); + output( "\tldp x29, x30, [sp],#16\n" ); + output( "\tldp x0, x1, [sp,#16]\n" ); + output( "\tldp x2, x3, [sp,#32]\n" ); + output( "\tldp x4, x5, [sp,#48]\n" ); + output( "\tldp x6, x7, [sp],#80\n" ); + output( "\tbr x9\n" ); /* or "ret x9" */ + output( "1:\t.quad %s\n", asm_name("__wine_spec_delay_load") ); + break; case CPU_POWERPC: if (target_platform == PLATFORM_APPLE) extra_stack_storage = 56;
@@ -1086,6 +1112,24 @@ static void output_delayed_import_thunks( const DLLSPEC *spec ) output( "\tldr PC,[PC,#-4]\n"); output( "\t.long %s\n", asm_name("__wine_delay_load_asm") ); break; + case CPU_ARM64: + output( "\tstp x6, x7, [sp,#-80]!\n" ); + output( "\tstp x4, x5, [sp,#48]\n" ); + output( "\tstp x2, x3, [sp,#32]\n" ); + output( "\tstp x0, x1, [sp,#16]\n" ); + output( "\tmov x0, #%d\n", idx ); + output( "\tmov x1, #16384\n" ); + output( "\tmul x1, x0, x1\n" ); + output( "\tmov x0, x1\n" ); + output( "\tmov x1, #4\n" ); + output( "\tmul x1, x0, x1\n" ); + output( "\tmov x0, x1\n" ); + output( "\tadd x0, x0, #%d\n", j ); + output( "\tadr x9, 1f\n" ); + output( "\tldur x9, [x9, #0]\n" ); + output( "\tbr x9\n" ); + output( "1:\t.quad %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 28ecec8..594b31b 100644 --- a/tools/winebuild/main.c +++ b/tools/winebuild/main.c @@ -59,6 +59,8 @@ enum target_cpu target_cpu = CPU_SPARC; enum target_cpu target_cpu = CPU_POWERPC; #elif defined(__arm__) enum target_cpu target_cpu = CPU_ARM; +#elif defined(__aarch64__) +enum target_cpu target_cpu = CPU_ARM64; #else #error Unsupported CPU #endif diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 20fcbc0..f6c8cd2 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -39,6 +39,7 @@ #define IMAGE_FILE_MACHINE_ARMNT 0x01C4 /* Wine extension */ #define IMAGE_FILE_MACHINE_SPARC 0x2000 +#define IMAGE_FILE_MACHINE_ARM64 0x01C5
#define IMAGE_SIZEOF_NT_OPTIONAL32_HEADER 224 #define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 240 @@ -447,6 +448,7 @@ static void output_asm_constructor( const char *constructor ) output( "\n\t.section ".text","ax"\n" ); output( "\tblx %s\n", asm_name(constructor) ); break; + case CPU_ARM64: case CPU_POWERPC: output( "\n\t.section ".init","ax"\n" ); output( "\tbl %s\n", asm_name(constructor) ); @@ -494,6 +496,7 @@ void output_module( DLLSPEC *spec ) output( "\n\t.section ".text","ax"\n" ); output( "\tb 1f\n" ); break; + case CPU_ARM64: case CPU_POWERPC: output( "\n\t.section ".init","ax"\n" ); output( "\tb 1f\n" ); @@ -518,6 +521,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_ARMNT; break; + case CPU_ARM64: machine = IMAGE_FILE_MACHINE_ARM64; break; case CPU_POWERPC: machine = IMAGE_FILE_MACHINE_POWERPC; break; case CPU_SPARC: machine = IMAGE_FILE_MACHINE_SPARC; break; } @@ -707,6 +711,7 @@ void output_fake_module( DLLSPEC *spec ) case CPU_POWERPC: put_word( IMAGE_FILE_MACHINE_POWERPC ); break; case CPU_SPARC: put_word( IMAGE_FILE_MACHINE_SPARC ); break; case CPU_ARM: put_word( IMAGE_FILE_MACHINE_ARMNT ); break; + case CPU_ARM64: put_word( IMAGE_FILE_MACHINE_ARM64 ); break; } put_word( nb_sections ); /* NumberOfSections */ put_dword( 0 ); /* TimeDateStamp */ diff --git a/tools/winebuild/utils.c b/tools/winebuild/utils.c index 09f9b73..559e476 100644 --- a/tools/winebuild/utils.c +++ b/tools/winebuild/utils.c @@ -58,7 +58,9 @@ static const struct { "x86_64", CPU_x86_64 }, { "sparc", CPU_SPARC }, { "powerpc", CPU_POWERPC }, - { "arm", CPU_ARM } + { "arm", CPU_ARM }, + { "arm64", CPU_ARM64 }, + { "aarch64", CPU_ARM64 }, };
/* atexit handler to clean tmp files */ @@ -867,6 +869,7 @@ unsigned int get_alignment(unsigned int align) /* fall through */ case CPU_POWERPC: case CPU_ARM: + case CPU_ARM64: n = 0; while ((1u << n) != align) n++; return n; @@ -885,6 +888,7 @@ unsigned int get_page_size(void) case CPU_x86_64: return 4096; case CPU_POWERPC: return 4096; case CPU_ARM: return 4096; + case CPU_ARM64: return 4096; case CPU_SPARC: return 8192; } /* unreached */ @@ -903,6 +907,7 @@ unsigned int get_ptr_size(void) case CPU_ARM: return 4; case CPU_x86_64: + case CPU_ARM64: return 8; } /* unreached */ @@ -975,6 +980,7 @@ const char *func_declaration( const char *func ) switch(target_cpu) { case CPU_ARM: + case CPU_ARM64: buffer = strmake( ".type %s,%%function", func ); break; default: @@ -1025,6 +1031,7 @@ void output_gnu_stack_note(void) switch(target_cpu) { case CPU_ARM: + case CPU_ARM64: output( "\t.section .note.GNU-stack,"",%%progbits\n" ); break; default: