瀏覽代碼

* fixed passing of floats for cdecl procedures/functions

git-svn-id: trunk@726 -
florian 20 年之前
父節點
當前提交
c15f720867
共有 3 個文件被更改,包括 34 次插入3 次删除
  1. 29 0
      compiler/arm/cgcpu.pas
  2. 3 1
      compiler/arm/cpupara.pas
  3. 2 2
      compiler/ncgcal.pas

+ 29 - 0
compiler/arm/cgcpu.pas

@@ -70,6 +70,7 @@ unit cgcpu;
         procedure a_loadfpu_ref_reg(list: taasmoutput; size: tcgsize; const ref: treference; reg: tregister); override;
         procedure a_loadfpu_reg_ref(list: taasmoutput; size: tcgsize; reg: tregister; const ref: treference); override;
 
+        procedure a_paramfpu_ref(list : taasmoutput;size : tcgsize;const ref : treference;const paraloc : TCGPara);override;
         {  comparison operations }
         procedure a_cmp_const_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;a : aint;reg : tregister;
           l : tasmlabel);override;
@@ -839,6 +840,34 @@ unit cgcpu;
        end;
 
 
+    procedure tcgarm.a_paramfpu_ref(list : taasmoutput;size : tcgsize;const ref : treference;const paraloc : TCGPara);
+      var
+         href,href2 : treference;
+         hloc : pcgparalocation;
+      begin
+        href:=ref;
+        hloc:=paraloc.location;
+        while assigned(hloc) do
+          begin
+            case hloc^.loc of
+              LOC_FPUREGISTER,LOC_CFPUREGISTER:
+                a_loadfpu_ref_reg(list,size,ref,hloc^.register);
+              LOC_REGISTER :
+                a_load_ref_reg(list,hloc^.size,hloc^.size,href,hloc^.register);
+              LOC_REFERENCE :
+                begin
+                  reference_reset_base(href2,hloc^.reference.index,hloc^.reference.offset);
+                  a_load_ref_ref(list,hloc^.size,hloc^.size,href,href2);
+                end;
+              else
+                internalerror(200408241);
+           end;
+           inc(href.offset,tcgsize2size[hloc^.size]);
+           hloc:=hloc^.next;
+         end;
+      end;
+
+
      procedure tcgarm.a_loadfpu_reg_reg(list: taasmoutput; size: tcgsize; reg1, reg2: tregister);
        begin
          list.concat(setoppostfix(taicpu.op_reg_reg(A_MVF,reg2,reg1),cgsize2fpuoppostfix[size]));

+ 3 - 1
compiler/arm/cpupara.pas

@@ -107,7 +107,7 @@ unit cpupara;
             orddef:
               getparaloc:=LOC_REGISTER;
             floatdef:
-              if calloption=pocall_softfloat then
+              if calloption in [pocall_cdecl,pocall_cppdecl,pocall_softfloat] then
                 getparaloc:=LOC_REGISTER
               else
                 getparaloc:=LOC_FPUREGISTER;
@@ -288,6 +288,8 @@ unit cpupara;
                    paraloc^.size:=OS_ADDR
                  else if paracgsize in [OS_64,OS_S64] then
                    paraloc^.size:=OS_32
+                 else if (loc=LOC_REGISTER) and (paracgsize in [OS_F32,OS_F64,OS_F80]) then
+                   paraloc^.size:=OS_32
                  else
                    paraloc^.size:=paracgsize;
                  case loc of

+ 2 - 2
compiler/ncgcal.pas

@@ -253,8 +253,8 @@ implementation
                      cg.a_param_ref(exprasmlist,left.location.size,left.location.reference,tempcgpara);
                    end;
 {$endif x86_64}
-{$ifdef sparc}
-                 { sparc pushes floats in normal registers }
+{$if defined(sparc) or defined(arm) }
+                 { sparc and arm passes floats in normal registers }
                  LOC_REGISTER,
                  LOC_CREGISTER,
 {$endif sparc}