Browse Source

* implement unary minus for floating point via -1.0*x instead of 0-x,
because otherwise -0.0 stays 0.0 (fixes webtbs/tw4534 for llvm)

git-svn-id: trunk@34990 -

Jonas Maebe 8 years ago
parent
commit
26a05518f8
1 changed files with 10 additions and 6 deletions
  1. 10 6
      compiler/llvm/nllvmmat.pas

+ 10 - 6
compiler/llvm/nllvmmat.pas

@@ -123,28 +123,32 @@ procedure tllvmmoddivnode.pass_generate_code;
 
 procedure Tllvmunaryminusnode.emit_float_sign_change(r: tregister; _size : tdef);
 var
-  zeroreg: tregister;
+  minusonereg: tregister;
 begin
+  { multiply with -1 instead of subtracting from 0, because otherwise we -x
+    won't turn into -0.0 if x was 0.0 (0.0 - 0.0 = 0.0, but -1.0 * 0.0 = -0.0 }
   if _size.typ<>floatdef then
     internalerror(2014012212);
-  zeroreg:=hlcg.getfpuregister(current_asmdata.CurrAsmList,_size);
+  minusonereg:=hlcg.getfpuregister(current_asmdata.CurrAsmList,_size);
   case tfloatdef(_size).floattype of
     s32real,s64real:
-      current_asmdata.CurrAsmList.concat(taillvm.op_reg_size_fpconst_size(la_bitcast,zeroreg,_size,0,_size));
+      current_asmdata.CurrAsmList.concat(taillvm.op_reg_size_fpconst_size(la_bitcast,minusonereg,_size,-1.0,_size));
     { comp and currency are handled as int64 at the llvm level }
     s64comp,
     s64currency:
       begin
         { sc80floattype instead of _size, see comment in thlcgllvm.a_loadfpu_ref_reg }
         _size:=sc80floattype;
-        current_asmdata.CurrAsmList.concat(taillvm.op_reg_size_const_size(la_sitofp,zeroreg,s64inttype,0,_size));
+        current_asmdata.CurrAsmList.concat(taillvm.op_reg_size_const_size(la_sitofp,minusonereg,s64inttype,-1,_size));
       end;
 {$ifdef cpuextended}
     s80real,sc80real:
-      current_asmdata.CurrAsmList.concat(taillvm.op_reg_size_fpconst80_size(la_bitcast,zeroreg,_size,0.0,_size));
+      current_asmdata.CurrAsmList.concat(taillvm.op_reg_size_fpconst80_size(la_bitcast,minusonereg,_size,-1.0,_size));
 {$endif cpuextended}
+    else
+      internalerror(2016112701);
   end;
-  current_asmdata.CurrAsmList.Concat(taillvm.op_reg_size_reg_reg(la_fsub,r,_size,zeroreg,r));
+  current_asmdata.CurrAsmList.Concat(taillvm.op_reg_size_reg_reg(la_fmul,r,_size,minusonereg,r));
 end;