Browse Source

+ added

git-svn-id: trunk@4241 -
Jonas Maebe 19 years ago
parent
commit
e95bd67f6c
2 changed files with 166 additions and 0 deletions
  1. 1 0
      .gitattributes
  2. 165 0
      tests/webtbs/tw7161.pp

+ 1 - 0
.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

+ 165 - 0
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.
+