summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2014-11-16 20:47:38 +0000
committerflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2014-11-16 20:47:38 +0000
commite4827c36fd5d9a718899819afbc78837c81198b9 (patch)
treeacb5b37715efbd419ffa23f5d38e3f1b3834ddde
parent6724e3993ae82d01905a9c3231ff9e85cc1b1ad5 (diff)
downloadfpc-e4827c36fd5d9a718899819afbc78837c81198b9.tar.gz
+ change always floating point divisions into multiplications if they are a power of two,
this is an exact operation so it is always allowed * change only divisions by normal numbers into multiplications git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@29085 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--compiler/aarch64/cpuinfo.pas3
-rw-r--r--compiler/alpha/cpuinfo.pas3
-rw-r--r--compiler/arm/cpuinfo.pas3
-rw-r--r--compiler/avr/cpuinfo.pas3
-rw-r--r--compiler/generic/cpuinfo.pas7
-rw-r--r--compiler/globals.pas30
-rw-r--r--compiler/globtype.pas4
-rw-r--r--compiler/i386/cpuinfo.pas3
-rw-r--r--compiler/i8086/cpuinfo.pas3
-rw-r--r--compiler/ia64/cpuinfo.pas3
-rw-r--r--compiler/jvm/cpuinfo.pas3
-rw-r--r--compiler/m68k/cpuinfo.pas3
-rw-r--r--compiler/mips/cpuinfo.pas3
-rw-r--r--compiler/nadd.pas33
-rw-r--r--compiler/powerpc/cpuinfo.pas3
-rw-r--r--compiler/powerpc64/cpuinfo.pas3
-rw-r--r--compiler/sparc/cpuinfo.pas3
-rw-r--r--compiler/vis/cpuinfo.pas3
-rw-r--r--compiler/x86_64/cpuinfo.pas7
19 files changed, 99 insertions, 24 deletions
diff --git a/compiler/aarch64/cpuinfo.pas b/compiler/aarch64/cpuinfo.pas
index d67a1e1ce7..d253ed77f4 100644
--- a/compiler/aarch64/cpuinfo.pas
+++ b/compiler/aarch64/cpuinfo.pas
@@ -21,6 +21,9 @@ Interface
Type
bestreal = double;
+{$if FPC_FULLVERSION>20700}
+ bestrealrec = TDoubleRec;
+{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = type extended;
diff --git a/compiler/alpha/cpuinfo.pas b/compiler/alpha/cpuinfo.pas
index 0ca4403f6c..cdf5a4ac3f 100644
--- a/compiler/alpha/cpuinfo.pas
+++ b/compiler/alpha/cpuinfo.pas
@@ -41,6 +41,9 @@ Type
TConstPtrUInt = qword;
bestreal = extended;
+{$if FPC_FULLVERSION>20700}
+ bestrealrec = TExtended80Rec;
+{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;
diff --git a/compiler/arm/cpuinfo.pas b/compiler/arm/cpuinfo.pas
index 1d0f25816b..05ea89d9e3 100644
--- a/compiler/arm/cpuinfo.pas
+++ b/compiler/arm/cpuinfo.pas
@@ -21,6 +21,9 @@ Interface
Type
bestreal = double;
+{$if FPC_FULLVERSION>20700}
+ bestrealrec = TDoubleRec;
+{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = type extended;
diff --git a/compiler/avr/cpuinfo.pas b/compiler/avr/cpuinfo.pas
index 468d1f59e0..eec89b73a2 100644
--- a/compiler/avr/cpuinfo.pas
+++ b/compiler/avr/cpuinfo.pas
@@ -21,6 +21,9 @@ Interface
Type
bestreal = double;
+{$if FPC_FULLVERSION>20700}
+ bestrealrec = TDoubleRec;
+{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = type extended;
diff --git a/compiler/generic/cpuinfo.pas b/compiler/generic/cpuinfo.pas
index 05b9407395..c864c8032b 100644
--- a/compiler/generic/cpuinfo.pas
+++ b/compiler/generic/cpuinfo.pas
@@ -22,6 +22,13 @@ Interface
Type
bestreal = extended;
+{$if FPC_FULLVERSION>20700}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+ bestrealrec = TExtended80Rec;
+{$else}
+ bestrealrec = TDoubleRec;
+{$endif}
+{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = type extended;
diff --git a/compiler/globals.pas b/compiler/globals.pas
index cc0df4e2d8..af28bcc9af 100644
--- a/compiler/globals.pas
+++ b/compiler/globals.pas
@@ -84,23 +84,23 @@ interface
treelogfilename = 'tree.log';
{$if defined(CPUARM) and defined(FPUFPA)}
- MathQNaN : tdoublerec = (bytes : (0,0,252,255,0,0,0,0));
- MathInf : tdoublerec = (bytes : (0,0,240,127,0,0,0,0));
- MathNegInf : tdoublerec = (bytes : (0,0,240,255,0,0,0,0));
- MathPi : tdoublerec = (bytes : (251,33,9,64,24,45,68,84));
+ MathQNaN : tcompdoublerec = (bytes : (0,0,252,255,0,0,0,0));
+ MathInf : tcompdoublerec = (bytes : (0,0,240,127,0,0,0,0));
+ MathNegInf : tcompdoublerec = (bytes : (0,0,240,255,0,0,0,0));
+ MathPi : tcompdoublerec = (bytes : (251,33,9,64,24,45,68,84));
{$else}
{$ifdef FPC_LITTLE_ENDIAN}
- MathQNaN : tdoublerec = (bytes : (0,0,0,0,0,0,252,255));
- MathInf : tdoublerec = (bytes : (0,0,0,0,0,0,240,127));
- MathNegInf : tdoublerec = (bytes : (0,0,0,0,0,0,240,255));
- MathPi : tdoublerec = (bytes : (24,45,68,84,251,33,9,64));
- MathPiExtended : textendedrec = (bytes : (53,194,104,33,162,218,15,201,0,64));
+ MathQNaN : tcompdoublerec = (bytes : (0,0,0,0,0,0,252,255));
+ MathInf : tcompdoublerec = (bytes : (0,0,0,0,0,0,240,127));
+ MathNegInf : tcompdoublerec = (bytes : (0,0,0,0,0,0,240,255));
+ MathPi : tcompdoublerec = (bytes : (24,45,68,84,251,33,9,64));
+ MathPiExtended : tcompextendedrec = (bytes : (53,194,104,33,162,218,15,201,0,64));
{$else FPC_LITTLE_ENDIAN}
- MathQNaN : tdoublerec = (bytes : (255,252,0,0,0,0,0,0));
- MathInf : tdoublerec = (bytes : (127,240,0,0,0,0,0,0));
- MathNegInf : tdoublerec = (bytes : (255,240,0,0,0,0,0,0));
- MathPi : tdoublerec = (bytes : (64,9,33,251,84,68,45,24));
- MathPiExtended : textendedrec = (bytes : (64,0,201,15,218,162,33,104,194,53));
+ MathQNaN : tcompdoublerec = (bytes : (255,252,0,0,0,0,0,0));
+ MathInf : tcompdoublerec = (bytes : (127,240,0,0,0,0,0,0));
+ MathNegInf : tcompdoublerec = (bytes : (255,240,0,0,0,0,0,0));
+ MathPi : tcompdoublerec = (bytes : (64,9,33,251,84,68,45,24));
+ MathPiExtended : tcompextendedrec = (bytes : (64,0,201,15,218,162,33,104,194,53));
{$endif FPC_LITTLE_ENDIAN}
{$endif}
@@ -963,7 +963,7 @@ implementation
result := -1;
end;
- function convertdoublerec(d : tdoublerec) : tdoublerec;{$ifdef USEINLINE}inline;{$endif}
+ function convertdoublerec(d : tcompdoublerec) : tcompdoublerec;{$ifdef USEINLINE}inline;{$endif}
{$ifdef CPUARM}
var
i : longint;
diff --git a/compiler/globtype.pas b/compiler/globtype.pas
index d1879f8cbb..b48a22f7b9 100644
--- a/compiler/globtype.pas
+++ b/compiler/globtype.pas
@@ -110,12 +110,12 @@ interface
{$endif i8086}
{ Use a variant record to be sure that the array if aligned correctly }
- tdoublerec=record
+ tcompdoublerec=record
case byte of
0 : (bytes:array[0..7] of byte);
1 : (value:double);
end;
- textendedrec=record
+ tcompextendedrec=record
case byte of
0 : (bytes:array[0..9] of byte);
1 : (value:extended);
diff --git a/compiler/i386/cpuinfo.pas b/compiler/i386/cpuinfo.pas
index ec8b6d62e1..ced7496d15 100644
--- a/compiler/i386/cpuinfo.pas
+++ b/compiler/i386/cpuinfo.pas
@@ -30,6 +30,9 @@ Interface
Type
bestreal = extended;
+{$if FPC_FULLVERSION>20700}
+ bestrealrec = TExtended80Rec;
+{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;
diff --git a/compiler/i8086/cpuinfo.pas b/compiler/i8086/cpuinfo.pas
index d662156c1a..ef971a94ad 100644
--- a/compiler/i8086/cpuinfo.pas
+++ b/compiler/i8086/cpuinfo.pas
@@ -30,6 +30,9 @@ Interface
Type
bestreal = extended;
+{$if FPC_FULLVERSION>20700}
+ bestrealrec = TExtended80Rec;
+{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;
diff --git a/compiler/ia64/cpuinfo.pas b/compiler/ia64/cpuinfo.pas
index 03c7ef92bc..5d0a8d0c1b 100644
--- a/compiler/ia64/cpuinfo.pas
+++ b/compiler/ia64/cpuinfo.pas
@@ -30,6 +30,9 @@ uses
Type
bestreal = extended;
+{$if FPC_FULLVERSION>20700}
+ bestrealrec = TExtended80Rec;
+{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;
diff --git a/compiler/jvm/cpuinfo.pas b/compiler/jvm/cpuinfo.pas
index 768cc4e9e2..62b89fcd1f 100644
--- a/compiler/jvm/cpuinfo.pas
+++ b/compiler/jvm/cpuinfo.pas
@@ -21,6 +21,9 @@ Interface
Type
bestreal = double;
+{$if FPC_FULLVERSION>20700}
+ bestrealrec = TDoubleRec;
+{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;
diff --git a/compiler/m68k/cpuinfo.pas b/compiler/m68k/cpuinfo.pas
index f833eddd6a..80f09b4f29 100644
--- a/compiler/m68k/cpuinfo.pas
+++ b/compiler/m68k/cpuinfo.pas
@@ -21,6 +21,9 @@ Interface
Type
bestreal = double;
+{$if FPC_FULLVERSION>20700}
+ bestrealrec = TDoubleRec;
+{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;
diff --git a/compiler/mips/cpuinfo.pas b/compiler/mips/cpuinfo.pas
index b7a6ab86ac..91355b99b1 100644
--- a/compiler/mips/cpuinfo.pas
+++ b/compiler/mips/cpuinfo.pas
@@ -21,6 +21,9 @@ Interface
Type
bestreal = double;
+{$if FPC_FULLVERSION>20700}
+ bestrealrec = TDoubleRec;
+{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = type double;
diff --git a/compiler/nadd.pas b/compiler/nadd.pas
index fd3082b978..9424c4e82b 100644
--- a/compiler/nadd.pas
+++ b/compiler/nadd.pas
@@ -684,23 +684,41 @@ implementation
result:=t;
exit;
end;
+{$if FPC_FULLVERSION>20700}
+ { bestrealrec is 2.7.1+ only }
+
+ { replace .../const by a multiplication, but only if fastmath is enabled or
+ the division is done by a power of 2, do not mess with special floating point values like Inf etc.
- { replace .../const by a multiplication, but only if fastmath is enabled,
do this after constant folding to avoid unnecessary precision loss if
an slash expresion would be first converted into a multiplication and later
folded }
if (nodetype=slashn) and
{ do not mess with currency types }
(not(is_currency(right.resultdef))) and
- (cs_opt_fastmath in current_settings.optimizerswitches) then
+ (((cs_opt_fastmath in current_settings.optimizerswitches) and (rt=ordconstn)) or
+ ((cs_opt_fastmath in current_settings.optimizerswitches) and (rt=realconstn) and
+ (bestrealrec(trealconstnode(right).value_real).SpecialType in [fsPositive,fsNegative])
+ ) or
+ ((rt=realconstn) and
+ (bestrealrec(trealconstnode(right).value_real).SpecialType in [fsPositive,fsNegative]) and
+ { mantissa returns the mantissa/fraction without the hidden 1, so power of two means only the hidden
+ bit is set => mantissa must be 0 }
+ (bestrealrec(trealconstnode(right).value_real).Mantissa=0)
+ )
+ ) then
case rt of
ordconstn:
begin
- nodetype:=muln;
- t:=crealconstnode.create(1/tordconstnode(right).value,resultdef);
- right.free;
- right:=t;
- exit;
+ { the normal code handles div/0 }
+ if (tordconstnode(right).value<>0) then
+ begin
+ nodetype:=muln;
+ t:=crealconstnode.create(1/tordconstnode(right).value,resultdef);
+ right.free;
+ right:=t;
+ exit;
+ end;
end;
realconstn:
begin
@@ -709,6 +727,7 @@ implementation
exit;
end;
end;
+{$endif FPC_FULLVERSION>20700}
{ first, we handle widestrings, so we can check later for }
{ stringconstn only }
diff --git a/compiler/powerpc/cpuinfo.pas b/compiler/powerpc/cpuinfo.pas
index 2a3b20d816..ac7b4e3cd1 100644
--- a/compiler/powerpc/cpuinfo.pas
+++ b/compiler/powerpc/cpuinfo.pas
@@ -21,6 +21,9 @@ Interface
Type
bestreal = double;
+{$if FPC_FULLVERSION>20700}
+ bestrealrec = TDoubleRec;
+{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;
diff --git a/compiler/powerpc64/cpuinfo.pas b/compiler/powerpc64/cpuinfo.pas
index b50198445b..8d4d636a4f 100644
--- a/compiler/powerpc64/cpuinfo.pas
+++ b/compiler/powerpc64/cpuinfo.pas
@@ -21,6 +21,9 @@ uses
type
bestreal = double;
+{$if FPC_FULLVERSION>20700}
+ bestrealrec = TDoubleRec;
+{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;
diff --git a/compiler/sparc/cpuinfo.pas b/compiler/sparc/cpuinfo.pas
index 3dc03de94b..55c26d3e6c 100644
--- a/compiler/sparc/cpuinfo.pas
+++ b/compiler/sparc/cpuinfo.pas
@@ -30,6 +30,9 @@ uses
type
bestreal = double;
+{$if FPC_FULLVERSION>20700}
+ bestrealrec = TDoubleRec;
+{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;
diff --git a/compiler/vis/cpuinfo.pas b/compiler/vis/cpuinfo.pas
index c33e4e4d3c..ccc3d9bbaa 100644
--- a/compiler/vis/cpuinfo.pas
+++ b/compiler/vis/cpuinfo.pas
@@ -34,6 +34,9 @@ Type
TConstPtrUInt = Longword;
bestreal = double;
+{$if FPC_FULLVERSION>20700}
+ bestrealrec = TDoubleRec;
+{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;
diff --git a/compiler/x86_64/cpuinfo.pas b/compiler/x86_64/cpuinfo.pas
index 23ffdfaf49..8dfb941acf 100644
--- a/compiler/x86_64/cpuinfo.pas
+++ b/compiler/x86_64/cpuinfo.pas
@@ -30,6 +30,13 @@ Interface
Type
bestreal = extended;
+{$if FPC_FULLVERSION>20700}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+ bestrealrec = TExtended80Rec;
+{$else}
+ bestrealrec = TDoubleRec;
+{$endif}
+{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;