=?UTF-8?Q?Andr=C3=A9=20Hentschel=20?=: winebuild: Add ARM64 support.

Alexandre Julliard julliard at winehq.org
Wed Jan 16 13:47:43 CST 2013


Module: wine
Branch: master
Commit: 3f393a65527d8483c4c8607f2e79d49bcf26c33a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=3f393a65527d8483c4c8607f2e79d49bcf26c33a

Author: André Hentschel <nerv at 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:




More information about the wine-cvs mailing list