Browse Source

+ implemented InterLockedCompareExchange for i8086

git-svn-id: trunk@27410 -
nickysn 11 years ago
parent
commit
d24cfbcc8e
1 changed files with 28 additions and 4 deletions
  1. 28 4
      rtl/i8086/i8086.inc

+ 28 - 4
rtl/i8086/i8086.inc

@@ -298,10 +298,34 @@ asm
 {$endif}
 end;
 
-{TODO: implement}
-function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint;
-begin
-  runerror(304);
+{TODO: use smallint?}
+function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint;assembler;
+asm
+{$ifdef FPC_X86_DATA_NEAR}
+  mov bx, [Target]  // Target
+{$else FPC_X86_DATA_NEAR}
+  mov cx, ds
+  lds bx, [Target]  // Target
+{$endif FPC_X86_DATA_NEAR}
+  mov di, [Comperand]
+  mov si, [Comperand+2]
+  pushf
+  cli
+  mov ax, [bx]
+  mov dx, [bx+2]
+  cmp ax, di
+  jne @@not_equal
+  cmp dx, si
+  jne @@not_equal
+  mov di, [NewValue]
+  mov si, [NewValue+2]
+  mov [bx], di
+  mov [bx+2], si
+@@not_equal:
+  popf
+{$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
+  mov ds, cx
+{$endif}
 end;