From bc47125943dd352ad661a25901e1f0a34fc44700 Mon Sep 17 00:00:00 2001 From: florian Date: Tue, 4 Sep 2012 18:58:20 +0000 Subject: [PATCH] * use BsrDWord in software mod/div * use a for loop instead of an until loop so code generation is potentially better git-svn-id: trunk@22318 - --- rtl/inc/generic.inc | 82 +++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 47 deletions(-) diff --git a/rtl/inc/generic.inc b/rtl/inc/generic.inc index e5aa0b4d57..cf00997c6b 100644 --- a/rtl/inc/generic.inc +++ b/rtl/inc/generic.inc @@ -1360,22 +1360,6 @@ end; ****************************************************************************} {$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 (longint($80000000) shr i))<>0 then - begin - result:=i; - exit; - end; - end; - result:=i; - end; - - {$ifndef FPC_SYSTEM_HAS_DIV_DWORD} function fpc_div_dword(n,z : dword) : dword; [public,alias: 'FPC_DIV_DWORD']; compilerproc; var @@ -1384,24 +1368,26 @@ function fpc_div_dword(n,z : dword) : dword; [public,alias: 'FPC_DIV_DWORD']; co result:=0; if n=0 then HandleErrorAddrFrameInd(200,get_pc_addr,get_frame); - lzz:=count_leading_zeros_32bit(z); - lzn:=count_leading_zeros_32bit(n); + if z=0 then + exit; + lzz:=BsrDWord(z); + lzn:=BsrDWord(n); { if the denominator contains less zeros then the numerator - the d is greater than the n } - if lznlzz then exit; - shift:=lzn-lzz; + shift:=lzz-lzn; n:=n shl shift; - repeat - if z>=n then - begin - z:=z-n; - result:=result+dword(1 shl shift); - end; - dec(shift); - n:=n shr 1; - until shift<0; + for shift:=shift downto 0 do + begin + if z>=n then + begin + z:=z-n; + result:=result+dword(1 shl shift); + end; + n:=n shr 1; + end; end; {$endif FPC_SYSTEM_HAS_DIV_DWORD} @@ -1411,27 +1397,29 @@ function fpc_mod_dword(n,z : dword) : dword; [public,alias: 'FPC_MOD_DWORD']; co var shift,lzz,lzn : longint; begin - result:=0; - if n=0 then - HandleErrorAddrFrameInd(200,get_pc_addr,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 lznlzz 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; + shift:=lzz-lzn; + n:=n shl shift; + for shift:=shift downto 0 do + begin + if z>=n then + z:=z-n; + n:=n shr 1; + end; result:=z; end; {$endif FPC_SYSTEM_HAS_MOD_DWORD}