|
@@ -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.
|
|
|
+
|