浏览代码

* llvm requires that single precision constants are exactly representable
using single precision -> convert them to single precision in the code
generator

git-svn-id: branches/hlcgllvm@27001 -

Jonas Maebe 11 年之前
父节点
当前提交
227ff0ea48
共有 3 个文件被更改,包括 31 次插入2 次删除
  1. 2 0
      compiler/aasmtai.pas
  2. 24 1
      compiler/llvm/aasmllvm.pas
  3. 5 1
      compiler/llvm/agllvm.pas

+ 2 - 0
compiler/aasmtai.pas

@@ -257,6 +257,7 @@ interface
 {$endif jvm}
 {$ifdef llvm}
        { llvm only }
+       ,top_single
        ,top_double
 {$ifdef cpuextended}
        ,top_extended80
@@ -311,6 +312,7 @@ interface
           top_wstring : (pwstrval: pcompilerwidestring);
       {$endif jvm}
       {$ifdef llvm}
+          top_single : (sval:single);
           top_double : (dval:double);
         {$ifdef cpuextended}
           top_extended80 : (eval:extended);

+ 24 - 1
compiler/llvm/aasmllvm.pas

@@ -96,6 +96,7 @@ interface
         constructor getelementptr_reg_size_ref_size_const(dst:tregister;ptrsize:tdef;const ref:treference;indextype:tdef;index1:ptrint;indirect:boolean);
 
         procedure loaddef(opidx: longint; _def: tdef);
+        procedure loadsingle(opidx: longint; _sval: single);
         procedure loaddouble(opidx: longint; _dval: double);
 {$ifdef cpuextended}
         procedure loadextended(opidx: longint; _eval: extended);
@@ -205,6 +206,19 @@ uses
       end;
 
 
+    procedure taillvm.loadsingle(opidx: longint; _sval: single);
+      begin
+        allocate_oper(opidx+1);
+        with oper[opidx]^ do
+         begin
+           if typ<>top_single then
+             clearop(opidx);
+           sval:=_sval;
+           typ:=top_single;
+         end;
+      end;
+
+
     procedure taillvm.loaddouble(opidx: longint; _dval: double);
       begin
         allocate_oper(opidx+1);
@@ -503,7 +517,16 @@ uses
         ops:=4;
         loadreg(0,dst);
         loaddef(1,fromsize);
-        loaddouble(2,src);
+        if fromsize.typ<>floatdef then
+          internalerror(2014012214);
+        case tfloatdef(fromsize).floattype of
+          s32real:
+            loadsingle(2,src);
+          s64real:
+            loaddouble(2,src);
+          else
+            internalerror(2014012215);
+        end;
         loaddef(3,tosize);
       end;
 

+ 5 - 1
compiler/llvm/agllvm.pas

@@ -261,6 +261,7 @@ implementation
            begin
              getopstr:=llvm_fpcond2str[o.fpcond];
            end;
+         top_single,
          top_double:
            begin
              { "When using the hexadecimal form, constants of types half,
@@ -269,7 +270,10 @@ implementation
 
                And always in big endian form (sign bit leftmost)
              }
-             doubleval.d:=o.dval;
+             if o.typ=top_double then
+               doubleval.d:=o.dval
+             else
+               doubleval.d:=o.sval;
              result:='0x'+hexstr(doubleval.i,16);
            end;
          top_para: