[llvm-commits] [llvm-gcc-4.2] r41322 - in /llvm-gcc-4.2/trunk/gcc/ada: a-numaux-x86.adb a-numaux-x86.ads
Duncan Sands
baldrick at free.fr
Thu Aug 23 09:04:49 PDT 2007
Author: baldrick
Date: Thu Aug 23 11:04:48 2007
New Revision: 41322
URL: http://llvm.org/viewvc/llvm-project?rev=41322&view=rev
Log:
Work around the current lack of support for inline
asm that uses the x86 floating point stack.
Modified:
llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.adb
llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.ads
Modified: llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.adb
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.adb?rev=41322&r1=41321&r2=41322&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.adb (original)
+++ llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.adb Thu Aug 23 11:04:48 2007
@@ -37,11 +37,13 @@
-- This version of Numerics.Aux is for the IEEE Double Extended floating
-- point format on x86.
-with System.Machine_Code; use System.Machine_Code;
+-- LLVM local
+-- with System.Machine_Code; use System.Machine_Code;
package body Ada.Numerics.Aux is
- NL : constant String := ASCII.LF & ASCII.HT;
+-- LLVM local
+-- NL : constant String := ASCII.LF & ASCII.HT;
-----------------------
-- Local subprograms --
@@ -55,6 +57,11 @@
-- to calculate the exponentiation. This is used by Pow for values
-- for values of Y in the open interval (-0.25, 0.25)
+ -- LLVM local begin
+ pragma Import (C, Logarithmic_Pow, "pow");
+ pragma Pure_Function (Logarithmic_Pow);
+ -- LLVM local end
+
procedure Reduce (X : in out Double; Q : out Natural);
-- Implements reduction of X by Pi/2. Q is the quadrant of the final
-- result in the range 0 .. 3. The absolute value of X is at most Pi.
@@ -73,15 +80,18 @@
-- Atan --
----------
+ -- LLVM local begin
+ function C_Atan (X : Double) return Double;
+ pragma Import (C, C_Atan, "atan");
+ pragma Pure_Function (C_Atan);
+ -- LLVM local end
+
function Atan (X : Double) return Double is
Result : Double;
begin
- Asm (Template =>
- "fld1" & NL
- & "fpatan",
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs => Double'Asm_Input ("0", X));
+ -- LLVM local
+ Result := C_Atan (X);
-- The result value is NaN iff input was invalid
@@ -96,25 +106,27 @@
-- Exp --
---------
- function Exp (X : Double) return Double is
- Result : Double;
- begin
- Asm (Template =>
- "fldl2e " & NL
- & "fmulp %%st, %%st(1)" & NL -- X * log2 (E)
- & "fld %%st(0) " & NL
- & "frndint " & NL -- Integer (X * Log2 (E))
- & "fsubr %%st, %%st(1)" & NL -- Fraction (X * Log2 (E))
- & "fxch " & NL
- & "f2xm1 " & NL -- 2**(...) - 1
- & "fld1 " & NL
- & "faddp %%st, %%st(1)" & NL -- 2**(Fraction (X * Log2 (E)))
- & "fscale " & NL -- E ** X
- & "fstp %%st(1) ",
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs => Double'Asm_Input ("0", X));
- return Result;
- end Exp;
+-- LLVM local begin
+-- function Exp (X : Double) return Double is
+-- Result : Double;
+-- begin
+-- Asm (Template =>
+-- "fldl2e " & NL
+-- & "fmulp %%st, %%st(1)" & NL -- X * log2 (E)
+-- & "fld %%st(0) " & NL
+-- & "frndint " & NL -- Integer (X * Log2 (E))
+-- & "fsubr %%st, %%st(1)" & NL -- Fraction (X * Log2 (E))
+-- & "fxch " & NL
+-- & "f2xm1 " & NL -- 2**(...) - 1
+-- & "fld1 " & NL
+-- & "faddp %%st, %%st(1)" & NL -- 2**(Fraction (X * Log2 (E)))
+-- & "fscale " & NL -- E ** X
+-- & "fstp %%st(1) ",
+-- Outputs => Double'Asm_Output ("=t", Result),
+-- Inputs => Double'Asm_Input ("0", X));
+-- return Result;
+-- end Exp;
+-- LLVM local end
------------
-- Is_Nan --
@@ -131,18 +143,20 @@
-- Log --
---------
- function Log (X : Double) return Double is
- Result : Double;
-
- begin
- Asm (Template =>
- "fldln2 " & NL
- & "fxch " & NL
- & "fyl2x " & NL,
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs => Double'Asm_Input ("0", X));
- return Result;
- end Log;
+-- LLVM local begin
+-- function Log (X : Double) return Double is
+-- Result : Double;
+--
+-- begin
+-- Asm (Template =>
+-- "fldln2 " & NL
+-- & "fxch " & NL
+-- & "fyl2x " & NL,
+-- Outputs => Double'Asm_Output ("=t", Result),
+-- Inputs => Double'Asm_Input ("0", X));
+-- return Result;
+-- end Log;
+-- LLVM local end
------------
-- Reduce --
@@ -193,6 +207,12 @@
-- Sqrt --
----------
+ -- LLVM local begin
+ function C_Sqrt (X : Double) return Double;
+ pragma Import (C, C_Sqrt, "sqrt");
+ pragma Pure_Function (C_Sqrt);
+ -- LLVM local end
+
function Sqrt (X : Double) return Double is
Result : Double;
@@ -201,9 +221,8 @@
raise Argument_Error;
end if;
- Asm (Template => "fsqrt",
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs => Double'Asm_Input ("0", X));
+ -- LLVM local
+ Result := C_Sqrt (X);
return Result;
end Sqrt;
@@ -214,6 +233,23 @@
-- These are built using the previously implemented basic functions
+ -- LLVM local begin
+ function C_Sin (X : Double) return Double;
+ pragma Import (C, C_Sin, "sin");
+ pragma Pure_Function (C_Sin);
+
+ function C_Cos (X : Double) return Double;
+ pragma Import (C, C_Cos, "cos");
+ pragma Pure_Function (C_Cos);
+
+ function C_Tan (X : Double) return Double;
+ pragma Import (C, C_Tan, "tan");
+ pragma Pure_Function (C_Tan);
+
+ procedure Sin_Cos (X : Double; Sin, Cos : out Double);
+ pragma Import (C, Sin_Cos, "sincos");
+ -- LLVM local end
+
----------
-- Acos --
----------
@@ -267,27 +303,22 @@
case Quadrant is
when 0 =>
- Asm (Template => "fcos",
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs => Double'Asm_Input ("0", Reduced_X));
+ -- LLVM local
+ Result := C_Cos (Reduced_X);
when 1 =>
- Asm (Template => "fsin",
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs => Double'Asm_Input ("0", -Reduced_X));
+ -- LLVM local
+ Result := C_Sin (-Reduced_X);
when 2 =>
- Asm (Template => "fcos ; fchs",
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs => Double'Asm_Input ("0", Reduced_X));
+ -- LLVM local
+ Result := -C_Cos (Reduced_X);
when 3 =>
- Asm (Template => "fsin",
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs => Double'Asm_Input ("0", Reduced_X));
+ -- LLVM local
+ Result := C_Sin (Reduced_X);
end case;
else
- Asm (Template => "fcos",
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs => Double'Asm_Input ("0", Reduced_X));
+ -- LLVM local
+ Result := C_Cos (Reduced_X);
end if;
return Result;
@@ -297,26 +328,28 @@
-- Logarithmic_Pow --
---------------------
- function Logarithmic_Pow (X, Y : Double) return Double is
- Result : Double;
- begin
- Asm (Template => "" -- X : Y
- & "fyl2x " & NL -- Y * Log2 (X)
- & "fst %%st(1) " & NL -- Y * Log2 (X) : Y * Log2 (X)
- & "frndint " & NL -- Int (...) : Y * Log2 (X)
- & "fsubr %%st, %%st(1)" & NL -- Int (...) : Fract (...)
- & "fxch " & NL -- Fract (...) : Int (...)
- & "f2xm1 " & NL -- 2**Fract (...) - 1 : Int (...)
- & "fld1 " & NL -- 1 : 2**Fract (...) - 1 : Int (...)
- & "faddp %%st, %%st(1)" & NL -- 2**Fract (...) : Int (...)
- & "fscale " & NL -- 2**(Fract (...) + Int (...))
- & "fstp %%st(1) ",
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs =>
- (Double'Asm_Input ("0", X),
- Double'Asm_Input ("u", Y)));
- return Result;
- end Logarithmic_Pow;
+-- LLVM local begin
+-- function Logarithmic_Pow (X, Y : Double) return Double is
+-- Result : Double;
+-- begin
+-- Asm (Template => "" -- X : Y
+-- & "fyl2x " & NL -- Y * Log2 (X)
+-- & "fst %%st(1) " & NL -- Y * Log2 (X) : Y * Log2 (X)
+-- & "frndint " & NL -- Int (...) : Y * Log2 (X)
+-- & "fsubr %%st, %%st(1)" & NL -- Int (...) : Fract (...)
+-- & "fxch " & NL -- Fract (...) : Int (...)
+-- & "f2xm1 " & NL -- 2**Fract (...) - 1 : Int (...)
+-- & "fld1 " & NL -- 1 : 2**Fract (...) - 1 : Int (...)
+-- & "faddp %%st, %%st(1)" & NL -- 2**Fract (...) : Int (...)
+-- & "fscale " & NL -- 2**(Fract (...) + Int (...))
+-- & "fstp %%st(1) ",
+-- Outputs => Double'Asm_Output ("=t", Result),
+-- Inputs =>
+-- (Double'Asm_Input ("0", X),
+-- Double'Asm_Input ("u", Y)));
+-- return Result;
+-- end Logarithmic_Pow;
+-- LLVM local end
---------
-- Pow --
@@ -453,27 +486,22 @@
case Quadrant is
when 0 =>
- Asm (Template => "fsin",
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs => Double'Asm_Input ("0", Reduced_X));
+ -- LLVM local
+ Result := C_Sin (Reduced_X);
when 1 =>
- Asm (Template => "fcos",
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs => Double'Asm_Input ("0", Reduced_X));
+ -- LLVM local
+ Result := C_Cos (Reduced_X);
when 2 =>
- Asm (Template => "fsin",
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs => Double'Asm_Input ("0", -Reduced_X));
+ -- LLVM local
+ Result := C_Sin (-Reduced_X);
when 3 =>
- Asm (Template => "fcos ; fchs",
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs => Double'Asm_Input ("0", Reduced_X));
+ -- LLVM local
+ Result := -C_Cos (Reduced_X);
end case;
else
- Asm (Template => "fsin",
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs => Double'Asm_Input ("0", Reduced_X));
+ -- LLVM local
+ Result := C_Sin (Reduced_X);
end if;
return Result;
@@ -487,32 +515,26 @@
Reduced_X : Double := X;
Result : Double;
Quadrant : Natural range 0 .. 3;
+ -- LLVM local
+ Sin, Cos : Double;
begin
if abs X > Pi / 4.0 then
Reduce (Reduced_X, Quadrant);
if Quadrant mod 2 = 0 then
- Asm (Template => "fptan" & NL
- & "ffree %%st(0)" & NL
- & "fincstp",
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs => Double'Asm_Input ("0", Reduced_X));
+ -- LLVM local
+ Result := C_Tan (Reduced_X);
else
- Asm (Template => "fsincos" & NL
- & "fdivp %%st, %%st(1)" & NL
- & "fchs",
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs => Double'Asm_Input ("0", Reduced_X));
+ -- LLVM local begin
+ Sin_Cos (X, Sin, Cos);
+ Result := -(Cos / Sin);
+ -- LLVM local end
end if;
else
- Asm (Template =>
- "fptan " & NL
- & "ffree %%st(0) " & NL
- & "fincstp ",
- Outputs => Double'Asm_Output ("=t", Result),
- Inputs => Double'Asm_Input ("0", Reduced_X));
+ -- LLVM local
+ Result := C_Tan (Reduced_X);
end if;
return Result;
Modified: llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.ads
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.ads?rev=41322&r1=41321&r2=41322&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.ads (original)
+++ llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.ads Thu Aug 23 11:04:48 2007
@@ -81,4 +81,11 @@
pragma Inline (Sin);
pragma Inline (Sqrt);
+ -- LLVM local begin
+ pragma Import (C, Exp, "exp");
+ pragma Pure_Function (Exp);
+ pragma Import (C, Log, "log");
+ pragma Pure_Function (Log);
+ -- LLVM local end
+
end Ada.Numerics.Aux;
More information about the llvm-commits
mailing list