mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-03 16:26:20 +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/testcomps.pp svneol=native#text/plain
|
||||||
tests/test/units/fpcunit/tstrutils.lpi 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/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.inc svneol=native#text/plain
|
||||||
tests/test/units/math/tmask.pp svneol=native#text/plain
|
tests/test/units/math/tmask.pp svneol=native#text/plain
|
||||||
tests/test/units/math/tmask2.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;
|
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;
|
function GetRoundMode: TFPURoundingMode;
|
||||||
begin
|
begin
|
||||||
Result := TFPURoundingMode((Get8087CW shr 10) and 3);
|
Result := TFPURoundingMode((Get8087CW shr 10) and 3);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
|
function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
|
||||||
var
|
var
|
||||||
CtlWord: Word;
|
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: Word);
|
||||||
procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: SmallInt);
|
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
|
// Sign functions
|
||||||
Type
|
Type
|
||||||
@ -1380,7 +1381,7 @@ begin
|
|||||||
m2 := reciprocalN * m2;
|
m2 := reciprocalN * m2;
|
||||||
m3 := reciprocalN * m3;
|
m3 := reciprocalN * m3;
|
||||||
m4 := reciprocalN * m4;
|
m4 := reciprocalN * m4;
|
||||||
|
|
||||||
skew := m3 / (sqrt(m2)*m2);
|
skew := m3 / (sqrt(m2)*m2);
|
||||||
kurtosis := m4 / (m2 * m2);
|
kurtosis := m4 / (m2 * m2);
|
||||||
end;
|
end;
|
||||||
@ -1548,7 +1549,7 @@ begin
|
|||||||
m2 := reciprocalN * m2;
|
m2 := reciprocalN * m2;
|
||||||
m3 := reciprocalN * m3;
|
m3 := reciprocalN * m3;
|
||||||
m4 := reciprocalN * m4;
|
m4 := reciprocalN * m4;
|
||||||
|
|
||||||
skew := m3 / (sqrt(m2)*m2);
|
skew := m3 / (sqrt(m2)*m2);
|
||||||
kurtosis := m4 / (m2 * m2);
|
kurtosis := m4 / (m2 * m2);
|
||||||
end;
|
end;
|
||||||
@ -1717,7 +1718,7 @@ begin
|
|||||||
m2 := reciprocalN * m2;
|
m2 := reciprocalN * m2;
|
||||||
m3 := reciprocalN * m3;
|
m3 := reciprocalN * m3;
|
||||||
m4 := reciprocalN * m4;
|
m4 := reciprocalN * m4;
|
||||||
|
|
||||||
skew := m3 / (sqrt(m2)*m2);
|
skew := m3 / (sqrt(m2)*m2);
|
||||||
kurtosis := m4 / (m2 * m2);
|
kurtosis := m4 / (m2 * m2);
|
||||||
end;
|
end;
|
||||||
@ -2216,15 +2217,13 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
// Some CPUs probably allow a faster way of doing this in a single operation...
|
// 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.
|
// There weshould define FPC_MATH_HAS_CPUDIVMOD in the header mathuh.inc and implement it using asm.
|
||||||
{$ifndef CPUDIVMOD}
|
{$ifndef FPC_MATH_HAS_DIVMOD}
|
||||||
procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: Word);
|
procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: Word);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result:=Dividend Div Divisor;
|
Result:=Dividend Div Divisor;
|
||||||
Remainder:=Dividend Mod Divisor;
|
Remainder:=Dividend -(Result*Divisor);
|
||||||
end;
|
end;
|
||||||
{$endif}
|
|
||||||
|
|
||||||
|
|
||||||
procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: SmallInt);
|
procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: SmallInt);
|
||||||
@ -2236,6 +2235,23 @@ begin
|
|||||||
end;
|
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;
|
function ifthen(val:boolean;const iftrue:integer; const iffalse:integer= 0) :integer;
|
||||||
begin
|
begin
|
||||||
if val then result:=iftrue else result:=iffalse;
|
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