Browse Source

* don't overwrite the target value of interlockedcompareexchange*() if the
value is different from the comparand (patch by "FVI", mantis #18082)
* sign extend the loaded value of interlockedcompareexchange() on PowerPC64,
because the function arguments are longints

git-svn-id: trunk@16475 -

Jonas Maebe 14 năm trước cách đây
mục cha
commit
5cbe12c622
4 tập tin đã thay đổi với 36 bổ sung3 xóa
  1. 1 0
      .gitattributes
  2. 1 1
      rtl/powerpc/powerpc.inc
  3. 5 2
      rtl/powerpc64/powerpc64.inc
  4. 29 0
      tests/webtbs/tw18082.pp

+ 1 - 0
.gitattributes

@@ -10769,6 +10769,7 @@ tests/webtbs/tw17986.pp svneol=native#text/pascal
 tests/webtbs/tw17998.pp svneol=native#text/plain
 tests/webtbs/tw18013.pp svneol=native#text/plain
 tests/webtbs/tw18075.pp svneol=native#text/pascal
+tests/webtbs/tw18082.pp svneol=native#text/plain
 tests/webtbs/tw18085.pp svneol=native#text/pascal
 tests/webtbs/tw1820.pp svneol=native#text/plain
 tests/webtbs/tw1825.pp svneol=native#text/plain

+ 1 - 1
rtl/powerpc/powerpc.inc

@@ -1172,7 +1172,7 @@ asm
   addic  r9,r9,-1
   subfe  r9,r9,r9
   and    r8,r4,r9
-  andc   r7,r5,r9
+  andc   r7,r10,r9
   or     r6,r7,r8
   stwcx. r6,0,r3
   bne .LInterlockedCompareExchangeLoop

+ 5 - 2
rtl/powerpc64/powerpc64.inc

@@ -676,11 +676,14 @@ function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comp
 asm
 .LInterlockedCompareExchangeLoop:
   lwarx  r10,0,r3
+  // lwarx performs an unsigned load -> sign extend since arguments are
+  // longints
+  extsw  r10,r10
   sub    r9,r10,r5
   addic  r9,r9,-1
   subfe  r9,r9,r9
   and    r8,r4,r9
-  andc   r7,r5,r9
+  andc   r7,r10,r9
   or     r6,r7,r8
   stwcx. r6,0,r3
   bne .LInterlockedCompareExchangeLoop
@@ -752,7 +755,7 @@ asm
   addic  r9,r9,-1
   subfe  r9,r9,r9
   and    r8,r4,r9
-  andc   r7,r5,r9
+  andc   r7,r10,r9
   or     r6,r7,r8
   stdcx. r6,0,r3
   bne .LInterlockedCompareExchangeLoop

+ 29 - 0
tests/webtbs/tw18082.pp

@@ -0,0 +1,29 @@
+var
+  l: longint;
+{$ifdef cpu64}
+  i: int64;
+{$endif}
+
+begin
+  l:=-123;
+  if interlockedcompareexchange(l,-1,124)<>-123 then
+    halt(1);
+  if l<>-123 then
+    halt(2);
+  if interlockedcompareexchange(l,-1,-123)<>-123 then
+    halt(3);
+  if l<>-1 then
+    halt(4);
+
+{$ifdef cpu64}
+  i:=-123;
+  if interlockedcompareexchange64(i,-1,124)<>-123 then
+    halt(5);
+  if i<>-123 then
+    halt(6);
+  if interlockedcompareexchange64(i,-1,-123)<>-123 then
+    halt(7);
+  if i<>-1 then
+    halt(8);
+{$endif}
+end.