diff --git a/.gitattributes b/.gitattributes index b127773138..dbbcef4c5b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7228,6 +7228,7 @@ tests/webtbs/tw6989.pp svneol=native#text/plain tests/webtbs/tw7006.pp svneol=native#text/plain tests/webtbs/tw7104.pp svneol=native#text/plain tests/webtbs/tw7143.pp -text +tests/webtbs/tw7161.pp svneol=native#text/plain tests/webtbs/ub1873.pp svneol=native#text/plain tests/webtbs/ub1883.pp svneol=native#text/plain tests/webtbs/uw0555.pp svneol=native#text/plain diff --git a/tests/webtbs/tw7161.pp b/tests/webtbs/tw7161.pp new file mode 100644 index 0000000000..54f6aa33aa --- /dev/null +++ b/tests/webtbs/tw7161.pp @@ -0,0 +1,165 @@ +{ %opt=-Cfsse2 -O-2 } +{ %cpu=i386 } + +(* + +Testprogram to show sse2/sse3 bug + +- works with fpu -O{1,2,3} +- works with -CfSSE{2,3} -O1 +- access violation with -CfSSE{2,3} -O{2,3} + +NOTE: It also works with -CfSSE3 -O3 if I + declare DMLogicToCube as global var! + + +Expected Output: + 0.2500 -> -115.4701 + 0.1000 -> -247.4874 + 0.0500 -> -20.4124 + 20.0000 -> -135.5047 + 45.0000 -> 23.8797 + +*) +program ssetest; + +{$mode objfpc}{$H+} + +uses + Classes, SysUtils + { add your units here } + ,math, mmx; + +type kfloat = double; + TPosArr = array[0..4] of kfloat; + VektorArr = Array[0..2] of kfloat; + Drehmatrix = Array[0..2] of VektorArr; + +type + TCube = class + private + DMLogicToCube : Drehmatrix; + public + Procedure InitDrehmatrizen; + function LogicToCube(const apo: TPosArr) : TPosArr; + end; + + +Function aTanG(const x,y : kfloat) : kfloat; +Var + b : kfloat; +begin + b:=x*x+y*y; + if isZero(b) then result:=0 + else begin + if IsZero(x) then + begin + if y >= 0 then result:=90 else result:=-90; + end + else begin + if IsZero(y) then result:=0 + else begin; + b:=ln(abs(y))-ln(abs(x)); + if (b > 230) then result:=90 else result:=180/pi*arctan(y/x); + end; + end; + if (x < 0) then result:=result+180; + if (result > 180) then result:=result-360; + end; +end; + +Function SinD(const w : kfloat) : kfloat; +begin + result:=sin(w*pi/180); +end; + +Function CosD(const w : kfloat) : kfloat; +begin + result:=Cos(w*pi/180); +end; + + + +Procedure EinheitsVektor(out v : VektorArr;const ph,th : kfloat); +var cth : kfloat; +begin + cth:=cosD(th); + v[0]:=cosD(ph)*cth; + v[1]:=sinD(ph)*cth; + v[2]:=sinD(th); +end; + +Function Gettheta(const v : VektorArr) : kfloat; +begin + result:=aTanG(sqrt(sqr(v[0])+sqr(v[1])),v[2]); +end; + +Function Getphi(const v : VektorArr) : kfloat; +begin + result:=aTanG(v[0],v[1]); +end; + +Procedure TCube.InitDrehmatrizen; +begin + DMLogicToCube[0,0]:=-cos(arctan(sqrt(2))); + DMLogicToCube[1,0]:=-1/sqrt(2); + DMLogicToCube[2,0]:=-cos(arctan(sqrt(2)))/sqrt(2); + DMLogicToCube[0,1]:= cos(arctan(sqrt(2))); + DMLogicToCube[1,1]:=-1/sqrt(2); + DMLogicToCube[2,1]:= cos(arctan(sqrt(2)))/sqrt(2); + DMLogicToCube[0,2]:=-cos(arctan(sqrt(2))); + DMLogicToCube[1,2]:= 0; + DMLogicToCube[2,2]:= sin(arctan(sqrt(2))); +end; + +function TCube.LogicToCube(const apo: TPosArr) : TPosArr; +Var + s,z : Integer; + vzz,v : VektorArr; + ee : KFloat; + +begin + EinheitsVektor(v,apo[3],apo[4]); + for z:=0 to 2 do + begin + result[z]:=0; + vzz[z]:=0; + for s:=0 to 2 do begin + ee:=DMLogicToCube[z,s]; //AccessViolation here + result[z]:=result[z]+ee*apo[s]; + vzz[z]:=vzz[z]+ee*v[s]; + end; + Result[z]:=result[z]*1000; + end; + result[3]:=Getphi(vzz); + result[4]:=Gettheta(vzz); +end; + +const useInput : TPosArr=(0.25,0.10,0.05,20.0,45.0); +var + Cube : TCube; + resu : TPosArr; + i : integer; + resstr: string; + + +const + correctresults: array[0..4] of string[10] = + (' -115.4701',' -247.4874',' -20.4124',' -135.5047',' 23.8797'); + +begin + if not is_sse2_cpu then + halt(0); + Cube:=TCube.Create; + Cube.InitDrehmatrizen; + resu:=Cube.LogicToCube(useInput); + for i := 0 to High(resu) do + begin + writeln(useinput[i]:10:4,' -> ',resu[i]:10:4); + str(resu[i]:10:4,resstr); + if resstr <> correctresults[i] then + halt(1); + end; + cube.free; +end. +