aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2015-03-21 04:59:45 +0100
committerTristan Gingold <tgingold@free.fr>2015-03-21 04:59:45 +0100
commit87f69712557aacc410e49bc9e51523171f37ddbe (patch)
tree9fdeece786755f5235a898c16e826680463b91b8 /src
parentaa82fb3fb5b83ab84486c54c4fc7c21b5ee2d3e0 (diff)
downloadghdl-87f69712557aacc410e49bc9e51523171f37ddbe.tar.gz
ghdl-87f69712557aacc410e49bc9e51523171f37ddbe.tar.bz2
ghdl-87f69712557aacc410e49bc9e51523171f37ddbe.zip
ortho_llvm: fix conversion from float to integer.
Diffstat (limited to 'src')
-rw-r--r--src/ortho/llvm/ortho_llvm.adb24
1 files changed, 21 insertions, 3 deletions
diff --git a/src/ortho/llvm/ortho_llvm.adb b/src/ortho/llvm/ortho_llvm.adb
index ce5213e64..be0c60f7c 100644
--- a/src/ortho/llvm/ortho_llvm.adb
+++ b/src/ortho/llvm/ortho_llvm.adb
@@ -81,6 +81,9 @@ package body Ortho_LLVM is
Stacksave_Name : constant String := "llvm.stacksave" & ASCII.NUL;
Stackrestore_Fun : ValueRef;
Stackrestore_Name : constant String := "llvm.stackrestore" & ASCII.NUL;
+ Copysign_Fun : ValueRef;
+ Copysign_Name : constant String := "llvm.copysign.f64" & ASCII.NUL;
+ Fp_0_5 : ValueRef;
-- For debugging
@@ -1512,9 +1515,17 @@ package body Ortho_LLVM is
when ON_Float_Type =>
-- Float to Int
if Rtype.Kind = ON_Signed_Type then
- Res := BuildFPToSI
- (Builder, Val.LLVM, Get_LLVM_Type (Rtype),
- Empty_Cstring);
+ -- FPtoSI rounds toward zero, so we need to add
+ -- copysign (0.5, x).
+ declare
+ V : ValueRef;
+ begin
+ V := BuildCall (Builder, Copysign_Fun,
+ (Fp_0_5, Val.LLVM), 2, Empty_Cstring);
+ V := BuildFAdd (Builder, Val.LLVM, V, Empty_Cstring);
+ Res := BuildFPToSI
+ (Builder, V, Get_LLVM_Type (Rtype), Empty_Cstring);
+ end;
end if;
when others =>
@@ -2900,6 +2911,13 @@ package body Ortho_LLVM is
(Module, Stackrestore_Name'Address,
FunctionType (VoidType, (1 => I8_Ptr_Type), 1, 0));
+ -- Create intrinsic 'double llvm.copysign.f64 (double, double)'.
+ Copysign_Fun := AddFunction
+ (Module, Copysign_Name'Address,
+ FunctionType (DoubleType, (0 .. 1 => DoubleType), 2, 0));
+
+ Fp_0_5 := ConstReal (DoubleType, 0.5);
+
if Flag_Debug_Line then
Debug_ID := GetMDKindID (Dbg_Str, Dbg_Str'Length);