diff --git a/rtl/linux/system.pp b/rtl/linux/system.pp index 733fe52cac..94fbd44923 100644 --- a/rtl/linux/system.pp +++ b/rtl/linux/system.pp @@ -135,7 +135,10 @@ End. { $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) 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 * First working POSIX *BSD system unit. -} \ No newline at end of file +} diff --git a/rtl/linux/x86_64/syscall.inc b/rtl/linux/x86_64/syscall.inc new file mode 100644 index 0000000000..6a9996abf5 --- /dev/null +++ b/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 +} + diff --git a/rtl/linux/x86_64/syscallh.inc b/rtl/linux/x86_64/syscallh.inc new file mode 100644 index 0000000000..9717794469 --- /dev/null +++ b/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. + + +} diff --git a/rtl/x86_64/math.inc b/rtl/x86_64/math.inc new file mode 100644 index 0000000000..ae0bfa8e5b --- /dev/null +++ b/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 +} diff --git a/rtl/x86_64/set.inc b/rtl/x86_64/set.inc new file mode 100644 index 0000000000..38c7a2a292 --- /dev/null +++ b/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 +} diff --git a/rtl/x86_64/setjump.inc b/rtl/x86_64/setjump.inc new file mode 100644 index 0000000000..b4ec79aa01 --- /dev/null +++ b/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 +} diff --git a/rtl/x86_64/setjumph.inc b/rtl/x86_64/setjumph.inc new file mode 100644 index 0000000000..2823a94efd --- /dev/null +++ b/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 +} diff --git a/rtl/x86_64/strings.inc b/rtl/x86_64/strings.inc index 821333549b..90c54f1db3 100644 --- a/rtl/x86_64/strings.inc +++ b/rtl/x86_64/strings.inc @@ -20,9 +20,164 @@ function strlen(p : pchar) : longint;assembler; {$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$ - 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 + some basic rtl stuff for x86-64 added -} \ No newline at end of file +} diff --git a/rtl/x86_64/x86_64.inc b/rtl/x86_64/x86_64.inc index dc5e9718a7..e92399f4da 100644 --- a/rtl/x86_64/x86_64.inc +++ b/rtl/x86_64/x86_64.inc @@ -123,7 +123,7 @@ small_alignment: end; {$define FPC_SYSTEM_HAS_FILLCHAR} -Procedure FillChar(var x;count:longint;value:byte); +Procedure FillChar(var x;count:longint;value:byte);assembler; asm { rdi destination rsi value (char) @@ -194,6 +194,7 @@ bad_alignment: jmp after_bad_alignment end; +{$define FPC_SYSTEM_HAS_DECLOCKED} { does a thread save inc/dec } function declocked(var l : longint) : boolean;assembler; asm @@ -210,11 +211,12 @@ function declocked(var l : longint) : boolean;assembler; jmp .Ldeclockedend .Ldeclockednolock: {$endif MT} - decl (%rdi); + decl (%rdi) .Ldeclockedend: setzb %al end; +{$define FPC_SYSTEM_HAS_INCLOCKED} procedure inclocked(var l : longint);assembler; asm @@ -237,6 +239,9 @@ procedure inclocked(var l : longint);assembler; { $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 }