mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-08 05:07:30 +01:00
+ new, much faster do_set_range based on the PowerPC version (which
will be committed tomorrow)
This commit is contained in:
parent
478ad23438
commit
33ee934d6e
@ -92,27 +92,46 @@ end;
|
|||||||
|
|
||||||
procedure do_set_range(p : pointer;l,h : byte);assembler;[public,alias:'FPC_SET_SET_RANGE'];
|
procedure do_set_range(p : pointer;l,h : byte);assembler;[public,alias:'FPC_SET_SET_RANGE'];
|
||||||
{
|
{
|
||||||
bad implementation, but it's very seldom used
|
adds the range [l..h] to the set pointed to by p
|
||||||
}
|
}
|
||||||
asm
|
asm
|
||||||
pushl %eax
|
pushl %eax
|
||||||
movl p,%edi
|
movzbl l,%eax // lowest bit to be set in eax
|
||||||
xorl %eax,%eax
|
movzbl h,%ebx // highest in ebx
|
||||||
xorl %ecx,%ecx
|
cmpl %eax,%ebx
|
||||||
movb h,%al
|
jb .Lset_range_done
|
||||||
movb l,%cl
|
movl p,%edi // set address in edi
|
||||||
.LSET_SET_RANGE_LOOP:
|
movl %eax,%ecx // lowest also in ecx
|
||||||
cmpl %ecx,%eax
|
shrl $3,%eax // divide by 8 to get starting and ending byte
|
||||||
jl .LSET_SET_RANGE_EXIT
|
shrl $3,%ebx // address
|
||||||
movl %eax,%ebx
|
andb $31,%cl // low five bits of lo determine start of bit mask
|
||||||
movl %eax,%edx
|
movl $0x0ffffffff,%edx // edx = bitmask to be inserted
|
||||||
andl $0xf8,%ebx
|
andl $0x0fffffffc,%eax // clear two lowest bits to get start/end longint
|
||||||
andl $7,%edx
|
andl $0x0fffffffc,%ebx // address * 4
|
||||||
shrl $3,%ebx
|
shll %cl,%edx // shift bitmask to clear bits below lo
|
||||||
btsl %edx,(%edi,%ebx)
|
addl %eax,%edi // go to starting pos in set
|
||||||
dec %eax
|
subl %eax,%ebx // are bit lo and hi in the same longint?
|
||||||
jmp .LSET_SET_RANGE_LOOP
|
jz .Lset_range_hi // yes, keep current mask and adjust for hi bit
|
||||||
.LSET_SET_RANGE_EXIT:
|
orl %edx,(%edi) // no, store current mask
|
||||||
|
movl $0x0ffffffff,%edx // new mask
|
||||||
|
addl $4,%edi // next longint of set
|
||||||
|
subl $4,%ebx // bit hi in this longint?
|
||||||
|
jz .Lset_range_hi // yes, keep full mask and adjust for hi bit
|
||||||
|
.Lset_range_loop:
|
||||||
|
movl %edx,(%edi) // no, fill longints in between with full mask
|
||||||
|
addl $4,%edi
|
||||||
|
subl $4,%ebx
|
||||||
|
jnz .Lset_range_loop
|
||||||
|
.Lset_range_hi:
|
||||||
|
movb h,%cl
|
||||||
|
movl %edx,%ebx // save current bitmask
|
||||||
|
andb $31,%cl
|
||||||
|
subb $31,%cl // cl := (31 - (hi and 31)) = shift count to
|
||||||
|
negb %cl // adjust bitmask for hi bit
|
||||||
|
shrl %cl,%edx // shift bitmask to clear bits higher than hi
|
||||||
|
andl %edx,%ebx // combine both bitmasks
|
||||||
|
orl %ebx,(%edi) // store to set
|
||||||
|
.Lset_range_done:
|
||||||
popl %eax
|
popl %eax
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -428,7 +447,11 @@ end;
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.2 2000-07-13 11:33:41 michael
|
Revision 1.3 2000-09-21 16:09:19 jonas
|
||||||
|
+ new, much faster do_set_range based on the PowerPC version (which
|
||||||
|
will be committed tomorrow)
|
||||||
|
|
||||||
|
Revision 1.2 2000/07/13 11:33:41 michael
|
||||||
+ removed logs
|
+ removed logs
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user