Browse Source

+ added 16-bit versions of the InterLocked* functions for i8086

git-svn-id: trunk@35149 -
nickysn 8 years ago
parent
commit
ca46040728
2 changed files with 111 additions and 5 deletions
  1. 97 5
      rtl/i8086/i8086.inc
  2. 14 0
      rtl/inc/systemh.inc

+ 97 - 5
rtl/i8086/i8086.inc

@@ -606,7 +606,25 @@ asm
 {$endif FPC_X86_DATA_NEAR}
 end;
 
-{TODO: use smallint?}
+function InterLockedDecrement (var Target: smallint) : smallint;nostackframe;assembler;
+asm
+  mov si, sp
+{$ifdef FPC_X86_DATA_NEAR}
+  mov bx, ss:[si + 2 + extra_param_offset]  // Target
+{$else FPC_X86_DATA_NEAR}
+  mov cx, ds
+  lds bx, ss:[si + 2 + extra_param_offset]  // Target
+{$endif FPC_X86_DATA_NEAR}
+  pushf
+  cli
+  sub word [bx], 1
+  mov ax, [bx]
+  popf
+{$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
+  mov ds, cx
+{$endif}
+end;
+
 function InterLockedDecrement (var Target: longint) : longint;nostackframe;assembler;
 asm
   mov si, sp
@@ -628,7 +646,25 @@ asm
 {$endif}
 end;
 
-{TODO: use smallint?}
+function InterLockedIncrement (var Target: smallint) : smallint;nostackframe;assembler;
+asm
+  mov si, sp
+{$ifdef FPC_X86_DATA_NEAR}
+  mov bx, ss:[si + 2 + extra_param_offset]  // Target
+{$else FPC_X86_DATA_NEAR}
+  mov cx, ds
+  lds bx, ss:[si + 2 + extra_param_offset]  // Target
+{$endif FPC_X86_DATA_NEAR}
+  pushf
+  cli
+  add word [bx], 1
+  mov ax, [bx]
+  popf
+{$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
+  mov ds, cx
+{$endif}
+end;
+
 function InterLockedIncrement (var Target: longint) : longint;nostackframe;assembler;
 asm
   mov si, sp
@@ -650,7 +686,22 @@ asm
 {$endif}
 end;
 
-{TODO: use smallint?}
+function InterLockedExchange (var Target: smallint;Source : smallint) : smallint;nostackframe;assembler;
+asm
+  mov si, sp
+{$ifdef FPC_X86_DATA_NEAR}
+  mov bx, ss:[si + 4 + extra_param_offset]  // Target
+{$else FPC_X86_DATA_NEAR}
+  mov cx, ds
+  lds bx, ss:[si + 4 + extra_param_offset]  // Target
+{$endif FPC_X86_DATA_NEAR}
+  mov ax, ss:[si + 2 + extra_param_offset]  // Source
+  xchg word [bx], ax
+{$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
+  mov ds, cx
+{$endif}
+end;
+
 function InterLockedExchange (var Target: longint;Source : longint) : longint;nostackframe;assembler;
 asm
   mov si, sp
@@ -672,7 +723,26 @@ asm
 {$endif}
 end;
 
-{TODO: use smallint?}
+function InterLockedExchangeAdd (var Target: smallint;Source : smallint) : smallint;nostackframe;assembler;
+asm
+  mov si, sp
+{$ifdef FPC_X86_DATA_NEAR}
+  mov bx, ss:[si + 4 + extra_param_offset]  // Target
+{$else FPC_X86_DATA_NEAR}
+  mov cx, ds
+  lds bx, ss:[si + 4 + extra_param_offset]  // Target
+{$endif FPC_X86_DATA_NEAR}
+  mov di, ss:[si + 2 + extra_param_offset]  // Source
+  pushf
+  cli
+  mov ax, [bx]
+  add word [bx], di
+  popf
+{$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
+  mov ds, cx
+{$endif}
+end;
+
 function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint;nostackframe;assembler;
 asm
   mov si, sp
@@ -696,7 +766,29 @@ asm
 {$endif}
 end;
 
-{TODO: use smallint?}
+function InterlockedCompareExchange(var Target: smallint; NewValue: smallint; Comperand: smallint): smallint;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]
+  pushf
+  cli
+  mov ax, [bx]
+  cmp ax, di
+  jne @@not_equal
+  mov di, [NewValue]
+  mov [bx], di
+@@not_equal:
+  popf
+{$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
+  mov ds, cx
+{$endif}
+end;
+
 function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint;assembler;
 asm
 {$ifdef FPC_X86_DATA_NEAR}

+ 14 - 0
rtl/inc/systemh.inc

@@ -1377,6 +1377,13 @@ Function GetProcessID:SizeUInt;
 Function GetThreadID:TThreadID;{$ifdef SYSTEMINLINE}inline;{$endif}
 {$endif FPC_HAS_FEATURE_PROCESSES}
 
+{$ifdef cpu16}
+function InterLockedIncrement (var Target: smallint) : smallint; public name 'FPC_INTERLOCKEDINCREMENT16';
+function InterLockedDecrement (var Target: smallint) : smallint; public name 'FPC_INTERLOCKEDDECREMENT16';
+function InterLockedExchange (var Target: smallint;Source : smallint) : smallint; public name 'FPC_INTERLOCKEDEXCHANGE16';
+function InterLockedExchangeAdd (var Target: smallint;Source : smallint) : smallint; public name 'FPC_INTERLOCKEDEXCHANGEADD16';
+function InterlockedCompareExchange(var Target: smallint; NewValue: smallint; Comperand: smallint): smallint; public name 'FPC_INTERLOCKEDCOMPAREEXCHANGE16';
+{$endif cpu16}
 function InterLockedIncrement (var Target: longint) : longint; public name 'FPC_INTERLOCKEDINCREMENT';
 function InterLockedDecrement (var Target: longint) : longint; public name 'FPC_INTERLOCKEDDECREMENT';
 function InterLockedExchange (var Target: longint;Source : longint) : longint; public name 'FPC_INTERLOCKEDEXCHANGE';
@@ -1406,6 +1413,13 @@ function InterlockedCompareExchange(var Target: Pointer; NewValue: Pointer; Comp
 function InterlockedCompareExchangePointer(var Target: Pointer; NewValue: Pointer; Comperand: Pointer): Pointer; external name 'FPC_INTERLOCKEDCOMPAREEXCHANGE';
 {$endif cpu64}
 { unsigned overloads }
+{$ifdef cpu16}
+function InterLockedIncrement (var Target: word) : word; external name 'FPC_INTERLOCKEDINCREMENT16';
+function InterLockedDecrement (var Target: word) : word; external name 'FPC_INTERLOCKEDDECREMENT16';
+function InterLockedExchange (var Target: word;Source : word) : word; external name 'FPC_INTERLOCKEDEXCHANGE16';
+function InterLockedExchangeAdd (var Target: word;Source : word) : word; external name 'FPC_INTERLOCKEDEXCHANGEADD16';
+function InterlockedCompareExchange(var Target: word; NewValue: word; Comperand: word): word; external name 'FPC_INTERLOCKEDCOMPAREEXCHANGE16';
+{$endif cpu16}
 function InterLockedIncrement (var Target: cardinal) : cardinal; external name 'FPC_INTERLOCKEDINCREMENT';
 function InterLockedDecrement (var Target: cardinal) : cardinal; external name 'FPC_INTERLOCKEDDECREMENT';
 function InterLockedExchange (var Target: cardinal;Source : cardinal) : cardinal; external name 'FPC_INTERLOCKEDEXCHANGE';