diff options
author | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2014-11-16 20:47:38 +0000 |
---|---|---|
committer | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2014-11-16 20:47:38 +0000 |
commit | e4827c36fd5d9a718899819afbc78837c81198b9 (patch) | |
tree | acb5b37715efbd419ffa23f5d38e3f1b3834ddde | |
parent | 6724e3993ae82d01905a9c3231ff9e85cc1b1ad5 (diff) | |
download | fpc-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.pas | 3 | ||||
-rw-r--r-- | compiler/alpha/cpuinfo.pas | 3 | ||||
-rw-r--r-- | compiler/arm/cpuinfo.pas | 3 | ||||
-rw-r--r-- | compiler/avr/cpuinfo.pas | 3 | ||||
-rw-r--r-- | compiler/generic/cpuinfo.pas | 7 | ||||
-rw-r--r-- | compiler/globals.pas | 30 | ||||
-rw-r--r-- | compiler/globtype.pas | 4 | ||||
-rw-r--r-- | compiler/i386/cpuinfo.pas | 3 | ||||
-rw-r--r-- | compiler/i8086/cpuinfo.pas | 3 | ||||
-rw-r--r-- | compiler/ia64/cpuinfo.pas | 3 | ||||
-rw-r--r-- | compiler/jvm/cpuinfo.pas | 3 | ||||
-rw-r--r-- | compiler/m68k/cpuinfo.pas | 3 | ||||
-rw-r--r-- | compiler/mips/cpuinfo.pas | 3 | ||||
-rw-r--r-- | compiler/nadd.pas | 33 | ||||
-rw-r--r-- | compiler/powerpc/cpuinfo.pas | 3 | ||||
-rw-r--r-- | compiler/powerpc64/cpuinfo.pas | 3 | ||||
-rw-r--r-- | compiler/sparc/cpuinfo.pas | 3 | ||||
-rw-r--r-- | compiler/vis/cpuinfo.pas | 3 | ||||
-rw-r--r-- | compiler/x86_64/cpuinfo.pas | 7 |
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; |