mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 06:28:55 +02:00
+ procedure DivMod(Dividend: Integer; Divisor: integer; var Result, Remainder: integer); and procedure DivMod(Dividend: cardinal; Divisor: cardinal; var Result, Remainder: cardinal);, resolves #14286
+ assembler implementations of DivMod for i386 git-svn-id: trunk@13508 -
This commit is contained in:
parent
c97a407633
commit
a14db25c64
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -8445,6 +8445,7 @@ tests/test/units/fpcunit/testclasses.lpr svneol=native#text/plain
|
||||
tests/test/units/fpcunit/testcomps.pp svneol=native#text/plain
|
||||
tests/test/units/fpcunit/tstrutils.lpi svneol=native#text/plain
|
||||
tests/test/units/fpcunit/tstrutils.lpr svneol=native#text/plain
|
||||
tests/test/units/math/tdivmod.pp svneol=native#text/plain
|
||||
tests/test/units/math/tmask.inc svneol=native#text/plain
|
||||
tests/test/units/math/tmask.pp svneol=native#text/plain
|
||||
tests/test/units/math/tmask2.pp svneol=native#text/plain
|
||||
|
@ -58,11 +58,66 @@ function cotan(x : float) : float;assembler;
|
||||
end;
|
||||
|
||||
|
||||
{$define FPC_MATH_HAS_DIVMOD}
|
||||
procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: Word);assembler;
|
||||
asm
|
||||
pushw %di
|
||||
movw %dx,%di
|
||||
movl %eax,%edx
|
||||
shrl $16,%edx
|
||||
div %di
|
||||
movw %ax,(%ecx)
|
||||
movl Remainder,%ecx
|
||||
movw %dx,(%ecx)
|
||||
popw %di
|
||||
end;
|
||||
|
||||
|
||||
procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: SmallInt);assembler;
|
||||
asm
|
||||
pushw %di
|
||||
movw %dx,%di
|
||||
movl %eax,%edx
|
||||
shrl $16,%edx
|
||||
div %di
|
||||
movw %ax,(%ecx)
|
||||
movl Remainder,%ecx
|
||||
movw %dx,(%ecx)
|
||||
popw %di
|
||||
end;
|
||||
|
||||
|
||||
procedure DivMod(Dividend: DWord; Divisor: DWord; var Result, Remainder: DWord);assembler;
|
||||
asm
|
||||
pushl %edi
|
||||
movl %edx,%edi
|
||||
xorl %edx,%edx
|
||||
div %edi
|
||||
movl %eax,(%ecx)
|
||||
movl Remainder,%ecx
|
||||
movl %edx,(%ecx)
|
||||
popl %edi
|
||||
end;
|
||||
|
||||
|
||||
procedure DivMod(Dividend: Integer; Divisor: Integer; var Result, Remainder: Integer);assembler;
|
||||
asm
|
||||
pushl %edi
|
||||
movl %edx,%edi
|
||||
xorl %edx,%edx
|
||||
idiv %edi
|
||||
movl %eax,(%ecx)
|
||||
movl Remainder,%ecx
|
||||
movl %edx,(%ecx)
|
||||
popl %edi
|
||||
end;
|
||||
|
||||
function GetRoundMode: TFPURoundingMode;
|
||||
begin
|
||||
Result := TFPURoundingMode((Get8087CW shr 10) and 3);
|
||||
end;
|
||||
|
||||
|
||||
function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
|
||||
var
|
||||
CtlWord: Word;
|
||||
|
@ -171,7 +171,8 @@ function EnsureRange(const AValue, AMin, AMax: Double): Double;inline; overload
|
||||
|
||||
procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: Word);
|
||||
procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: SmallInt);
|
||||
|
||||
procedure DivMod(Dividend: DWord; Divisor: DWord; var Result, Remainder: DWord);
|
||||
procedure DivMod(Dividend: Integer; Divisor: Integer; var Result, Remainder: Integer);
|
||||
|
||||
// Sign functions
|
||||
Type
|
||||
@ -1380,7 +1381,7 @@ begin
|
||||
m2 := reciprocalN * m2;
|
||||
m3 := reciprocalN * m3;
|
||||
m4 := reciprocalN * m4;
|
||||
|
||||
|
||||
skew := m3 / (sqrt(m2)*m2);
|
||||
kurtosis := m4 / (m2 * m2);
|
||||
end;
|
||||
@ -1548,7 +1549,7 @@ begin
|
||||
m2 := reciprocalN * m2;
|
||||
m3 := reciprocalN * m3;
|
||||
m4 := reciprocalN * m4;
|
||||
|
||||
|
||||
skew := m3 / (sqrt(m2)*m2);
|
||||
kurtosis := m4 / (m2 * m2);
|
||||
end;
|
||||
@ -1717,7 +1718,7 @@ begin
|
||||
m2 := reciprocalN * m2;
|
||||
m3 := reciprocalN * m3;
|
||||
m4 := reciprocalN * m4;
|
||||
|
||||
|
||||
skew := m3 / (sqrt(m2)*m2);
|
||||
kurtosis := m4 / (m2 * m2);
|
||||
end;
|
||||
@ -2216,15 +2217,13 @@ begin
|
||||
end;
|
||||
|
||||
// Some CPUs probably allow a faster way of doing this in a single operation...
|
||||
// There weshould define CPUDIVMOD in the header mathuh.inc and implement it using asm.
|
||||
{$ifndef CPUDIVMOD}
|
||||
// There weshould define FPC_MATH_HAS_CPUDIVMOD in the header mathuh.inc and implement it using asm.
|
||||
{$ifndef FPC_MATH_HAS_DIVMOD}
|
||||
procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: Word);
|
||||
|
||||
begin
|
||||
Result:=Dividend Div Divisor;
|
||||
Remainder:=Dividend Mod Divisor;
|
||||
Remainder:=Dividend -(Result*Divisor);
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
|
||||
procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: SmallInt);
|
||||
@ -2236,6 +2235,23 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure DivMod(Dividend: DWord; Divisor: DWord; var Result, Remainder: DWord);
|
||||
begin
|
||||
Result:=Dividend Div Divisor;
|
||||
Remainder:=Dividend -(Result*Divisor);
|
||||
end;
|
||||
|
||||
|
||||
procedure DivMod(Dividend: Integer; Divisor: Integer; var Result, Remainder: Integer);
|
||||
var
|
||||
UnsignedResult: DWord absolute Result;
|
||||
UnsignedRemainder: DWord absolute Remainder;
|
||||
begin
|
||||
DivMod(Dividend, Divisor, UnsignedResult, UnsignedRemainder);
|
||||
end;
|
||||
{$endif FPC_MATH_HAS_DIVMOD}
|
||||
|
||||
|
||||
function ifthen(val:boolean;const iftrue:integer; const iffalse:integer= 0) :integer;
|
||||
begin
|
||||
if val then result:=iftrue else result:=iffalse;
|
||||
|
59
tests/test/units/math/tdivmod.pp
Normal file
59
tests/test/units/math/tdivmod.pp
Normal file
@ -0,0 +1,59 @@
|
||||
uses
|
||||
math;
|
||||
{ tests:
|
||||
procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: Word);
|
||||
procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: SmallInt);
|
||||
procedure DivMod(Dividend: DWord; Divisor: DWord; var Result, Remainder: DWord);
|
||||
procedure DivMod(Dividend: Integer; Divisor: Integer; var Result, Remainder: Integer);
|
||||
}
|
||||
procedure doerror(i : integer);
|
||||
begin
|
||||
writeln('Error: ',i);
|
||||
halt(1);
|
||||
end;
|
||||
|
||||
|
||||
var
|
||||
QuotientWord,RemainderWord : Word;
|
||||
QuotientSmallInt,RemainderSmallInt : SmallInt;
|
||||
QuotientDWord,RemainderDWord : DWord;
|
||||
QuotientInteger,RemainderInteger : Integer;
|
||||
|
||||
begin
|
||||
DivMod($ffff,65,QuotientWord,RemainderWord);
|
||||
if QuotientWord<>1008 then
|
||||
doerror(1);
|
||||
if RemainderWord<>15 then
|
||||
doerror(2);
|
||||
|
||||
DivMod($ffff,65,QuotientSmallInt,RemainderSmallInt);
|
||||
if QuotientSmallInt<>1008 then
|
||||
doerror(1001);
|
||||
if RemainderSmallInt<>15 then
|
||||
doerror(2);
|
||||
|
||||
DivMod($ffff,65,QuotientDWord,RemainderDWord);
|
||||
if QuotientDWord<>1008 then
|
||||
doerror(2001);
|
||||
if RemainderDWord<>15 then
|
||||
doerror(2002);
|
||||
|
||||
DivMod(123456,23,QuotientDWord,RemainderDWord);
|
||||
if QuotientDWord<>5367 then
|
||||
doerror(2003);
|
||||
if RemainderDWord<>15 then
|
||||
doerror(2004);
|
||||
|
||||
DivMod($ffff,65,QuotientInteger,RemainderInteger);
|
||||
if QuotientInteger<>1008 then
|
||||
doerror(3001);
|
||||
if RemainderInteger<>15 then
|
||||
doerror(3002);
|
||||
|
||||
DivMod(123456,23,QuotientInteger,RemainderInteger);
|
||||
if QuotientInteger<>5367 then
|
||||
doerror(3003);
|
||||
if RemainderInteger<>15 then
|
||||
doerror(3004);
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user