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

This commit is contained in:
Nikolay Nikolov 2021-10-14 10:34:08 +03:00
parent df92d88f39
commit b91fc3a0d3
3 changed files with 37 additions and 5 deletions

View File

@ -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

View File

@ -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;

View File

@ -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)];