mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-10-27 00:51:33 +01:00
+ created generic versions of software dword/longint mod/div
This commit is contained in:
parent
e0f9297e01
commit
44368ca0e1
@ -802,34 +802,146 @@ end;
|
|||||||
****************************************************************************}
|
****************************************************************************}
|
||||||
{$ifdef FPC_INCLUDE_SOFTWARE_MOD_DIV}
|
{$ifdef FPC_INCLUDE_SOFTWARE_MOD_DIV}
|
||||||
|
|
||||||
|
function count_leading_zeros_32bit(l : longint) : longint;
|
||||||
|
var
|
||||||
|
i : longint;
|
||||||
|
begin
|
||||||
|
for i:=0 to 31 do
|
||||||
|
begin
|
||||||
|
if (l and ($80000000 shr i))<>0 then
|
||||||
|
begin
|
||||||
|
result:=i;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
result:=i;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{$ifndef FPC_SYSTEM_HAS_DIV_DWORD}
|
{$ifndef FPC_SYSTEM_HAS_DIV_DWORD}
|
||||||
function fpc_div_dword(n,z : dword) : dword; [public,alias: 'FPC_DIV_DWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
function fpc_div_dword(n,z : dword) : dword; [public,alias: 'FPC_DIV_DWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||||
|
var
|
||||||
|
shift,lzz,lzn : longint;
|
||||||
begin
|
begin
|
||||||
{!!!!}
|
result:=0;
|
||||||
|
if n=0 then
|
||||||
|
HandleErrorFrame(200,get_frame);
|
||||||
|
lzz:=count_leading_zeros_32bit(z);
|
||||||
|
lzn:=count_leading_zeros_32bit(n);
|
||||||
|
{ if the denominator contains less zeros
|
||||||
|
then the numerator
|
||||||
|
the d is greater than the n }
|
||||||
|
if lzn<lzz then
|
||||||
|
exit;
|
||||||
|
shift:=lzn-lzz;
|
||||||
|
n:=n shl shift;
|
||||||
|
repeat
|
||||||
|
if z>=n then
|
||||||
|
begin
|
||||||
|
z:=z-n;
|
||||||
|
result:=result+(1 shl shift);
|
||||||
|
end;
|
||||||
|
dec(shift);
|
||||||
|
n:=n shr 1;
|
||||||
|
until shift<0;
|
||||||
end;
|
end;
|
||||||
{$endif FPC_SYSTEM_HAS_DIV_DWORD}
|
{$endif FPC_SYSTEM_HAS_DIV_DWORD}
|
||||||
|
|
||||||
|
|
||||||
{$ifndef FPC_SYSTEM_HAS_MOD_DWORD}
|
{$ifndef FPC_SYSTEM_HAS_MOD_DWORD}
|
||||||
function fpc_mod_dword(n,z : dword) : dword; [public,alias: 'FPC_MOD_DWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
function fpc_mod_dword(n,z : dword) : dword; [public,alias: 'FPC_MOD_DWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||||
|
var
|
||||||
|
shift,lzz,lzn : longint;
|
||||||
begin
|
begin
|
||||||
{!!!!}
|
result:=0;
|
||||||
|
if n=0 then
|
||||||
|
HandleErrorFrame(200,get_frame);
|
||||||
|
lzz:=count_leading_zeros_32bit(z);
|
||||||
|
lzn:=count_leading_zeros_32bit(n);
|
||||||
|
{ if the denominator contains less zeros
|
||||||
|
then the numerator
|
||||||
|
the d is greater than the n }
|
||||||
|
if lzn<lzz then
|
||||||
|
begin
|
||||||
|
result:=z;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
shift:=lzn-lzz;
|
||||||
|
n:=n shl shift;
|
||||||
|
repeat
|
||||||
|
if z>=n then
|
||||||
|
z:=z-n;
|
||||||
|
dec(shift);
|
||||||
|
n:=n shr 1;
|
||||||
|
until shift<0;
|
||||||
|
result:=z;
|
||||||
end;
|
end;
|
||||||
{$endif FPC_SYSTEM_HAS_MOD_DWORD}
|
{$endif FPC_SYSTEM_HAS_MOD_DWORD}
|
||||||
|
|
||||||
|
|
||||||
{$ifndef FPC_SYSTEM_HAS_DIV_LONGINT}
|
{$ifndef FPC_SYSTEM_HAS_DIV_LONGINT}
|
||||||
function fpc_div_longint(n,z : longint) : longint; [public,alias: 'FPC_DIV_LONGINT']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
function fpc_div_longint(n,z : longint) : longint; [public,alias: 'FPC_DIV_LONGINT']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||||
|
var
|
||||||
|
sign : boolean;
|
||||||
|
d1,d2 : dword;
|
||||||
begin
|
begin
|
||||||
{!!!!}
|
if n=0 then
|
||||||
|
HandleErrorFrame(200,get_frame);
|
||||||
|
sign:=false;
|
||||||
|
if z<0 then
|
||||||
|
begin
|
||||||
|
sign:=not(sign);
|
||||||
|
d1:=dword(-z);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
d1:=z;
|
||||||
|
if n<0 then
|
||||||
|
begin
|
||||||
|
sign:=not(sign);
|
||||||
|
d2:=dword(-n);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
d2:=n;
|
||||||
|
|
||||||
|
{ the div is coded by the compiler as call to divdword }
|
||||||
|
if sign then
|
||||||
|
result:=-(d1 div d2)
|
||||||
|
else
|
||||||
|
result:=d1 div d2;
|
||||||
end;
|
end;
|
||||||
{$endif FPC_SYSTEM_HAS_DIV_LONGINT}
|
{$endif FPC_SYSTEM_HAS_DIV_LONGINT}
|
||||||
|
|
||||||
|
|
||||||
{$ifndef FPC_SYSTEM_HAS_MOD_LONGINT}
|
{$ifndef FPC_SYSTEM_HAS_MOD_LONGINT}
|
||||||
function fpc_mod_longint(n,z : longint) : longint; [public,alias: 'FPC_MOD_LONGINT']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
function fpc_mod_longint(n,z : longint) : longint; [public,alias: 'FPC_MOD_LONGINT']; {$ifdef hascompilerproc} compilerproc; {$endif}
|
||||||
|
var
|
||||||
|
signed : boolean;
|
||||||
|
r,nq,zq : dword;
|
||||||
begin
|
begin
|
||||||
{!!!!}
|
if n=0 then
|
||||||
|
HandleErrorFrame(200,get_frame);
|
||||||
|
if n<0 then
|
||||||
|
begin
|
||||||
|
nq:=-n;
|
||||||
|
signed:=true;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
signed:=false;
|
||||||
|
nq:=n;
|
||||||
|
end;
|
||||||
|
if z<0 then
|
||||||
|
begin
|
||||||
|
zq:=dword(-z);
|
||||||
|
signed:=not(signed);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
zq:=z;
|
||||||
|
r:=zq mod nq;
|
||||||
|
if signed then
|
||||||
|
result:=-longint(r)
|
||||||
|
else
|
||||||
|
result:=r;
|
||||||
end;
|
end;
|
||||||
{$endif FPC_SYSTEM_HAS_MOD_LONGINT}
|
{$endif FPC_SYSTEM_HAS_MOD_LONGINT}
|
||||||
|
|
||||||
@ -1022,7 +1134,10 @@ end;
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.64 2004-01-10 17:01:29 jonas
|
Revision 1.65 2004-01-20 23:16:56 florian
|
||||||
|
+ created generic versions of software dword/longint mod/div
|
||||||
|
|
||||||
|
Revision 1.64 2004/01/10 17:01:29 jonas
|
||||||
* changed index* to conform to the assembler implementations (interpret
|
* changed index* to conform to the assembler implementations (interpret
|
||||||
negative upper bound as maximum)
|
negative upper bound as maximum)
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user