winebuild: add ARM support

André Hentschel nerv at dawncrow.de
Tue Nov 17 13:20:48 CST 2009


These are my actually efforts on winebuild. We are not yet on a point where we can check if it works completely, but with this in git some others might give it a try and/or optimize it. Of course i will continue working on it anyway.
---
 tools/winebuild/build.h  |    2 +-
 tools/winebuild/import.c |   12 ++++++++++++
 tools/winebuild/main.c   |    2 ++
 tools/winebuild/spec32.c |    7 +++++++
 tools/winebuild/utils.c  |   26 +++++++++++++++++++++++---
 5 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h
index b942934..65163f3 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 bb9d6d1..d41a754 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 4dfa63f..14c1689 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 09e69f5..c2b11af 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 bbf23f4..c0b9371 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, at function", func );
+        switch(target_cpu)
+        {
+        case CPU_ARM:
+            sprintf( buffer, ".type %s,%%function", func );
+            break;
+        default:
+            sprintf( buffer, ".type %s, at 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,\"\", at progbits\n" );
+        switch(target_cpu)
+        {
+        case CPU_ARM:
+            output( "\t.section .note.GNU-stack,\"\",%%progbits\n" );
+            break;
+        default:
+            output( "\t.section .note.GNU-stack,\"\", at progbits\n" );
+            break;
+        }
         break;
     }
 }
-- 

Best Regards, André Hentschel



More information about the wine-patches mailing list