Fix import stub on ppc

Simon Richter Simon.Richter at hogyros.de
Sat May 31 03:51:01 CDT 2008


The address calculation was wrong, as the addition of the lower 16 bits
is a signed addition, so if bit 15 is set, the upper 16 bits need to be
incremented by one (so the hi portion of the symbol always references
the symbol + 0x8000).

The new code is also significantly shorter and only makes one memory
access (reading the actual pointer from the table); r0 is clobbered in
the process, but that is allowed (the ABI defines it as a scratch
register that is never saved). Since r0 cannot be used as a base in an
"lwz" instruction, r31 is saved to r0 and used for the lookup.
---
 tools/winebuild/import.c |   26 ++++++++------------------
 1 files changed, 8 insertions(+), 18 deletions(-)

diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c
index 5b62512..5e0c172 100644
--- a/tools/winebuild/import.c
+++ b/tools/winebuild/import.c
@@ -699,30 +699,20 @@ static void output_import_thunk( const char *name, const char *table, int pos )
         output( "\tjmp $31,($0)\n" );
         break;
     case CPU_POWERPC:
-        output( "\taddi %s, %s, -0x4\n", ppc_reg(1), ppc_reg(1) );
-        output( "\tstw  %s, 0(%s)\n",    ppc_reg(9), ppc_reg(1) );
-        output( "\taddi %s, %s, -0x4\n", ppc_reg(1), ppc_reg(1) );
-        output( "\tstw  %s, 0(%s)\n",    ppc_reg(8), ppc_reg(1) );
-        output( "\taddi %s, %s, -0x4\n", ppc_reg(1), ppc_reg(1) );
-        output( "\tstw  %s, 0(%s)\n",    ppc_reg(7), ppc_reg(1) );
+        output( "\tmr %s, %s\n", ppc_reg(0), ppc_reg(31) );
         if (target_platform == PLATFORM_APPLE)
         {
-            output( "\tlis %s, ha16(%s+%d)\n", ppc_reg(9), table, pos );
-            output( "\tla  %s, lo16(%s+%d)(%s)\n", ppc_reg(8), table, pos, ppc_reg(9) );
+            output( "\tlis %s, ha16(%s+%d+32768)\n", ppc_reg(31), table, pos );
+            output( "\tla  %s, lo16(%s+%d)(%s)\n", ppc_reg(31), table, pos, ppc_reg(31) );
         }
         else
         {
-            output( "\tlis %s, (%s+%d)@h\n", ppc_reg(9), table, pos );
-            output( "\tla  %s, (%s+%d)@l(%s)\n", ppc_reg(8), table, pos, ppc_reg(9) );
+            output( "\tlis %s, (%s+%d+32768)@h\n", ppc_reg(31), table, pos );
+            output( "\tla  %s, (%s+%d)@l(%s)\n", ppc_reg(31), table, pos, ppc_reg(31) );
         }
-        output( "\tlwz  %s, 0(%s)\n", ppc_reg(7), ppc_reg(8) );
-        output( "\tmtctr %s\n", ppc_reg(7) );
-        output( "\tlwz  %s, 0(%s)\n",   ppc_reg(7), ppc_reg(1) );
-        output( "\taddi %s, %s, 0x4\n", ppc_reg(1), ppc_reg(1) );
-        output( "\tlwz  %s, 0(%s)\n",   ppc_reg(8), ppc_reg(1) );
-        output( "\taddi %s, %s, 0x4\n", ppc_reg(1), ppc_reg(1) );
-        output( "\tlwz  %s, 0(%s)\n",   ppc_reg(9), ppc_reg(1) );
-        output( "\taddi %s, %s, 0x4\n", ppc_reg(1), ppc_reg(1) );
+        output( "\tlwz   %s, 0(%s)\n", ppc_reg(31), ppc_reg(31) );
+        output( "\tmtctr %s\n", ppc_reg(31) );
+        output( "\tmr    %s, %s\n", ppc_reg(31), ppc_reg(0) );
         output( "\tbctr\n" );
         break;
     }
-- 
1.5.5.2



More information about the wine-patches mailing list