瀏覽代碼

Merged revision(s) 32063 from trunk:
fix InterlockedCompareExchange on ARM-Linux: kuser_cmpxchg destroys r3, which needs to be restored, if we have to loop
........

git-svn-id: branches/fixes_3_0@32079 -

yury 9 年之前
父節點
當前提交
bb42a1a2a0
共有 1 個文件被更改,包括 7 次插入5 次删除
  1. 7 5
      rtl/arm/arm.inc

+ 7 - 5
rtl/arm/arm.inc

@@ -881,8 +881,6 @@ asm
 {$else}
 {$ifdef SYSTEM_HAS_KUSER_CMPXCHG}
   stmfd r13!, {r4, lr}
-  mvn   r3, #0x0000f000
-  sub   r3, r3, #0x3F
 
   mov   r4, r2 // Swap parameters around
   mov   r2, r0
@@ -890,9 +888,13 @@ asm
 
   // r1 and r2 will not be clobbered by kuser_cmpxchg
   // If we have to loop, r0 will be set to the original Comperand
+  // kuser_cmpxchg is documented to destroy r3, therefore setting
+  // r3 must be in the loop
   .Linterlocked_compare_exchange_loop:
+  mvn   r3, #0x0000f000
+  sub   r3, r3, #0x3F
 {$ifdef CPUARM_HAS_BLX}
-  blx r3	 // Call kuser_cmpxchg, sets C-Flag on success
+  blx r3       // Call kuser_cmpxchg, sets C-Flag on success
 {$else}
   mov lr, pc
 {$ifdef CPUARM_HAS_BX}
@@ -908,11 +910,11 @@ asm
   // The loop case is HIGHLY unlikely, it would require that we got rescheduled between
   // calling kuser_cmpxchg and the ldr. While beeing rescheduled another process/thread
   // would have the set the value to our comperand
-  ldr	r0, [r2] // Load the currently set value
+  ldr   r0, [r2] // Load the currently set value
   cmp   r0, r4   // Return if Comperand != current value, otherwise loop again
   ldmnefd r13!, {r4, pc}
   // If we need to loop here, we have to
-  b	.Linterlocked_compare_exchange_loop
+  b    .Linterlocked_compare_exchange_loop
 
 {$else}
 // lock