ソースを参照

* factored comp/currency-in-register handling out of a_loadfpu_reg_reg()
into llvmconvop() so it's also used by code using that routine

git-svn-id: trunk@33938 -

Jonas Maebe 9 年 前
コミット
ea54b6b2c5
3 ファイル変更37 行追加33 行削除
  1. 5 28
      compiler/llvm/hlcgllvm.pas
  2. 31 4
      compiler/llvm/llvmdef.pas
  3. 1 1
      compiler/llvm/nllvmtcon.pas

+ 5 - 28
compiler/llvm/hlcgllvm.pas

@@ -494,7 +494,7 @@ implementation
 
   procedure thlcgllvm.a_load_const_reg(list: TAsmList; tosize: tdef; a: tcgint; register: tregister);
     begin
-      list.concat(taillvm.op_reg_size_const_size(llvmconvop(ptrsinttype,tosize),register,ptrsinttype,a,tosize))
+      list.concat(taillvm.op_reg_size_const_size(llvmconvop(ptrsinttype,tosize,false),register,ptrsinttype,a,tosize))
     end;
 
 
@@ -604,7 +604,7 @@ implementation
       tmpreg: tregister;
       tmpintdef: tdef;
     begin
-      op:=llvmconvop(fromsize,tosize);
+      op:=llvmconvop(fromsize,tosize,true);
       { converting from pointer to something else and vice versa is only
         possible via an intermediate pass to integer. Same for "something else"
         to pointer. }
@@ -656,7 +656,7 @@ implementation
               tg.ungettemp(list,tmpref);
             end
           else
-            list.concat(taillvm.op_reg_size_ref_size(llvmconvop(fromsize,tosize),register,fromsize,sref,tosize))
+            list.concat(taillvm.op_reg_size_ref_size(llvmconvop(fromsize,tosize,false),register,fromsize,sref,tosize))
         end
       else
         begin
@@ -1124,31 +1124,8 @@ implementation
   procedure thlcgllvm.a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tdef; reg1, reg2: tregister);
     var
       op: tllvmop;
-      intfromsize,
-      inttosize: longint;
-    begin
-      { treat comp and currency as extended in registers (see comment at start
-        of a_loadfpu_ref_reg) }
-      if tfloatdef(fromsize).floattype in [s64comp,s64currency] then
-        fromsize:=sc80floattype;
-      if tfloatdef(tosize).floattype in [s64comp,s64currency] then
-        tosize:=sc80floattype;
-      { at the value level, s80real and sc80real are the same }
-      if fromsize<>s80floattype then
-        intfromsize:=fromsize.size
-      else
-        intfromsize:=sc80floattype.size;
-      if tosize<>s80floattype then
-        inttosize:=tosize.size
-      else
-        inttosize:=sc80floattype.size;
-
-      if intfromsize<inttosize then
-        op:=la_fpext
-       else if intfromsize>inttosize then
-        op:=la_fptrunc
-      else
-        op:=la_bitcast;
+    begin
+      op:=llvmconvop(fromsize,tosize,true);
       { reg2 = bitcast fromllsize reg1 to tollsize }
       list.concat(taillvm.op_reg_size_reg_size(op,reg2,fromsize,reg1,tosize));
     end;

+ 31 - 4
compiler/llvm/llvmdef.pas

@@ -100,7 +100,7 @@ interface
       (struct, array) }
     function llvmaggregatetype(def: tdef): boolean;
 
-    function llvmconvop(fromsize, tosize: tdef): tllvmop;
+    function llvmconvop(var fromsize, tosize: tdef; inregs: boolean): tllvmop;
 
     { mangle a global identifier so that it's recognised by LLVM as a global
       (in the sense of module-global) label and so that it won't mangle the
@@ -148,7 +148,7 @@ implementation
     end;
 
 
-  function llvmconvop(fromsize, tosize: tdef): tllvmop;
+  function llvmconvop(var fromsize, tosize: tdef; inregs: boolean): tllvmop;
     var
       fromregtyp,
       toregtyp: tregistertype;
@@ -182,8 +182,35 @@ implementation
         end
       else
         begin
-          frombytesize:=fromsize.size;
-          tobytesize:=tosize.size;
+          { treat comp and currency as extended in registers (see comment at start
+            of thlgcobj.a_loadfpu_ref_reg) }
+          if inregs and
+             (fromsize.typ=floatdef) then
+            begin
+              if tfloatdef(fromsize).floattype in [s64comp,s64currency] then
+                fromsize:=sc80floattype;
+              { at the value level, s80real and sc80real are the same }
+              if tfloatdef(fromsize).floattype<>s80real then
+                frombytesize:=fromsize.size
+              else
+                frombytesize:=sc80floattype.size;
+            end
+          else
+            frombytesize:=fromsize.size;
+
+          if inregs and
+             (tosize.typ=floatdef) then
+            begin
+              if tfloatdef(tosize).floattype in [s64comp,s64currency] then
+                tosize:=sc80floattype;
+              if tfloatdef(tosize).floattype<>s80real then
+                tobytesize:=tosize.size
+              else
+                tobytesize:=sc80floattype.size;
+            end
+          else
+            tobytesize:=tosize.size;
+
           { need zero/sign extension, float truncation or plain bitcast? }
           if tobytesize<>frombytesize then
             begin

+ 1 - 1
compiler/llvm/nllvmtcon.pas

@@ -671,7 +671,7 @@ implementation
       if (fromdef.typ=procdef) and
          (todef.typ<>procdef) then
         fromdef:=cprocvardef.getreusableprocaddr(tprocdef(fromdef));
-      op:=llvmconvop(fromdef,todef);
+      op:=llvmconvop(fromdef,todef,false);
       case op of
         la_ptrtoint_to_x,
         la_x_to_inttoptr: