diff options
author | nickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2021-04-17 13:58:55 +0000 |
---|---|---|
committer | nickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2021-04-17 13:58:55 +0000 |
commit | 104cf2150fec5d520a9bc86ca7b926f69cc13d16 (patch) | |
tree | 2cb63c204e4f01f40906a37761afb6bbcce96dcf | |
parent | 6a7363bea75330a3a4f4fc762b9c4af47d2655fe (diff) | |
download | fpc-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.pas | 62 |
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)); |