浏览代码

+ Split rtti according to processor. Implemented optimized i386 code.

michael 27 年之前
父节点
当前提交
4b73216117
共有 4 个文件被更改,包括 542 次插入107 次删除
  1. 269 0
      rtl/i386/rttip.inc
  2. 9 107
      rtl/inc/rtti.inc
  3. 132 0
      rtl/m68k/rttip.inc
  4. 132 0
      rtl/template/rttip.inc

+ 269 - 0
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.
+
+}

+ 9 - 107
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'];
-
-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;
+{$i rttip.inc}
+
+{ 
+  $Log$
+  Revision 1.2  1998-06-08 15:32:15  michael
+  + Split rtti according to processor. Implemented optimized i386 code.
+
+}

+ 132 - 0
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.
+
+}

+ 132 - 0
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.
+
+}