2
0
Эх сурвалжийг харах

* fixed passing of singleton record parameters, containing a float in WebAssembly

Nikolay Nikolov 3 жил өмнө
parent
commit
b91fc3a0d3

+ 6 - 1
compiler/defutil.pas

@@ -1588,7 +1588,12 @@ implementation
             else
               result:=tfloat2tcgsize[tfloatdef(def).floattype];
           recorddef :
-            result:=int_cgsize(def.size);
+{$ifdef wasm32}
+            if (def.size in [4,8]) and (trecorddef(def).contains_float_field) then
+              result:=int_float_cgsize(def.size)
+            else
+{$endif wasm32}
+              result:=int_cgsize(def.size);
           arraydef :
             begin
               if is_dynamic_array(def) or not is_special_array(def) then

+ 17 - 2
compiler/wasm32/cpupara.pas

@@ -59,7 +59,7 @@ implementation
 
     uses
       cutils,verbose,systems,
-      defutil,wasmdef,
+      defutil,wasmdef,tgcpu,
       aasmcpu,
       hlcgobj;
 
@@ -241,6 +241,7 @@ implementation
         paracgsize   : tcgsize;
         paraofs      : longint;
         paradef      : tdef;
+        wbt          : TWasmBasicType;
       begin
         paraofs:=0;
         for i:=0 to paras.count-1 do
@@ -260,7 +261,21 @@ implementation
               end
             else
               begin
-                paracgsize:=def_cgsize(hp.vardef);
+                if (hp.vardef.typ=recorddef) and
+                   (trecorddef(hp.vardef).contains_float_field) and
+                   defToWasmBasic(hp.vardef,wbt) then
+                  begin
+                    case wbt of
+                      wbt_f32:
+                        paracgsize:=OS_F32;
+                      wbt_f64:
+                        paracgsize:=OS_F64;
+                      else
+                        internalerror(2021101401);
+                    end;
+                  end
+                else
+                  paracgsize:=def_cgsize(hp.vardef);
                 if paracgsize=OS_NO then
                   paracgsize:=OS_ADDR;
                 paradef:=hp.vardef;

+ 14 - 2
compiler/wasm32/hlcgcpu.pas

@@ -73,6 +73,8 @@ uses
       procedure incstack(list : TAsmList;slots: longint);
       procedure decstack(list : TAsmList;slots: longint);
 
+      class function def2regtyp(def: tdef): tregistertype; override;
+
       procedure a_load_const_cgpara(list : TAsmList;tosize : tdef;a : tcgint;const cgpara : TCGPara);override;
 
       function a_call_name(list : TAsmList;pd : tprocdef;const s : TSymStr; const paras: array of pcgpara; forceresdef: tdef; weak: boolean): tcgpara;override;
@@ -380,6 +382,16 @@ implementation
         list.concat(tai_comment.Create(strpnew('    freed '+tostr(slots)+', stack height = '+tostr(fevalstackheight))));
     end;
 
+
+  class function thlcgwasm.def2regtyp(def: tdef): tregistertype;
+    begin
+      if (def.typ=recorddef) and (def.size in [4,8]) and (trecorddef(def).contains_float_field) then
+        result:=R_FPUREGISTER
+      else
+        result:=inherited;
+    end;
+
+
   procedure thlcgwasm.a_load_const_cgpara(list: TAsmList; tosize: tdef; a: tcgint; const cgpara: TCGPara);
     begin
       tosize:=get_para_push_size(tosize);
@@ -2364,11 +2376,11 @@ implementation
             1: result := getputmem8[isload, is_signed(def)];
             2: result := getputmem16[isload, is_signed(def)];
             4:
-              if is_single(def) then
+              if is_single(def) or ((def.typ=recorddef) and (trecorddef(def).contains_float_field)) then
                 result := getputmemf32[isload]
               else
                 result := getputmem32[isload, is_signed(def)];
-            8: if is_double(def) then
+            8: if is_double(def) or ((def.typ=recorddef) and (trecorddef(def).contains_float_field)) then
                  result := getputmemf64[isload]
                else
                 result := getputmem64[isload, is_signed(def)];