Browse Source

+ for a lot of x86-64 dependend files mostly dummies added

florian 22 years ago
parent
commit
a79edeb568

+ 5 - 2
rtl/linux/system.pp

@@ -135,7 +135,10 @@ End.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.6  2002-12-27 18:36:16  peter
+  Revision 1.7  2003-04-30 22:11:06  florian
+    + for a lot of x86-64 dependend files mostly dummies added
+
+  Revision 1.6  2002/12/27 18:36:16  peter
     * Setup ExecPathStr for ParamStr(0)
     * Setup ExecPathStr for ParamStr(0)
 
 
   Revision 1.5  2002/12/18 20:42:29  peter
   Revision 1.5  2002/12/18 20:42:29  peter
@@ -167,4 +170,4 @@ End.
   Revision 1.1  2002/08/19 12:29:11  marco
   Revision 1.1  2002/08/19 12:29:11  marco
    * First working POSIX *BSD system unit.
    * First working POSIX *BSD system unit.
 
 
-}
+}

+ 347 - 0
rtl/linux/x86_64/syscall.inc

@@ -0,0 +1,347 @@
+{
+    $Id$
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 1999-2000 by Michael Van Canneyt,
+    member of the Free Pascal development team.
+
+    The syscalls for the new RTL, moved to platform dependant dir.
+    Old linux calling convention is stil kept.
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+
+{$ASMMODE ATT}
+
+function FpSysCall(sysnr:TSysParam):TSysResult; assembler;[public,alias:'FPC_SYSCALL0'];
+
+asm
+{ load the registers... }
+  movl  sysnr,%eax
+  int   $0x80
+  testl %eax,%eax
+  jns   .LSyscOK
+  negl  %eax
+{$ifdef VER1_0}
+  movl  %eax,Errno
+{$else}
+  movl  %eax,%edx
+  movl  FPC_THREADVAR_RELOCATE,%eax
+  testl %eax,%eax
+  jne   .LThread
+  movl  %edx,Errno+4
+  jmp   .LNoThread
+.LThread:
+  pushl %edx
+  pushl Errno
+  call  *%eax
+  popl  %edx
+  movl  %edx,(%eax)
+.LNoThread:
+  movl  $-1,%eax
+{$endif}
+.LSyscOK:
+end;
+
+function FpSysCall(sysnr,param1 : TSysParam):TSysResult; assembler;[public,alias:'FPC_SYSCALL1'];
+
+asm
+{ load the registers... }
+  movl sysnr,%eax
+  movl param1,%ebx
+  int $0x80
+  testl %eax,%eax
+  jns   .LSyscOK
+  negl  %eax
+{$ifdef VER1_0}
+  movl  %eax,Errno
+{$else}
+  movl  %eax,%edx
+  movl  FPC_THREADVAR_RELOCATE,%eax
+  testl %eax,%eax
+  jne   .LThread
+  movl  %edx,Errno+4
+  jmp   .LNoThread
+.LThread:
+  pushl %edx
+  pushl Errno
+  call  *%eax
+  popl  %edx
+  movl  %edx,(%eax)
+.LNoThread:
+  movl  $-1,%eax
+{$endif}
+.LSyscOK:
+end;
+
+function FpSysCall(sysnr,param1,param2 : TSysParam):TSysResult; assembler;[public,alias:'FPC_SYSCALL2'];
+
+asm
+{ load the registers... }
+  movl sysnr,%eax
+  movl param1,%ebx
+  movl param2,%ecx
+  int $0x80
+  testl %eax,%eax
+  jns   .LSyscOK
+  negl  %eax
+{$ifdef VER1_0}
+  movl  %eax,Errno
+{$else}
+  movl  %eax,%edx
+  movl  FPC_THREADVAR_RELOCATE,%eax
+  testl %eax,%eax
+  jne   .LThread
+  movl  %edx,Errno+4
+  jmp   .LNoThread
+.LThread:
+  pushl %edx
+  pushl Errno
+  call  *%eax
+  popl  %edx
+  movl  %edx,(%eax)
+.LNoThread:
+  movl  $-1,%eax
+{$endif}
+.LSyscOK:
+end;
+
+function FpSysCall(sysnr,param1,param2,param3:TSysParam):TSysResult; assembler;[public,alias:'FPC_SYSCALL3'];
+
+asm
+{ load the registers... }
+  movl sysnr,%eax
+  movl param1,%ebx
+  movl param2,%ecx
+  movl param3,%edx
+  int $0x80
+  testl %eax,%eax
+  jns   .LSyscOK
+  negl  %eax
+{$ifdef VER1_0}
+  movl  %eax,Errno
+{$else}
+  movl  %eax,%edx
+  movl  FPC_THREADVAR_RELOCATE,%eax
+  testl %eax,%eax
+  jne   .LThread
+  movl  %edx,Errno+4
+  jmp   .LNoThread
+.LThread:
+  pushl %edx
+  pushl Errno
+  call  *%eax
+  popl  %edx
+  movl  %edx,(%eax)
+.LNoThread:
+  movl  $-1,%eax
+{$endif}
+.LSyscOK:
+end;
+
+function FpSysCall(sysnr,param1,param2,param3,param4:TSysParam):TSysResult; assembler;[public,alias:'FPC_SYSCALL4'];
+
+asm
+{ load the registers... }
+  movl sysnr,%eax
+  movl param1,%ebx
+  movl param2,%ecx
+  movl param3,%edx
+  movl param4,%esi
+  int $0x80
+  testl %eax,%eax
+  jns   .LSyscOK
+  negl  %eax
+{$ifdef VER1_0}
+  movl  %eax,Errno
+{$else}
+  movl  %eax,%edx
+  movl  FPC_THREADVAR_RELOCATE,%eax
+  testl %eax,%eax
+  jne   .LThread
+  movl  %edx,Errno+4
+  jmp   .LNoThread
+.LThread:
+  pushl %edx
+  pushl Errno
+  call  *%eax
+  popl  %edx
+  movl  %edx,(%eax)
+.LNoThread:
+  movl  $-1,%eax
+{$endif}
+.LSyscOK:
+end;
+
+function FpSysCall(sysnr,param1,param2,param3,param4,param5 : TSysParam):TSysResult; assembler;[public,alias:'FPC_SYSCALL5'];
+
+asm
+{ load the registers... }
+  movl sysnr,%eax
+  movl param1,%ebx
+  movl param2,%ecx
+  movl param3,%edx
+  movl param4,%esi
+  movl param5,%edi
+  int $0x80
+  testl %eax,%eax
+  jns   .LSyscOK
+  negl  %eax
+{$ifdef VER1_0}
+  movl  %eax,Errno
+{$else}
+  movl  %eax,%edx
+  movl  FPC_THREADVAR_RELOCATE,%eax
+  testl %eax,%eax
+  jne   .LThread
+  movl  %edx,Errno+4
+  jmp   .LNoThread
+.LThread:
+  pushl %edx
+  pushl Errno
+  call  *%eax
+  popl  %edx
+  movl  %edx,(%eax)
+.LNoThread:
+  movl  $-1,%eax
+{$endif}
+.LSyscOK:
+end;
+
+{$ifdef notsupported}
+{ Only 5 params are pushed, so it'll not work as expected (PFV) }
+function FpSysCall(sysnr,param1,param2,param3,param4,param5,param6 : TSysParam):TSysResult; assembler;[public,alias:'FPC_SYSCALL6'];
+
+asm
+{ load the registers... }
+  movl sysnr,%eax
+  movl param1,%ebx
+  movl param2,%ecx
+  movl param3,%edx
+  movl param4,%esi
+  movl param5,%edi
+  int $0x80
+  testl %eax,%eax
+  jns   .LSyscOK
+  negl  %eax
+{$ifdef VER1_0}
+  movl  %eax,Errno
+{$else}
+  movl  %eax,%edx
+  movl  FPC_THREADVAR_RELOCATE,%eax
+  testl %eax,%eax
+  jne   .LThread
+  movl  %edx,Errno+4
+  jmp   .LNoThread
+.LThread:
+  pushl %edx
+  pushl Errno
+  call  *%eax
+  popl  %edx
+  movl  %edx,(%eax)
+.LNoThread:
+  movl  $-1,%eax
+{$endif}
+.LSyscOK:
+end;
+{$endif notsupported}
+
+{No debugging for syslinux include !}
+{$IFDEF SYS_LINUX}
+  {$UNDEF SYSCALL_DEBUG}
+{$ENDIF SYS_LINUX}
+
+{*****************************************************************************
+                     --- Main:The System Call Self ---
+*****************************************************************************}
+
+Procedure FpSysCall( callnr:TSysParam;var regs : SysCallregs );assembler;
+{
+  This function puts the registers in place, does the call, and then
+  copies back the registers as they are after the SysCall.
+}
+{$ASMMODE ATT}
+{$define fpc_syscall_ok}
+asm
+{ load the registers... }
+  movl 12(%ebp),%eax
+  movl 4(%eax),%ebx
+  movl 8(%eax),%ecx
+  movl 12(%eax),%edx
+  movl 16(%eax),%esi
+  movl 20(%eax),%edi
+{ set the call number }
+  movl 8(%ebp),%eax
+{ Go ! }
+  int $0x80
+{ Put back the registers... }
+  pushl %eax
+  movl 12(%ebp),%eax
+  movl %edi,20(%eax)
+  movl %esi,16(%eax)
+  movl %edx,12(%eax)
+  movl %ecx,8(%eax)
+  movl %ebx,4(%eax)
+  popl %ebx
+  movl %ebx,(%eax)
+end;
+
+{$ASMMODE DEFAULT}
+
+Function SysCall( callnr:longint;var regs : SysCallregs ):longint;
+{
+  This function serves as an interface to do_SysCall.
+  If the SysCall returned a negative number, it returns -1, and puts the
+  SysCall result in errno. Otherwise, it returns the SysCall return value
+}
+begin
+  FpSysCall(callnr,regs);
+  if regs.reg1<0 then
+   begin
+{$IFDEF SYSCALL_DEBUG}
+     If DoSysCallDebug then
+       debugtxt:=' syscall error: ';
+{$endif}
+     setErrNo(-regs.reg1);
+     SysCall:=-1;
+   end
+  else
+   begin
+{$IFDEF SYSCALL_DEBUG}
+  if DoSysCallDebug then
+       debugtxt:=' syscall returned: ';
+{$endif}
+     SysCall:=regs.reg1;
+     seterrno(0);
+   end;
+{$IFDEF SYSCALL_DEBUG}
+  if DoSysCallDebug then
+    begin
+    inc(lastcnt);
+    if (callnr<>lastcall) or (regs.reg1<>lasteax) then
+      begin
+      if lastcnt>1 then
+        writeln(sys_nr_txt[lastcall],debugtxt,lasteax,' (',lastcnt,'x)');
+      lastcall:=callnr;
+      lasteax:=regs.reg1;
+      lastcnt:=0;
+      writeln(sys_nr_txt[lastcall],debugtxt,lasteax);
+      end;
+    end;
+{$endif}
+end;
+
+
+
+{
+  $Log$
+  Revision 1.1  2003-04-30 22:11:06  florian
+    + for a lot of x86-64 dependend files mostly dummies added
+}
+

+ 76 - 0
rtl/linux/x86_64/syscallh.inc

@@ -0,0 +1,76 @@
+{
+    $Id$
+    Copyright (c) 2002 by Marco van de Voort
+
+    Header for syscall in system unit for i386 *BSD.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+
+}
+
+Type
+
+  TSysResult = longint; // all platforms, cint=32-bit.
+                        // On platforms with off_t =64-bit, people should
+                        // use int64, and typecast all calls that don't
+                        // return off_t to cint.
+
+// I don't think this is going to work on several platforms
+// 64-bit machines don't have only 64-bit params.
+
+  TSysParam  = Longint;
+
+function Do_SysCall(sysnr:TSysParam):TSysResult;  external name 'FPC_SYSCALL0';
+function Do_SysCall(sysnr,param1:TSysParam):TSysResult; external name 'FPC_SYSCALL1';
+function Do_SysCall(sysnr,param1,param2:TSysParam):TSysResult;  external name 'FPC_SYSCALL2';
+function Do_SysCall(sysnr,param1,param2,param3:TSysParam):TSysResult; external name 'FPC_SYSCALL3';
+function Do_SysCall(sysnr,param1,param2,param3,param4:TSysParam):TSysResult; external name 'FPC_SYSCALL4';
+function Do_SysCall(sysnr,param1,param2,param3,param4,param5:TSysParam):TSysResult;  external name 'FPC_SYSCALL5';
+{$ifdef notsupported}
+function Do_SysCall(sysnr,param1,param2,param3,param4,param5,param6:TSysParam):TSysResult;  external name 'FPC_SYSCALL5';
+{$endif notsupported}
+
+{
+  $Log$
+  Revision 1.1  2003-04-30 22:11:06  florian
+    + for a lot of x86-64 dependend files mostly dummies added
+
+  Revision 1.3  2002/12/18 20:41:33  peter
+    * Threadvar support for Errno
+    * Fixed syscall error return check
+    * Uncommented Syscall with 6 parameters, only 5 were really set
+
+  Revision 1.2  2002/12/18 16:46:37  marco
+   * Some mods.
+
+  Revision 1.1  2002/11/16 15:37:47  marco
+   * TSysParam + result moved to -h
+
+  Revision 1.4  2002/10/16 18:44:00  marco
+   * and again for ftruncate (sigh)
+
+  Revision 1.3  2002/10/16 18:41:14  marco
+   * the 7 param syscall (for lseek and truncate) now returns a int64.
+
+  Revision 1.2  2002/09/07 16:01:17  peter
+    * old logs removed and tabs fixed
+
+  Revision 1.1  2002/08/20 08:28:14  marco
+   * Updates for new errno scheme.
+
+
+}

+ 203 - 0
rtl/x86_64/math.inc

@@ -0,0 +1,203 @@
+{
+    $Id$
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 1999-2001 by the Free Pascal development team
+
+    Implementation of mathematical routines (for extended type)
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+{****************************************************************************
+                            FPU Control word
+ ****************************************************************************}
+
+    procedure Set8087CW(cw:word);assembler;
+    asm
+      movw cw,%ax
+      movw %ax,default8087cw
+      fnclex
+      fldcw default8087cw
+    end;
+
+    function Get8087CW:word;assembler;
+    asm
+      pushl $0
+      fnstcw (%rsp)
+      popl %eax
+    end;
+
+{****************************************************************************
+                       EXTENDED data type routines
+ ****************************************************************************}
+
+    {$define FPC_SYSTEM_HAS_PI}
+    function pi : extended;[internproc:in_pi];
+    {$define FPC_SYSTEM_HAS_ABS}
+    function abs(d : extended) : extended;[internproc:in_abs_extended];
+    {$define FPC_SYSTEM_HAS_SQR}
+    function sqr(d : extended) : extended;[internproc:in_sqr_extended];
+    {$define FPC_SYSTEM_HAS_SQRT}
+    function sqrt(d : extended) : extended;[internproc:in_sqrt_extended];
+    {$define FPC_SYSTEM_HAS_ARCTAN}
+    function arctan(d : extended) : extended;[internproc:in_arctan_extended];
+    {$define FPC_SYSTEM_HAS_LN}
+    function ln(d : extended) : extended;[internproc:in_ln_extended];
+    {$define FPC_SYSTEM_HAS_SIN}
+    function sin(d : extended) : extended;[internproc:in_sin_extended];
+    {$define FPC_SYSTEM_HAS_COS}
+    function cos(d : extended) : extended;[internproc:in_cos_extended];
+
+    {$define FPC_SYSTEM_HAS_EXP}
+    function exp(d : extended) : extended;assembler;[internconst:in_const_exp];
+       asm
+            // comes from DJ GPP
+            fldt        d
+            fldl2e
+            fmulp       %st,%st(1)
+            fstcw      .LCW1
+            fstcw      .LCW2
+            andw        $0xf3ff,.LCW2
+            orw         $0x0400,.LCW2
+            fldcw      .LCW2
+            fld         %st(0)
+            frndint
+            fldcw      .LCW1
+            fxch        %st(1)
+            fsub        %st(1),%st
+            f2xm1
+            fld1
+            faddp       %st,%st(1)
+            fscale
+            fstp        %st(1)
+            jmp         .LCW3
+            // store some help data in the data segment
+        .data
+        .LCW1:
+            .word       0
+        .LCW2:
+            .word       0
+        .text
+        .LCW3:
+      end;
+
+
+    {$define FPC_SYSTEM_HAS_FRAC}
+    function frac(d : extended) : extended;assembler;[internconst:in_const_frac];
+      asm
+            subl $16,%esp
+            fnstcw -4(%ebp)
+            fwait
+            movw -4(%ebp),%cx
+            orw $0x0c3f,%cx
+            movw %cx,-8(%ebp)
+            fldcw -8(%ebp)
+            fwait
+            fldt d
+            frndint
+            fldt d
+            fsub %st(1),%st
+            fstp %st(1)
+            fclex
+            fldcw -4(%ebp)
+      end ['ECX'];
+
+
+    {$define FPC_SYSTEM_HAS_INT}
+    function int(d : extended) : extended;assembler;[internconst:in_const_int];
+      asm
+            subl $16,%rsp
+            fnstcw -4(%rbp)
+            fwait
+            movw -4(%rbp),%cx
+            orw $0x0c3f,%cx
+            movw %cx,-8(rbp)
+            fldcw -8(%rbp)
+            fwait
+            fldt d
+            frndint
+            fclex
+            fldcw -4(%rbp)
+      end ['ECX'];
+
+
+
+    {$define FPC_SYSTEM_HAS_TRUNC}
+    function trunc(d : extended) : int64;assembler;[internconst:in_const_trunc];
+      var
+        oldcw,
+        newcw : word;
+        res   : int64;
+      asm
+            fnstcw oldcw
+            fwait
+            movw oldcw,%cx
+            orw $0x0c3f,%cx
+            movw %cx,newcw
+            fldcw newcw
+            fwait
+            fldt d
+            fistpq res
+            movl res,%eax
+            movl res+4,%edx
+            fldcw oldcw
+      end ['EAX','ECX','EDX'];
+
+
+    {$define FPC_SYSTEM_HAS_ROUND}
+{$ifdef hascompilerproc}
+    function round(d : extended) : int64;[internconst:in_const_round, external name 'FPC_ROUND'];
+
+    function fpc_round(d : extended) : int64;assembler;[public, alias:'FPC_ROUND'];{$ifdef hascompilerproc}compilerproc;{$endif hascompilerproc}
+{$else}
+    function round(d : extended) : int64;assembler;[internconst:in_const_round];
+{$endif hascompilerproc}
+      var
+        oldcw,
+        newcw : word;
+        res   : int64;
+      asm
+            fnstcw oldcw
+            fwait
+            movw $0x1372,newcw
+            fldcw newcw
+            fwait
+            fldt d
+            fistpq res
+            movl res,%eax
+            movl res+4,%edx
+            fldcw oldcw
+      end ['EAX','EDX'];
+
+
+    {$define FPC_SYSTEM_HAS_POWER}
+   function power(bas,expo : extended) : extended;
+     begin
+        if bas=0 then
+          begin
+            if expo<>0 then
+              power:=0.0
+            else
+              HandleError(207);
+          end
+        else if expo=0 then
+         power:=1
+        else
+        { bas < 0 is not allowed }
+         if bas<0 then
+          handleerror(207)
+         else
+          power:=exp(ln(bas)*expo);
+     end;
+
+{
+  $Log$
+  Revision 1.1  2003-04-30 22:11:06  florian
+    + for a lot of x86-64 dependend files mostly dummies added
+}

+ 21 - 0
rtl/x86_64/set.inc

@@ -0,0 +1,21 @@
+{
+    $Id$
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2002 by the Free Pascal development team
+
+    Include file with set operations called by the compiler
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+{
+  $Log$
+  Revision 1.1  2003-04-30 22:11:06  florian
+    + for a lot of x86-64 dependend files mostly dummies added
+}

+ 32 - 0
rtl/x86_64/setjump.inc

@@ -0,0 +1,32 @@
+{
+    $Id$
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2003 by Florian Klaempfl and other members of the
+    Free Pascal development team
+
+    SetJmp and LongJmp implementation for exception handling
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+function setjmp(var S : jmp_buf) : longint;assembler;[Public, alias : 'FPC_SETJMP'];
+{$warning FIX ME!!}
+  asm
+  end;
+
+procedure longjmp(var S : jmp_buf;value : longint);assembler;[Public, alias : 'FPC_LONGJMP'];
+{$warning FIX ME!!}
+  asm
+  end;
+
+{
+  $Log$
+  Revision 1.1  2003-04-30 22:11:06  florian
+    + for a lot of x86-64 dependend files mostly dummies added
+}

+ 31 - 0
rtl/x86_64/setjumph.inc

@@ -0,0 +1,31 @@
+{
+    $Id$
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2000-2002 by Jonas Maebe and other members of the
+    Free Pascal development team
+
+    SetJmp/Longjmp declarations
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+type
+   jmp_buf = packed record
+     {$warning FIX ME!!}
+   end;
+   pjmp_buf = ^jmp_buf;
+
+function setjmp(var S : jmp_buf) : longint;
+procedure longjmp(var S : jmp_buf;value : longint);
+
+{
+  $Log$
+  Revision 1.1  2003-04-30 22:11:06  florian
+    + for a lot of x86-64 dependend files mostly dummies added
+}

+ 157 - 2
rtl/x86_64/strings.inc

@@ -20,9 +20,164 @@
 function strlen(p : pchar) : longint;assembler;
 function strlen(p : pchar) : longint;assembler;
 {$i strlen.inc}
 {$i strlen.inc}
 
 
+
+{$define FPC_UNIT_HAS_STRCOPY}
+{ Created from glibc: libc/sysdeps/x86_64/strcpy.S Version 1.2 }
+function strcopy(dest,source : pchar) : pchar;assembler;
+asm
+        movq %rsi, %rcx                { Source register. }
+        andl $7, %ecx                  { mask alignment bits }
+        movq %rdi, %rdx                { Duplicate destination pointer.  }
+
+        jz LFPC_STRCOPY_5              { aligned => start loop }
+
+        neg %ecx                       { We need to align to 8 bytes.  }
+        addl $8,%ecx
+
+        { Search the first bytes directly.  }
+LFPC_STRCOPY_0:
+        movb        (%rsi), %al        { Fetch a byte }
+        testb       %al, %al           { Is it NUL? }
+        movb        %al, (%rdx)        { Store it }
+        jz          LFPC_STRCOPY_4     { If it was NUL, done! }
+        incq        %rsi
+        incq        %rdx
+        decl        %ecx
+        jnz         LFPC_STRCOPY_0
+
+LFPC_STRCOPY_5:
+        movq        $0xfefefefefefefeff,%r8
+
+        { Now the sources is aligned.  Unfortunatly we cannot force
+           to have both source and destination aligned, so ignore the
+           alignment of the destination.  }
+        .p2align 4
+LFPC_STRCOPY_1:
+        { 1st unroll.  }
+        movq        (%rsi), %rax       { Read double word (8 bytes).  }
+        addq        $8, %rsi           { Adjust pointer for next word.  }
+        movq        %rax, %r9          { Save a copy for NUL finding.  }
+        addq        %r8, %r9           { add the magic value to the word.  We get
+                                         carry bits reported for each byte which
+                                         is *not* 0 }
+        jnc         LFPC_STRCOPY_3     { highest byte is NUL => return pointer }
+        xorq        %rax, %r9          { (word+magic)^word }
+        orq         %r8, %r9           { set all non-carry bits }
+        incq        %r9                { add 1: if one carry bit was *not* set
+                                         the addition will not result in 0.  }
+
+        jnz         LFPC_STRCOPY_3                { found NUL => return pointer }
+
+        movq        %rax, (%rdx)        { Write value to destination.  }
+        addq        $8, %rdx        { Adjust pointer.  }
+
+        { 2nd unroll.  }
+        movq        (%rsi), %rax        { Read double word (8 bytes).  }
+        addq        $8, %rsi        { Adjust pointer for next word.  }
+        movq        %rax, %r9        { Save a copy for NUL finding.  }
+        addq        %r8, %r9        { add the magic value to the word.  We get
+                                   carry bits reported for each byte which
+                                   is *not* 0 }
+        jnc         LFPC_STRCOPY_3                { highest byte is NUL => return pointer }
+        xorq        %rax, %r9        { (word+magic)^word }
+        orq         %r8, %r9        { set all non-carry bits }
+        incq        %r9                { add 1: if one carry bit was *not* set
+                                   the addition will not result in 0.  }
+
+        jnz         LFPC_STRCOPY_3                { found NUL => return pointer }
+
+        movq        %rax, (%rdx)        { Write value to destination.  }
+        addq        $8, %rdx        { Adjust pointer.  }
+
+        { 3rd unroll.  }
+        movq        (%rsi), %rax        { Read double word (8 bytes).  }
+        addq        $8, %rsi        { Adjust pointer for next word.  }
+        movq        %rax, %r9        { Save a copy for NUL finding.  }
+        addq        %r8, %r9        { add the magic value to the word.  We get
+                                   carry bits reported for each byte which
+                                   is *not* 0 }
+        jnc        LFPC_STRCOPY_3                { highest byte is NUL => return pointer }
+        xorq        %rax, %r9        { (word+magic)^word }
+        orq        %r8, %r9        { set all non-carry bits }
+        incq        %r9                { add 1: if one carry bit was *not* set
+                                   the addition will not result in 0.  }
+
+        jnz         LFPC_STRCOPY_3                { found NUL => return pointer }
+
+        movq        %rax, (%rdx)        { Write value to destination.  }
+        addq        $8, %rdx        { Adjust pointer.  }
+
+        { 4th unroll.  }
+        movq        (%rsi), %rax        { Read double word (8 bytes).  }
+        addq        $8, %rsi        { Adjust pointer for next word.  }
+        movq        %rax, %r9        { Save a copy for NUL finding.  }
+        addq        %r8, %r9        { add the magic value to the word.  We get
+                                   carry bits reported for each byte which
+                                   is *not* 0 }
+        jnc         LFPC_STRCOPY_3                { highest byte is NUL => return pointer }
+        xorq        %rax, %r9        { (word+magic)^word }
+        orq         %r8, %r9        { set all non-carry bits }
+        incq        %r9                { add 1: if one carry bit was *not* set
+                                   the addition will not result in 0.  }
+
+        jnz         LFPC_STRCOPY_3                { found NUL => return pointer }
+
+        movq        %rax, (%rdx)        { Write value to destination.  }
+        addq        $8, %rdx        { Adjust pointer.  }
+        jmp         LFPC_STRCOPY_1                { Next iteration.  }
+
+        { Do the last few bytes. %rax contains the value to write.
+           The loop is unrolled twice.  }
+        .p2align 4
+LFPC_STRCOPY_3:
+        { Note that stpcpy needs to return with the value of the NUL
+           byte.  }
+        movb        %al, (%rdx)        { 1st byte.  }
+        testb       %al, %al        { Is it NUL.  }
+        jz          LFPC_STRCOPY_4                { yes, finish.  }
+        incq        %rdx                { Increment destination.  }
+        movb        %ah, (%rdx)        { 2nd byte.  }
+        testb       %ah, %ah        { Is it NUL?.  }
+        jz          LFPC_STRCOPY_4                { yes, finish.  }
+        incq        %rdx                { Increment destination.  }
+        shrq        $16, %rax        { Shift...  }
+        jmp         LFPC_STRCOPY_3                { and look at next two bytes in %rax.  }
+
+LFPC_STRCOPY_4:
+        movq        %rdi, %rax        { Source is return value.  }
+        retq
+end;
+
+
+{$define FPC_UNIT_HAS_STRCOMP}
+{ Created from glibc: libc/sysdeps/x86_64/strcmp.S Version 1.2 }
+function StrComp(Str1, Str2: PChar): StrLenInt;
+asm
+FPC_STRCMP_LOOP:
+        movb        (%rdi), %al
+        cmpb        (%rsi), %al
+        jne         FPC_STRCMP_NEG
+        incq        %rdi
+        incq        %rsi
+        testb       %al, %al
+        jnz         FPC_STRCMP_LOOP
+
+        xorq        %rax, %rax
+        ret
+
+FPC_STRCMP_NEG:
+        movl        $1, %eax
+        movl        $-1, %ecx
+        cmovbl      %ecx, %eax
+        ret
+end;
+
 {
 {
   $Log$
   $Log$
-  Revision 1.1  2003-04-30 16:36:39  florian
+  Revision 1.2  2003-04-30 22:11:06  florian
+    + for a lot of x86-64 dependend files mostly dummies added
+
+  Revision 1.1  2003/04/30 16:36:39  florian
     + support for generic pchar routines added
     + support for generic pchar routines added
     + some basic rtl stuff for x86-64 added
     + some basic rtl stuff for x86-64 added
-}
+}

+ 8 - 3
rtl/x86_64/x86_64.inc

@@ -123,7 +123,7 @@ small_alignment:
   end;
   end;
 
 
 {$define FPC_SYSTEM_HAS_FILLCHAR}
 {$define FPC_SYSTEM_HAS_FILLCHAR}
-Procedure FillChar(var x;count:longint;value:byte);
+Procedure FillChar(var x;count:longint;value:byte);assembler;
   asm
   asm
     { rdi   destination
     { rdi   destination
       rsi   value (char)
       rsi   value (char)
@@ -194,6 +194,7 @@ bad_alignment:
      jmp after_bad_alignment
      jmp after_bad_alignment
   end;
   end;
 
 
+{$define FPC_SYSTEM_HAS_DECLOCKED}
 { does a thread save inc/dec }
 { does a thread save inc/dec }
 function declocked(var l : longint) : boolean;assembler;
 function declocked(var l : longint) : boolean;assembler;
   asm
   asm
@@ -210,11 +211,12 @@ function declocked(var l : longint) : boolean;assembler;
      jmp        .Ldeclockedend
      jmp        .Ldeclockedend
 .Ldeclockednolock:
 .Ldeclockednolock:
 {$endif MT}
 {$endif MT}
-     decl       (%rdi);
+     decl       (%rdi)
 .Ldeclockedend:
 .Ldeclockedend:
      setzb      %al
      setzb      %al
   end;
   end;
 
 
+{$define FPC_SYSTEM_HAS_INCLOCKED}
 procedure inclocked(var l : longint);assembler;
 procedure inclocked(var l : longint);assembler;
 
 
   asm
   asm
@@ -237,6 +239,9 @@ procedure inclocked(var l : longint);assembler;
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.1  2003-01-06 19:40:18  florian
+  Revision 1.2  2003-04-30 22:11:06  florian
+    + for a lot of x86-64 dependend files mostly dummies added
+
+  Revision 1.1  2003/01/06 19:40:18  florian
     + initial revision
     + initial revision
 }
 }