Bladeren bron

+ added an i8086 asm optimized strpcopy routine

git-svn-id: trunk@31915 -
nickysn 10 jaren geleden
bovenliggende
commit
7fb2418287
1 gewijzigde bestanden met toevoegingen van 47 en 0 verwijderingen
  1. 47 0
      rtl/i8086/stringss.inc

+ 47 - 0
rtl/i8086/stringss.inc

@@ -15,3 +15,50 @@
 
  **********************************************************************}
 
+
+{$ifndef FPC_UNIT_HAS_STRPCOPY}
+{$define FPC_UNIT_HAS_STRPCOPY}
+function strpcopy(d : pchar;const s : string) : pchar;assembler;nostackframe;
+const
+  { used for an offset fixup for accessing the proc parameters in asm routines
+    that use nostackframe. We can't use the parameter name directly, because
+    i8086 doesn't support sp relative addressing. }
+{$ifdef FPC_X86_CODE_FAR}
+  extra_param_offset = 2;
+{$else FPC_X86_CODE_FAR}
+  extra_param_offset = 0;
+{$endif FPC_X86_CODE_FAR}
+asm
+  mov bx, sp
+  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 + 4 + extra_param_offset]  // @d
+  mov di, ss:[bx + 2 + extra_param_offset]  // @s
+{$else FPC_X86_DATA_NEAR}
+  lds si, ss:[bx + 6 + extra_param_offset]  // @d
+  les di, ss:[bx + 2 + extra_param_offset]  // @s
+{$endif FPC_X86_DATA_NEAR}
+  // we will no longer use bx for reading parameters, so save di there
+  // in order to be able to return it in the end
+  mov bx, di
+
+{$ifdef FPC_ENABLED_CLD}
+  cld
+{$endif FPC_ENABLED_CLD}
+  lodsb        // load length in al
+  xor ah, ah
+  xchg cx, ax  // 1 byte shorter than mov
+  shr cx, 1
+  rep movsw
+  adc cx, cx
+  rep movsb
+  xchg ax, cx  // ax := 0 (1 byte shorter than xor al, al)
+  stosb        // zero terminate the destination string
+{$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
+  mov ds, dx
+  mov dx, es   // return segment of d in dx
+{$endif}
+  xchg ax, bx  // return original offset of d in ax
+end;
+{$endif FPC_UNIT_HAS_STRPCOPY}