summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2>2021-04-17 13:58:55 +0000
committernickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2>2021-04-17 13:58:55 +0000
commit104cf2150fec5d520a9bc86ca7b926f69cc13d16 (patch)
tree2cb63c204e4f01f40906a37761afb6bbcce96dcf
parent6a7363bea75330a3a4f4fc762b9c4af47d2655fe (diff)
downloadfpc-104cf2150fec5d520a9bc86ca7b926f69cc13d16.tar.gz
+ fixed code generation for high(dynarray) for the WebAssembly target
git-svn-id: https://svn.freepascal.org/svn/fpc/trunk@49217 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--compiler/wasm32/nwasminl.pas62
1 files changed, 61 insertions, 1 deletions
diff --git a/compiler/wasm32/nwasminl.pas b/compiler/wasm32/nwasminl.pas
index b24a6d2516..4a456b263f 100644
--- a/compiler/wasm32/nwasminl.pas
+++ b/compiler/wasm32/nwasminl.pas
@@ -34,6 +34,7 @@ interface
twasminlinenode = class(tcginlinenode)
private
+ procedure second_high; override;
procedure second_memory_size;
procedure second_memory_grow;
procedure second_unreachable;
@@ -52,13 +53,72 @@ implementation
aasmbase,aasmdata,aasmcpu,
cgbase,cgutils,
hlcgobj,hlcgcpu,
- defutil,pass_2,
+ defutil,pass_2,verbose,
symtype,symdef;
{*****************************************************************************
twasminlinenode
*****************************************************************************}
+ procedure twasminlinenode.second_high;
+ var
+ hightype: TWasmBasicType;
+ begin
+ secondpass(left);
+ if not(is_dynamic_array(left.resultdef)) then
+ Internalerror(2019122801);
+ { determine the WasmBasicType of the result }
+ if is_64bit(resultdef) then
+ hightype:=wbt_i64
+ else
+ hightype:=wbt_i32;
+ { length in dynamic arrays is at offset -sizeof(pint) }
+ thlcgwasm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
+ { 64-bit pointer values need a <>0 comparison to produce a 32-bit int on the stack (0 or 1) for the 'if' instruction.
+ 32-bit pointer values don't need it, because 'if' already expects and pops a 32-bit int and checks for <>0. }
+ if is_64bit(left.resultdef) then
+ begin
+ thlcgwasm(hlcg).a_load_const_stack(current_asmdata.CurrAsmList,left.resultdef,0,R_INTREGISTER);
+ thlcgwasm(hlcg).a_cmp_stack_stack(current_asmdata.CurrAsmList,left.resultdef,OC_NE);
+ end;
+ { if not nil }
+ current_asmdata.CurrAsmList.Concat(taicpu.op_functype(a_if,TWasmFuncType.Create([],[hightype])));
+ thlcgwasm(hlcg).incblock;
+ thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1);
+ { volatility of the dyn. array refers to the volatility of the
+ string pointer, not of the string data }
+ thlcgwasm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
+ { length in dynamic arrays is at offset -ossinttype.size }
+ thlcgwasm(hlcg).a_op_const_stack(current_asmdata.CurrAsmList,OP_SUB,left.resultdef,ossinttype.size);
+ { load length }
+ if ossinttype.size=8 then
+ current_asmdata.CurrAsmList.Concat(taicpu.op_const(a_i64_load,0))
+ else
+ current_asmdata.CurrAsmList.Concat(taicpu.op_const(a_i32_load,0));
+ { else }
+ current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_else));
+ thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1);
+ { high=-1 }
+ thlcgwasm(hlcg).a_load_const_stack(current_asmdata.CurrAsmList,resultdef,-1,R_INTREGISTER);
+ { endif }
+ current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_end_if));
+ thlcgwasm(hlcg).decblock;
+
+ location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
+{$if not defined(cpu64bitalu) and not defined(cpuhighleveltarget)}
+ if location.size in [OS_64,OS_S64] then
+ begin
+ location.register64.reglo := cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+ location.register64.reghi := cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+ end
+ else
+{$endif}
+ location.register := hlcg.getintregister(current_asmdata.CurrAsmList,resultdef);
+
+ thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
+ end;
+
+
procedure twasminlinenode.second_memory_size;
begin
current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_memory_size));