Browse Source

+ i8086 asm optimized implementation of CompareDWord

git-svn-id: trunk@32039 -
nickysn 9 years ago
parent
commit
7ed7b090fe
1 changed files with 63 additions and 0 deletions
  1. 63 0
      rtl/i8086/i8086.inc

+ 63 - 0
rtl/i8086/i8086.inc

@@ -370,6 +370,69 @@ end;
 {$endif FPC_SYSTEM_HAS_COMPAREWORD}
 
 
+{$ifndef FPC_SYSTEM_HAS_COMPAREDWORD}
+{$define FPC_SYSTEM_HAS_COMPAREDWORD}
+function CompareDWord(Const buf1,buf2;len:SizeInt):SizeInt; assembler; nostackframe;
+asm
+  xor ax, ax  // initialize ax=0 (it's the result register, we never use it for anything else in this function)
+  mov bx, sp
+  mov cx, ss:[bx + 2 + extra_param_offset]  // len
+  jcxz @@Done
+  cmp cx, 4000h
+  jb @@NotTooBig
+  mov cx, 4000h
+@@NotTooBig:
+  shl cx, 1
+
+  mov dx, ds  // for far data models, backup ds; for near data models, use to initialize es
+{$ifdef FPC_X86_DATA_NEAR}
+  mov es, dx
+  mov si, ss:[bx + 6 + extra_param_offset]  // @buf1
+  mov di, ss:[bx + 4 + extra_param_offset]  // @buf2
+{$else FPC_X86_DATA_NEAR}
+  lds si, ss:[bx + 8 + extra_param_offset]  // @buf1
+  les di, ss:[bx + 4 + extra_param_offset]  // @buf2
+{$endif FPC_X86_DATA_NEAR}
+
+{$ifdef FPC_ENABLED_CLD}
+  cld
+{$endif FPC_ENABLED_CLD}
+  repe cmpsw
+  je @@Equal
+
+  // ax is 0
+  sbb ax, ax
+  shl ax, 1
+  inc ax
+
+  shr cx, 1
+  jnc @@Skip
+
+  xchg ax, bx
+  xor ax, ax
+  cmpsw
+  je @@hi_equal
+  // ax is 0
+  sbb ax, ax
+  shl ax, 1
+  inc ax
+  jmp @@Skip
+
+@@hi_equal:
+  xchg ax, bx
+
+@@Equal:
+  // ax is 0
+@@Skip:
+
+{$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
+  mov ds, dx
+{$endif}
+@@Done:
+end;
+{$endif FPC_SYSTEM_HAS_COMPAREDWORD}
+
+
 {$define FPC_SYSTEM_HAS_SPTR}
 Function Sptr : Pointer;assembler;nostackframe;
 asm