From 4b732161174fa5f217429390834bd865a9245150 Mon Sep 17 00:00:00 2001 From: michael Date: Mon, 8 Jun 1998 15:32:08 +0000 Subject: [PATCH] + Split rtti according to processor. Implemented optimized i386 code. --- rtl/i386/rttip.inc | 269 +++++++++++++++++++++++++++++++++++++++++ rtl/inc/rtti.inc | 112 ++--------------- rtl/m68k/rttip.inc | 132 ++++++++++++++++++++ rtl/template/rttip.inc | 132 ++++++++++++++++++++ 4 files changed, 540 insertions(+), 105 deletions(-) create mode 100644 rtl/i386/rttip.inc create mode 100644 rtl/m68k/rttip.inc create mode 100644 rtl/template/rttip.inc diff --git a/rtl/i386/rttip.inc b/rtl/i386/rttip.inc new file mode 100644 index 0000000000..ad71a17c28 --- /dev/null +++ b/rtl/i386/rttip.inc @@ -0,0 +1,269 @@ +{ + $Id$ + This file is part of the Free Pascal run time library. + Copyright (c) 1993,97 by xxxx + member of the Free Pascal development team + + 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. + + **********************************************************************} + +{ Run-Time type information routines - processor dependent part } + +Procedure Initialize (Data,TypeInfo : pointer);[Alias : 'INITIALIZE'];assembler; + +asm +# Save registers + push %esp + movl %esp,%ebp + push %eax + push %ebx + push %ecx + push %edx +# decide what type it is + movl 12(%ebp),%ebx + movb (%ebx),%al + subb $10,%al + jz .DoAnsiStringInit + decb %al + jz .DoAnsiStringInit + subb $2,%al + jz .DoArrayInit + decb %al + jz .DoRecordInit + jmp .ExitInitialize +.DoRecordInit: + incl %ebx + movzbl (%ebx),%eax +# Skip also recordsize. + addl $5,%eax + addl %eax,%ebx +# %ebx points to element count. Set in %edx + movl (%ebx),%edx + addl $4,%ebx +# %ebx points to First element in record +.MyRecordInitLoop: + decl %edx + jl .ExitInitialize +# Calculate data + movl 8(%ebp),%eax + addl (%ebx),%eax + addl $4,%ebx +# Push type + pushl (%ebx) + addl $4,%ebx +# push data + pushl %eax + call INITIALIZE + jmp .MyRecordInitLoop +# Array handling +.DoArrayInit: +# %ebx points to size. Put size in ecx + movl (%ebx),%ecx + addl $4, %ebx +# %ebx points to count. Put count in %edx + movl (%ebx),%edx + addl $4, %ebx +# %ebx points to type. Put into ebx. +# Start treating elements. +.MyArrayInitLoop: + decl %edx + jl .ExitInitialize +# push type + pushl (%ebx) +# calculate data + movl %ecx,%eax + imull %edx,%eax + addl 8(%ebp),%eax +# push data + pushl %eax + call INITIALIZE + jmp .MyArrayInitLoop +# AnsiString handling : +.DoAnsiStringInit: + movl $0,8(%ebp) +.ExitInitialize: + pop %edx + pop %ecx + pop %ebx + pop %eax + leave + ret $8 +end; + +Procedure Finalize (Data,TypeInfo: Pointer);[Alias : 'FINALIZE']; assembler; + +asm +# Save registers + push %esp + movl %esp,%ebp + push %eax + push %ebx + push %ecx + push %edx +# decide what type it is + movl 12(%ebp),%ebx + movb (%ebx),%al + subb $10,%al + jz .DoAnsiStringFinal + decb %al + jz .DoAnsiStringFinal + subb $2,%al + jz .DoArrayFinal + decb %al + jz .DoRecordFinal + jmp .ExitFinalize +.DoRecordFinal: + incl %ebx + movzbl (%ebx),%eax +# Skip also recordsize. + addl $5,%eax + addl %eax,%ebx +# %ebx points to element count. Set in %edx + movl (%ebx),%edx + addl $4,%ebx +# %ebx points to First element in record +.MyRecordFinalLoop: + decl %edx + jl .ExitFinalize +# Calculate data + movl 8(%ebp),%eax + addl (%ebx),%eax + addl $4,%ebx +# Push type + pushl (%ebx) + addl $4,%ebx +# push data + pushl %eax + call FINALIZE + jmp .MyRecordFinalLoop +# Array handling +.DoArrayFinal: +# %ebx points to size. Put size in ecx + movl (%ebx),%ecx + addl $4, %ebx +# %ebx points to count. Put count in %edx + movl (%ebx),%edx + addl $4, %ebx +# %ebx points to type. Put into ebx. +# Start treating elements. +.MyArrayFinalLoop: + decl %edx + jl .ExitFinalize +# push type + pushl (%ebx) +# calculate data + movl %ecx,%eax + imull %edx,%eax + addl 8(%ebp),%eax +# push data + pushl %eax + call FINALIZE + jmp .MyArrayFinalLoop +# AnsiString handling : +.DoAnsiStringFinal: + movl 8(%ebp),%eax + pushl %eax + call DECR_ANSI_REF +.ExitFinalize: + pop %edx + pop %ecx + pop %ebx + pop %eax + ret $8 +end; + +Procedure Addref (Data,TypeInfo : Pointer); [alias : 'ADDREF'];Assembler; + +asm +# Save registers + push %esp + movl %esp,%ebp + push %eax + push %ebx + push %ecx + push %edx +# decide what type it is + movl 12(%ebp),%ebx + movb (%ebx),%al + subb $10,%al + jz .DoAnsiStringAddRef + decb %al + jz .DoAnsiStringAddRef + subb $2,%al + jz .DoArrayAddRef + decb %al + jz .DoRecordAddRef + jmp .ExitAddRef +.DoRecordAddRef: + incl %ebx + movzbl (%ebx),%eax +# Skip also recordsize. + addl $5,%eax + addl %eax,%ebx +# %ebx points to element count. Set in %edx + movl (%ebx),%edx + addl $4,%ebx +# %ebx points to First element in record +.MyRecordAddRefLoop: + decl %edx + jl .ExitAddRef +# Calculate data + movl 8(%ebp),%eax + addl (%ebx),%eax + addl $4,%ebx +# Push type + pushl (%ebx) + addl $4,%ebx +# push data + pushl %eax + call ADDREF + jmp .MyRecordAddRefLoop +# Array handling +.DoArrayAddRef: +# %ebx points to size. Put size in ecx + movl (%ebx),%ecx + addl $4, %ebx +# %ebx points to count. Put count in %edx + movl (%ebx),%edx + addl $4, %ebx +# %ebx points to type. Put into ebx. +# Start treating elements. +.MyArrayAddRefLoop: + decl %edx + jl .ExitAddRef +# push type + pushl (%ebx) +# calculate data + movl %ecx,%eax + imull %edx,%eax + addl 8(%ebp),%eax +# push data + pushl %eax + call ADDREF + jmp .MyArrayAddRefLoop +# AnsiString handling : +.DoAnsiStringAddRef: + movl 8(%ebp),%eax + pushl %eax + call DECR_ANSI_REF +.ExitAddRef: + pop %edx + pop %ecx + pop %ebx + pop %eax + leave + ret $8 +end; + +{ + $Log$ + Revision 1.1 1998-06-08 15:32:12 michael + + Split rtti according to processor. Implemented optimized i386 code. + +} \ No newline at end of file diff --git a/rtl/inc/rtti.inc b/rtl/inc/rtti.inc index f2173e772f..1096d79211 100644 --- a/rtl/inc/rtti.inc +++ b/rtl/inc/rtti.inc @@ -69,111 +69,13 @@ TArrayRec = record Info : Pointer; end; +{ The actual Routines are implemented per processor. } -Procedure Initialize (Data,TypeInfo : pointer);[Alias : 'INITIALIZE']; +{$i rttip.inc} -Var Temp : PByte; - I : longint; - Size,Count : longint; - TInfo : Pointer; - -begin - Temp:=PByte(TypeInfo); - case temp^ of - tkLstring,tkWstring : PPchar(Data)^:=Nil; - tkArray : - begin - temp:=Temp+1; - I:=temp^; - temp:=temp+(I+1); // skip name string; - Size:=PArrayRec(Temp)^.Size; // get element size - Count:=PArrayRec(Temp)^.Count; // get element Count - TInfo:=PArrayRec(Temp)^.Info; // Get element info - For I:=0 to Count-1 do - Initialize (Data+(I*size),TInfo); - end; - tkrecord : - begin - Temp:=Temp+1; - I:=Temp^; - temp:=temp+(I+1); // skip name string; - Size:=PRecRec(Temp)^.Size; // get record size; not needed. - Count:=PRecRec(Temp)^.Count; // get element Count - For I:=1 to count Do - With PRecRec(Temp)^.elements[I] do - Initialize (Data+Offset,Info); - end; - end; -end; +{ + $Log$ + Revision 1.2 1998-06-08 15:32:15 michael + + Split rtti according to processor. Implemented optimized i386 code. -Procedure Finalize (Data,TypeInfo: Pointer);[Alias : 'FINALIZE']; - -Var Temp : PByte; - I : longint; - Size,Count : longint; - TInfo : Pointer; - -begin - Temp:=PByte(TypeInfo); - case temp^ of - tkLstring,tkWstring : Decr_Ansi_ref(Data); - tkArray : - begin - Temp:=Temp+1; - I:=temp^; - temp:=temp+(I+1); // skip name string; - Size:=PArrayRec(Temp)^.Size; // get element size - Count:=PArrayRec(Temp)^.Count; // get element Count - TInfo:=PArrayRec(Temp)^.Info; // Get element info - For I:=0 to Count-1 do - Finalize (Data+(I*size),TInfo); - end; - tkrecord : - begin - Temp:=Temp+1; - I:=Temp^; - temp:=temp+(I+1); // skip name string; - Size:=PRecRec(Temp)^.Size; // get record size; not needed. - Count:=PRecRec(Temp)^.Count; // get element Count - For I:=1 to count do - With PRecRec(Temp)^.elements[I] do - Finalize (Data+Offset,Info); - end; - end; -end; - -Procedure Addref (Data,TypeInfo : Pointer); [alias : 'ADDREF']; - -Var Temp : PByte; - I : longint; - Size,Count : longint; - TInfo : Pointer; - -begin - Temp:=PByte(TypeInfo); - case temp^ of - tkLstring,tkWstring : Incr_Ansi_ref(Data); - tkArray : - begin - Temp:=Temp+1; - I:=temp^; - temp:=temp+(I+1); // skip name string; - Size:=PArrayRec(Temp)^.Size; // get element size - Count:=PArrayRec(Temp)^.Count; // get element Count - TInfo:=PArrayRec(Temp)^.Info; // Get element info - For I:=0 to Count-1 do - Finalize (Data+(I*size),TInfo); - end; - tkrecord : - begin - Temp:=Temp+1; - I:=Temp^; - temp:=temp+(I+1); // skip name string; - Size:=PRecRec(Temp)^.Size; // get record size; not needed. - Count:=PRecRec(Temp)^.Count; // get element Count - For I:=1 to count do - With PRecRec(Temp)^.elements[I] do - Finalize (Data+Offset,Info); - end; - end; -end; +} diff --git a/rtl/m68k/rttip.inc b/rtl/m68k/rttip.inc new file mode 100644 index 0000000000..6f032bc66c --- /dev/null +++ b/rtl/m68k/rttip.inc @@ -0,0 +1,132 @@ +{ + $Id$ + This file is part of the Free Pascal run time library. + Copyright (c) 1993,97 by xxxx + member of the Free Pascal development team + + 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. + + **********************************************************************} + +{ Run-Time type information routines - processor dependent part } + + +Procedure Initialize (Data,TypeInfo : pointer);[Alias : 'INITIALIZE']; + +Var Temp : PByte; + I : longint; + Size,Count : longint; + TInfo : Pointer; + +begin + Temp:=PByte(TypeInfo); + case temp^ of + tkLstring,tkWstring : PPchar(Data)^:=Nil; + tkArray : + begin + temp:=Temp+1; + I:=temp^; + temp:=temp+(I+1); // skip name string; + Size:=PArrayRec(Temp)^.Size; // get element size + Count:=PArrayRec(Temp)^.Count; // get element Count + TInfo:=PArrayRec(Temp)^.Info; // Get element info + For I:=0 to Count-1 do + Initialize (Data+(I*size),TInfo); + end; + tkrecord : + begin + Temp:=Temp+1; + I:=Temp^; + temp:=temp+(I+1); // skip name string; + Size:=PRecRec(Temp)^.Size; // get record size; not needed. + Count:=PRecRec(Temp)^.Count; // get element Count + For I:=1 to count Do + With PRecRec(Temp)^.elements[I] do + Initialize (Data+Offset,Info); + end; + end; +end; + +Procedure Finalize (Data,TypeInfo: Pointer);[Alias : 'FINALIZE']; + +Var Temp : PByte; + I : longint; + Size,Count : longint; + TInfo : Pointer; + +begin + Temp:=PByte(TypeInfo); + case temp^ of + tkLstring,tkWstring : Decr_Ansi_ref(Data); + tkArray : + begin + Temp:=Temp+1; + I:=temp^; + temp:=temp+(I+1); // skip name string; + Size:=PArrayRec(Temp)^.Size; // get element size + Count:=PArrayRec(Temp)^.Count; // get element Count + TInfo:=PArrayRec(Temp)^.Info; // Get element info + For I:=0 to Count-1 do + Finalize (Data+(I*size),TInfo); + end; + tkrecord : + begin + Temp:=Temp+1; + I:=Temp^; + temp:=temp+(I+1); // skip name string; + Size:=PRecRec(Temp)^.Size; // get record size; not needed. + Count:=PRecRec(Temp)^.Count; // get element Count + For I:=1 to count do + With PRecRec(Temp)^.elements[I] do + Finalize (Data+Offset,Info); + end; + end; +end; + +Procedure Addref (Data,TypeInfo : Pointer); [alias : 'ADDREF']; + +Var Temp : PByte; + I : longint; + Size,Count : longint; + TInfo : Pointer; + +begin + Temp:=PByte(TypeInfo); + case temp^ of + tkLstring,tkWstring : Incr_Ansi_ref(Data); + tkArray : + begin + Temp:=Temp+1; + I:=temp^; + temp:=temp+(I+1); // skip name string; + Size:=PArrayRec(Temp)^.Size; // get element size + Count:=PArrayRec(Temp)^.Count; // get element Count + TInfo:=PArrayRec(Temp)^.Info; // Get element info + For I:=0 to Count-1 do + Finalize (Data+(I*size),TInfo); + end; + tkrecord : + begin + Temp:=Temp+1; + I:=Temp^; + temp:=temp+(I+1); // skip name string; + Size:=PRecRec(Temp)^.Size; // get record size; not needed. + Count:=PRecRec(Temp)^.Count; // get element Count + For I:=1 to count do + With PRecRec(Temp)^.elements[I] do + Finalize (Data+Offset,Info); + end; + end; +end; + +{ + $Log$ + Revision 1.1 1998-06-08 15:32:08 michael + + Split rtti according to processor. Implemented optimized i386 code. + +} \ No newline at end of file diff --git a/rtl/template/rttip.inc b/rtl/template/rttip.inc new file mode 100644 index 0000000000..05699021c0 --- /dev/null +++ b/rtl/template/rttip.inc @@ -0,0 +1,132 @@ +{ + $Id$ + This file is part of the Free Pascal run time library. + Copyright (c) 1993,97 by xxxx + member of the Free Pascal development team + + 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. + + **********************************************************************} + +{ Run-Time type information routines - processor dependent part } + + +Procedure Initialize (Data,TypeInfo : pointer);[Alias : 'INITIALIZE']; + +Var Temp : PByte; + I : longint; + Size,Count : longint; + TInfo : Pointer; + +begin + Temp:=PByte(TypeInfo); + case temp^ of + tkLstring,tkWstring : PPchar(Data)^:=Nil; + tkArray : + begin + temp:=Temp+1; + I:=temp^; + temp:=temp+(I+1); // skip name string; + Size:=PArrayRec(Temp)^.Size; // get element size + Count:=PArrayRec(Temp)^.Count; // get element Count + TInfo:=PArrayRec(Temp)^.Info; // Get element info + For I:=0 to Count-1 do + Initialize (Data+(I*size),TInfo); + end; + tkrecord : + begin + Temp:=Temp+1; + I:=Temp^; + temp:=temp+(I+1); // skip name string; + Size:=PRecRec(Temp)^.Size; // get record size; not needed. + Count:=PRecRec(Temp)^.Count; // get element Count + For I:=1 to count Do + With PRecRec(Temp)^.elements[I] do + Initialize (Data+Offset,Info); + end; + end; +end; + +Procedure Finalize (Data,TypeInfo: Pointer);[Alias : 'FINALIZE']; + +Var Temp : PByte; + I : longint; + Size,Count : longint; + TInfo : Pointer; + +begin + Temp:=PByte(TypeInfo); + case temp^ of + tkLstring,tkWstring : Decr_Ansi_ref(Data); + tkArray : + begin + Temp:=Temp+1; + I:=temp^; + temp:=temp+(I+1); // skip name string; + Size:=PArrayRec(Temp)^.Size; // get element size + Count:=PArrayRec(Temp)^.Count; // get element Count + TInfo:=PArrayRec(Temp)^.Info; // Get element info + For I:=0 to Count-1 do + Finalize (Data+(I*size),TInfo); + end; + tkrecord : + begin + Temp:=Temp+1; + I:=Temp^; + temp:=temp+(I+1); // skip name string; + Size:=PRecRec(Temp)^.Size; // get record size; not needed. + Count:=PRecRec(Temp)^.Count; // get element Count + For I:=1 to count do + With PRecRec(Temp)^.elements[I] do + Finalize (Data+Offset,Info); + end; + end; +end; + +Procedure Addref (Data,TypeInfo : Pointer); [alias : 'ADDREF']; + +Var Temp : PByte; + I : longint; + Size,Count : longint; + TInfo : Pointer; + +begin + Temp:=PByte(TypeInfo); + case temp^ of + tkLstring,tkWstring : Incr_Ansi_ref(Data); + tkArray : + begin + Temp:=Temp+1; + I:=temp^; + temp:=temp+(I+1); // skip name string; + Size:=PArrayRec(Temp)^.Size; // get element size + Count:=PArrayRec(Temp)^.Count; // get element Count + TInfo:=PArrayRec(Temp)^.Info; // Get element info + For I:=0 to Count-1 do + Finalize (Data+(I*size),TInfo); + end; + tkrecord : + begin + Temp:=Temp+1; + I:=Temp^; + temp:=temp+(I+1); // skip name string; + Size:=PRecRec(Temp)^.Size; // get record size; not needed. + Count:=PRecRec(Temp)^.Count; // get element Count + For I:=1 to count do + With PRecRec(Temp)^.elements[I] do + Finalize (Data+Offset,Info); + end; + end; +end; + +{ + $Log$ + Revision 1.1 1998-06-08 15:32:14 michael + + Split rtti according to processor. Implemented optimized i386 code. + +} \ No newline at end of file