fpc/rtl/i386/rttip.inc
1998-11-30 10:07:34 +00:00

429 lines
10 KiB
PHP

{
$Id$
This file is part of the Free Pascal run time library.
Copyright (c) 1998 by Michael Van Canneyt
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 }
{$ASMMODE DIRECT}
Procedure Initialize (Data,TypeInfo : pointer);[Public,Alias : 'FPC_INITIALIZE'{$ifndef FPC_NAMES},alias:'INITIALIZE'{$endif}];assembler;
asm
# Save registers
push %eax
push %ebx
push %ecx
push %edx
# decide what type it is
movl 12(%ebp),%ebx
movb (%ebx),%al
# This is MANIFESTLY wrong
subb $9,%al
jz .DoAnsiStringInit
decb %al
jz .DoAnsiStringInit
subb $3,%al
jz .DoArrayInit
decb %al
jz .DoRecordInit
decb %al
decb %al
jz .DoObjectInit
decb %al
jz .DoClassInit
jmp .ExitInitialize
.DoObjectInit:
.DoClassInit:
.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
# %ebx points to typeinfo pointer
# Push type
pushl (%ebx)
addl $4,%ebx
# %ebx points to offset in record.
# Us it to calculate data
movl 8(%ebp),%eax
addl (%ebx),%eax
addl $4,%ebx
# push data
pushl %eax
call FPC_INITIALIZE
jmp .MyRecordInitLoop
# Array handling
.DoArrayInit:
# Skip array name !!
incl %ebx
movzbl (%ebx),%eax
incl %eax
addl %eax,%ebx
# %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 FPC_INITIALIZE
jmp .MyArrayInitLoop
# AnsiString handling :
.DoAnsiStringInit:
movl 8(%ebp), %eax
movl $0,(%eax)
.ExitInitialize:
pop %edx
pop %ecx
pop %ebx
pop %eax
end;
Procedure Finalize (Data,TypeInfo: Pointer);[Public,Alias : 'FPC_FINALIZE'{$ifndef FPC_NAMES},alias:'FINALIZE'{$endif}]; assembler;
asm
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
decb %al
decb %al
jz .DoObjectFinal
decb %al
jz .DoClassFinal
jmp .ExitFinalize
.DoClassFinal:
.DoObjectFinal:
.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
# %ebx points to typeinfo pointer
# Push type
pushl (%ebx)
addl $4,%ebx
# %ebx points to offset.
# Use to calculate data
movl 8(%ebp),%eax
addl (%ebx),%eax
addl $4,%ebx
# push data
pushl %eax
call FPC_FINALIZE
jmp .MyRecordFinalLoop
# Array handling
.DoArrayFinal:
# Skip array name !!
incl %ebx
movzbl (%ebx),%eax
incl %eax
addl %eax,%ebx
# %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 FPC_FINALIZE
jmp .MyArrayFinalLoop
# AnsiString handling :
.DoAnsiStringFinal:
pushl 8(%ebp)
{$ifdef NEWSTRNAMES}
call FPC_ANSISTR_DECR_REF
{$else}
call FPC_DECR_ANSI_REF
{$endif}
.ExitFinalize:
pop %edx
pop %ecx
pop %ebx
pop %eax
end;
Procedure Addref (Data,TypeInfo : Pointer); [Public,alias : 'FPC_ADDREF'];Assembler;
asm
# Save registers
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
decb %al
decb %al
jz .DoObjectAddRef
decb %al
jz .DoClassAddRef
jmp .ExitAddRef
.DoClassAddRef:
.DoObjectAddRef:
.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 FPC_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 FPC_ADDREF
jmp .MyArrayAddRefLoop
# AnsiString handling :
.DoAnsiStringAddRef:
pushl 8(%ebp)
{$ifdef NEWSTRNAMES}
call FPC_ANSISTR_INCR_REF
{$else}
call FPC_INCR_ANSI_REF
{$endif}
.ExitAddRef:
pop %edx
pop %ecx
pop %ebx
pop %eax
end;
Procedure DecRef (Data,TypeInfo : Pointer); [Public,alias : 'FPC_DECREF'];Assembler;
asm
# Save registers
push %eax
push %ebx
push %ecx
push %edx
# decide what type it is
movl 12(%ebp),%ebx
movb (%ebx),%al
subb $10,%al
jz .DoAnsiStringDecRef
decb %al
jz .DoAnsiStringDecRef
subb $2,%al
jz .DoArrayDecRef
decb %al
jz .DoRecordDecRef
decb %al
decb %al
jz .DoObjectDecRef
decb %al
jz .DoClassDecRef
jmp .ExitDecRef
.DoClassDecRef:
.DoObjectDecRef:
.DoRecordDecRef:
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
.MyRecordDecRefLoop:
decl %edx
jl .ExitDecRef
# Calculate data
movl 8(%ebp),%eax
addl (%ebx),%eax
addl $4,%ebx
# Push type
pushl (%ebx)
addl $4,%ebx
# push data
pushl %eax
call FPC_DECREF
jmp .MyRecordDecRefLoop
# Array handling
.DoArrayDecRef:
# %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.
.MyArrayDecRefLoop:
decl %edx
jl .ExitDecRef
# push type
pushl (%ebx)
# calculate data
movl %ecx,%eax
imull %edx,%eax
addl 8(%ebp),%eax
# push data
pushl %eax
call FPC_DECREF
jmp .MyArrayDecRefLoop
# AnsiString handling :
.DoAnsiStringDecRef:
movl 8(%ebp),%eax
pushl %eax
{$ifdef NEWSTRNAMES}
call FPC_ANSISTR_DECR_REF
{$else}
call FPC_DECR_ANSI_REF
{$endif}
.ExitDecRef:
pop %edx
pop %ecx
pop %ebx
pop %eax
end;
{$ASMMODE DEFAULT}
{
$Log$
Revision 1.12 1998-11-30 10:07:34 michael
+ Adjusted typeinfo constants
Revision 1.11 1998/11/17 00:41:10 peter
* renamed string functions
Revision 1.10 1998/11/16 12:21:47 peter
* fixes for 0.99.8
Revision 1.9 1998/09/29 08:38:25 michael
+ Corrections in record and array handling.
Revision 1.8 1998/09/20 17:49:07 florian
* some ansistring fixes
Revision 1.7 1998/09/14 10:48:11 peter
* FPC_ names
* Heap manager is now system independent
Revision 1.6 1998/08/23 20:58:50 florian
+ rtti for objects and classes
+ TObject.GetClassName implemented
Revision 1.5 1998/06/25 08:41:43 florian
* better rtti
Revision 1.4 1998/06/17 11:50:43 michael
+ Small patch: forgot to make alias public
Revision 1.3 1998/06/10 07:46:49 michael
+ Forgot to commit some changes
Revision 1.2 1998/06/08 19:31:03 michael
+ Implemented DecRef
Revision 1.1 1998/06/08 15:32:12 michael
+ Split rtti according to processor. Implemented optimized i386 code.
}