mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-12 23:09:40 +02:00
+ provide also 8 and 16 bit div/mod helper
* tmoddivnode.first_moddivint does not force a 32 bit helper, the used helper depends now on the resultdef type set by tmoddivnode.pass_typecheck git-svn-id: trunk@31195 -
This commit is contained in:
parent
cf64e05c6f
commit
ba1297b1ab
@ -56,7 +56,7 @@
|
||||
{$define SUPPORT_SAFECALL}
|
||||
{$define cpuneedsmulhelper}
|
||||
{ TODO: add another define in order to disable the div helper for 16-bit divs? }
|
||||
{$define cpuneedsdiv32helper}
|
||||
{$define cpuneedsdivhelper}
|
||||
{$define VOLATILE_ES}
|
||||
{$define SUPPORT_GET_FRAME}
|
||||
{$endif i8086}
|
||||
@ -145,7 +145,7 @@
|
||||
{$define cpu32bitalu}
|
||||
{$define cpuflags}
|
||||
{$define cpufpemu}
|
||||
{$define cpuneedsdiv32helper}
|
||||
{$define cpuneedsdivhelper}
|
||||
{$define cpurox}
|
||||
{$define cputargethasfixedstack}
|
||||
{$define cpurefshaveindexreg}
|
||||
@ -178,7 +178,7 @@
|
||||
{$define cpufpemu}
|
||||
{$define cpurefshaveindexreg}
|
||||
{$define cpucapabilities}
|
||||
{$define cpuneedsdiv32helper}
|
||||
{$define cpuneedsdivhelper}
|
||||
{$endif m68k}
|
||||
|
||||
{$ifdef avr}
|
||||
@ -188,7 +188,7 @@
|
||||
{$define cpuflags}
|
||||
{$define cpunofpu}
|
||||
{$define cpunodefaultint}
|
||||
{$define cpuneedsdiv32helper}
|
||||
{$define cpuneedsdivhelper}
|
||||
{$define cpuneedsmulhelper}
|
||||
{$define cpurefshaveindexreg}
|
||||
{$define cpucapabilities}
|
||||
|
@ -393,7 +393,7 @@ implementation
|
||||
|
||||
|
||||
function tmoddivnode.first_moddivint: tnode;
|
||||
{$ifdef cpuneedsdiv32helper}
|
||||
{$ifdef cpuneedsdivhelper}
|
||||
var
|
||||
procname: string[31];
|
||||
begin
|
||||
@ -404,12 +404,25 @@ implementation
|
||||
procname := 'fpc_div_'
|
||||
else
|
||||
procname := 'fpc_mod_';
|
||||
|
||||
{ only qword needs the unsigned code, the
|
||||
signed code is also used for currency }
|
||||
if is_signed(resultdef) then
|
||||
procname := procname + 'longint'
|
||||
else
|
||||
procname := procname + 'dword';
|
||||
case torddef(resultdef).ordtype of
|
||||
u8bit:
|
||||
procname := procname + 'byte';
|
||||
s8bit:
|
||||
procname := procname + 'shortint';
|
||||
u16bit:
|
||||
procname := procname + 'word';
|
||||
s16bit:
|
||||
procname := procname + 'smallint';
|
||||
u32bit:
|
||||
procname := procname + 'dword';
|
||||
s32bit:
|
||||
procname := procname + 'longint'
|
||||
else
|
||||
internalerror(2015070501);
|
||||
end;
|
||||
|
||||
result := ccallnode.createintern(procname,ccallparanode.create(left,
|
||||
ccallparanode.create(right,nil)));
|
||||
@ -424,7 +437,7 @@ implementation
|
||||
if torddef(result.resultdef).ordtype <> torddef(resultdef).ordtype then
|
||||
inserttypeconv(result,resultdef);
|
||||
end;
|
||||
{$else cpuneedsdiv32helper}
|
||||
{$else cpuneedsdivhelper}
|
||||
begin
|
||||
result:=nil;
|
||||
end;
|
||||
|
@ -568,6 +568,14 @@ function fpc_div_dword(n,z : dword) : dword; compilerproc;
|
||||
function fpc_mod_dword(n,z : dword) : dword; compilerproc;
|
||||
function fpc_div_longint(n,z : longint) : longint; compilerproc;
|
||||
function fpc_mod_longint(n,z : longint) : longint; compilerproc;
|
||||
function fpc_div_word(n,z : word) : word; compilerproc;
|
||||
function fpc_mod_word(n,z : word) : word; compilerproc;
|
||||
function fpc_div_smallint(n,z : smallint) : smallint; compilerproc;
|
||||
function fpc_mod_smallint(n,z : smallint) : smallint; compilerproc;
|
||||
function fpc_div_byte(n,z : byte) : byte; compilerproc;
|
||||
function fpc_mod_byte(n,z : byte) : byte; compilerproc;
|
||||
function fpc_div_shortint(n,z : shortint) : shortint; compilerproc;
|
||||
function fpc_mod_shortint(n,z : shortint) : shortint; compilerproc;
|
||||
{$endif FPC_INCLUDE_SOFTWARE_MOD_DIV}
|
||||
|
||||
{$ifdef FPC_INCLUDE_SOFTWARE_MUL}
|
||||
|
@ -1556,6 +1556,136 @@ function fpc_mod_dword(n,z : dword) : dword; [public,alias: 'FPC_MOD_DWORD']; co
|
||||
{$endif FPC_SYSTEM_HAS_MOD_DWORD}
|
||||
|
||||
|
||||
{$ifndef FPC_SYSTEM_HAS_DIV_WORD}
|
||||
function fpc_div_word(n,z : word) : word; [public,alias: 'FPC_DIV_WORD']; compilerproc;
|
||||
var
|
||||
shift,lzz,lzn : Byte;
|
||||
begin
|
||||
result:=0;
|
||||
if n=0 then
|
||||
HandleErrorAddrFrameInd(200,get_pc_addr,get_frame);
|
||||
if z=0 then
|
||||
exit;
|
||||
lzz:=BsrWord(z);
|
||||
lzn:=BsrWord(n);
|
||||
{ if the denominator contains less zeros
|
||||
then the numerator
|
||||
then d is greater than the n }
|
||||
if lzn>lzz then
|
||||
exit;
|
||||
shift:=lzz-lzn;
|
||||
n:=n shl shift;
|
||||
for shift:=shift downto 0 do
|
||||
begin
|
||||
if z>=n then
|
||||
begin
|
||||
z:=z-n;
|
||||
result:=result+word(word(1) shl shift);
|
||||
end;
|
||||
n:=n shr 1;
|
||||
end;
|
||||
end;
|
||||
{$endif FPC_SYSTEM_HAS_DIV_WORD}
|
||||
|
||||
|
||||
{$ifndef FPC_SYSTEM_HAS_MOD_WORD}
|
||||
function fpc_mod_word(n,z : word) : word; [public,alias: 'FPC_MOD_WORD']; compilerproc;
|
||||
var
|
||||
shift,lzz,lzn : Byte;
|
||||
begin
|
||||
result:=0;
|
||||
if n=0 then
|
||||
HandleErrorAddrFrameInd(200,get_pc_addr,get_frame);
|
||||
if z=0 then
|
||||
exit;
|
||||
lzz:=BsrWord(z);
|
||||
lzn:=BsrWord(n);
|
||||
{ if the denominator contains less zeros
|
||||
then the numerator
|
||||
then d is greater than the n }
|
||||
if lzn>lzz then
|
||||
begin
|
||||
result:=z;
|
||||
exit;
|
||||
end;
|
||||
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_WORD}
|
||||
|
||||
|
||||
{$ifndef FPC_SYSTEM_HAS_DIV_BYTE}
|
||||
function fpc_div_byte(n,z : byte) : byte; [public,alias: 'FPC_DIV_BYTE']; compilerproc;
|
||||
var
|
||||
shift,lzz,lzn : Byte;
|
||||
begin
|
||||
result:=0;
|
||||
if n=0 then
|
||||
HandleErrorAddrFrameInd(200,get_pc_addr,get_frame);
|
||||
if z=0 then
|
||||
exit;
|
||||
lzz:=BsrByte(z);
|
||||
lzn:=BsrByte(n);
|
||||
{ if the denominator contains less zeros
|
||||
then the numerator
|
||||
then d is greater than the n }
|
||||
if lzn>lzz then
|
||||
exit;
|
||||
shift:=lzz-lzn;
|
||||
n:=n shl shift;
|
||||
for shift:=shift downto 0 do
|
||||
begin
|
||||
if z>=n then
|
||||
begin
|
||||
z:=z-n;
|
||||
result:=result+byte(byte(1) shl shift);
|
||||
end;
|
||||
n:=n shr 1;
|
||||
end;
|
||||
end;
|
||||
{$endif FPC_SYSTEM_HAS_DIV_BYTE}
|
||||
|
||||
|
||||
{$ifndef FPC_SYSTEM_HAS_MOD_BYTE}
|
||||
function fpc_mod_byte(n,z : byte) : byte; [public,alias: 'FPC_MOD_BYTE']; compilerproc;
|
||||
var
|
||||
shift,lzz,lzn : Byte;
|
||||
begin
|
||||
result:=0;
|
||||
if n=0 then
|
||||
HandleErrorAddrFrameInd(200,get_pc_addr,get_frame);
|
||||
if z=0 then
|
||||
exit;
|
||||
lzz:=BsrByte(z);
|
||||
lzn:=BsrByte(n);
|
||||
{ if the denominator contains less zeros
|
||||
then the numerator
|
||||
then d is greater than the n }
|
||||
if lzn>lzz then
|
||||
begin
|
||||
result:=z;
|
||||
exit;
|
||||
end;
|
||||
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_BYTE}
|
||||
|
||||
|
||||
{$ifndef FPC_SYSTEM_HAS_DIV_LONGINT}
|
||||
function fpc_div_longint(n,z : longint) : longint; [public,alias: 'FPC_DIV_LONGINT']; compilerproc;
|
||||
var
|
||||
@ -1618,8 +1748,133 @@ function fpc_mod_longint(n,z : longint) : longint; [public,alias: 'FPC_MOD_LONGI
|
||||
end;
|
||||
{$endif FPC_SYSTEM_HAS_MOD_LONGINT}
|
||||
|
||||
{$endif FPC_INCLUDE_SOFTWARE_MOD_DIV}
|
||||
|
||||
{$ifndef FPC_SYSTEM_HAS_DIV_SMALLINT}
|
||||
function fpc_div_smallint(n,z : smallint) : smallint; [public,alias: 'FPC_DIV_SMALLINT']; compilerproc;
|
||||
var
|
||||
sign : boolean;
|
||||
w1,w2 : word;
|
||||
begin
|
||||
if n=0 then
|
||||
HandleErrorAddrFrameInd(200,get_pc_addr,get_frame);
|
||||
sign:=false;
|
||||
if z<0 then
|
||||
begin
|
||||
sign:=not(sign);
|
||||
w1:=word(-z);
|
||||
end
|
||||
else
|
||||
w1:=z;
|
||||
if n<0 then
|
||||
begin
|
||||
sign:=not(sign);
|
||||
w2:=word(-n);
|
||||
end
|
||||
else
|
||||
w2:=n;
|
||||
|
||||
{ the div is coded by the compiler as call to divdword }
|
||||
if sign then
|
||||
result:=-(w1 div w2)
|
||||
else
|
||||
result:=w1 div w2;
|
||||
end;
|
||||
{$endif FPC_SYSTEM_HAS_DIV_SMALLINT}
|
||||
|
||||
|
||||
{$ifndef FPC_SYSTEM_HAS_MOD_SMALLINT}
|
||||
function fpc_mod_smallint(n,z : smallint) : smallint; [public,alias: 'FPC_MOD_SMALLINT']; compilerproc;
|
||||
var
|
||||
signed : boolean;
|
||||
r,nq,zq : word;
|
||||
begin
|
||||
if n=0 then
|
||||
HandleErrorAddrFrameInd(200,get_pc_addr,get_frame);
|
||||
nq:=abs(n);
|
||||
|
||||
if z<0 then
|
||||
begin
|
||||
zq:=word(-z);
|
||||
signed:=true;
|
||||
end
|
||||
else
|
||||
begin
|
||||
zq:=z;
|
||||
signed:=false;
|
||||
end;
|
||||
|
||||
r:=zq mod nq;
|
||||
if signed then
|
||||
result:=-smallint(r)
|
||||
else
|
||||
result:=r;
|
||||
end;
|
||||
{$endif FPC_SYSTEM_HAS_MOD_SMALLINT}
|
||||
|
||||
|
||||
{$ifndef FPC_SYSTEM_HAS_DIV_SHORTINT}
|
||||
function fpc_div_shortint(n,z : shortint) : shortint; [public,alias: 'FPC_DIV_SHORTINT']; compilerproc;
|
||||
var
|
||||
sign : boolean;
|
||||
b1,b2 : byte;
|
||||
begin
|
||||
if n=0 then
|
||||
HandleErrorAddrFrameInd(200,get_pc_addr,get_frame);
|
||||
sign:=false;
|
||||
if z<0 then
|
||||
begin
|
||||
sign:=not(sign);
|
||||
b1:=byte(-z);
|
||||
end
|
||||
else
|
||||
b1:=z;
|
||||
if n<0 then
|
||||
begin
|
||||
sign:=not(sign);
|
||||
b2:=byte(-n);
|
||||
end
|
||||
else
|
||||
b2:=n;
|
||||
|
||||
{ the div is coded by the compiler as call to divdword }
|
||||
if sign then
|
||||
result:=-(b1 div b2)
|
||||
else
|
||||
result:=b1 div b2;
|
||||
end;
|
||||
{$endif FPC_SYSTEM_HAS_DIV_SHORTINT}
|
||||
|
||||
|
||||
{$ifndef FPC_SYSTEM_HAS_MOD_SHORTINT}
|
||||
function fpc_mod_shortint(n,z : shortint) : shortint; [public,alias: 'FPC_MOD_SHORTINT']; compilerproc;
|
||||
var
|
||||
signed : boolean;
|
||||
r,nq,zq : byte;
|
||||
begin
|
||||
if n=0 then
|
||||
HandleErrorAddrFrameInd(200,get_pc_addr,get_frame);
|
||||
nq:=abs(n);
|
||||
|
||||
if z<0 then
|
||||
begin
|
||||
zq:=byte(-z);
|
||||
signed:=true;
|
||||
end
|
||||
else
|
||||
begin
|
||||
zq:=z;
|
||||
signed:=false;
|
||||
end;
|
||||
|
||||
r:=zq mod nq;
|
||||
if signed then
|
||||
result:=-shortint(r)
|
||||
else
|
||||
result:=r;
|
||||
end;
|
||||
{$endif FPC_SYSTEM_HAS_MOD_SHORTINT}
|
||||
|
||||
{$endif FPC_INCLUDE_SOFTWARE_MOD_DIV}
|
||||
|
||||
{****************************************************************************}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user