diff --git a/.gitattributes b/.gitattributes index 1aa1fdec4d..8ab7571a71 100644 --- a/.gitattributes +++ b/.gitattributes @@ -979,6 +979,7 @@ compiler/wasm32/cpupara.pas svneol=native#text/plain compiler/wasm32/cpupi.pas svneol=native#text/plain compiler/wasm32/cputarg.pas svneol=native#text/plain compiler/wasm32/hlcgcpu.pas svneol=native#text/plain +compiler/wasm32/itcpugas.pas svneol=native#text/plain compiler/wasm32/itcpuwasm.pas svneol=native#text/plain compiler/wasm32/nwasmadd.pas svneol=native#text/plain compiler/wasm32/nwasmcal.pas svneol=native#text/plain @@ -993,6 +994,7 @@ compiler/wasm32/rwasmrni.inc svneol=native#text/plain compiler/wasm32/rwasmsri.inc svneol=native#text/plain compiler/wasm32/rwasmstd.inc svneol=native#text/plain compiler/wasm32/rwasmsup.inc svneol=native#text/plain +compiler/wasm32/strinst.inc svneol=native#text/plain compiler/wasm32/symcpu.pas svneol=native#text/plain compiler/wasm32/tgcpu.pas svneol=native#text/plain compiler/wasm32/tripletcpu.pas svneol=native#text/plain diff --git a/compiler/wasm32/agllvmmc.pas b/compiler/wasm32/agllvmmc.pas index 0b671b3728..ef4fda1ec1 100644 --- a/compiler/wasm32/agllvmmc.pas +++ b/compiler/wasm32/agllvmmc.pas @@ -31,16 +31,15 @@ interface systems, globtype,globals, aasmbase,aasmtai,aasmdata, - assemble; + assemble,aggas; type { TLLVMMachineCodePlaygroundAssembler } - TLLVMMachineCodePlaygroundAssembler=class(texternalassembler) - public - procedure WriteTree(p : TAsmList); override; - procedure WriteAsmList;override; + TLLVMMachineCodePlaygroundAssembler=class({texternalassembler}TGNUassembler) + protected + function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override; end; implementation @@ -52,379 +51,12 @@ implementation { TLLVMMachineCodePlaygroundAssembler } - procedure TLLVMMachineCodePlaygroundAssembler.WriteTree(p: TAsmList); - var - lasthp, - hp: tai; - InlineLevel : longint; - prevfileinfo : tfileposinfo; - previnfile : tinputfile; - counter,lines,i,j,l,tokens,pos,last_align: longint; - quoted, do_line: Boolean; - s, LastSecName: string; - LastAlign: Integer; - LastSecOrder: TAsmSectionOrder; + function TLLVMMachineCodePlaygroundAssembler.sectionname(atype: TAsmSectiontype; const aname: string; aorder: TAsmSectionOrder): string; begin - if not assigned(p) then - exit; - InlineLevel:=0; - last_align:=1; - lasthp:=nil; - { lineinfo is only needed for al_procedures (PFV) } - do_line:=(cs_asm_source in current_settings.globalswitches) or - ((cs_lineinfo in current_settings.moduleswitches) - and (p=current_asmdata.asmlists[al_procedures])); - hp:=tai(p.first); - while assigned(hp) do - begin - prefetch(pointer(hp.next)^); - if not(hp.typ in SkipLineInfo) then - begin - previnfile:=lastinfile; - prevfileinfo:=lastfileinfo; - current_filepos:=tailineinfo(hp).fileinfo; - - { no line info for inlined code } - if do_line and (inlinelevel=0) then - WriteSourceLine(hp as tailineinfo); - (*if (lastfileinfo.line<>prevfileinfo.line) or - (previnfile<>lastinfile) then - begin - { +0 postfix means no line increment per assembler instruction } - writer.AsmWrite('%LINE '+tostr(current_filepos.line)+'+0'); - if assigned(lastinfile) and ((previnfile<>lastinfile) or NewObject) then - writer.AsmWriteLn(' '+lastinfile.name) - else - writer.AsmLn; - NewObject:=false; - end;*) - end; - case hp.typ of - ait_comment : - begin - writer.AsmWrite(asminfo^.comment); - writer.AsmWritePChar(tai_comment(hp).str); - writer.AsmLn; - end; - ait_regalloc : - begin - if (cs_asm_regalloc in current_settings.globalswitches) then - writer.AsmWriteLn(#9#9+asminfo^.comment+'Register '+std_regname(tai_regalloc(hp).reg)+' '+ - regallocstr[tai_regalloc(hp).ratype]); - end; - ait_tempalloc : - begin - if (cs_asm_tempalloc in current_settings.globalswitches) then - WriteTempalloc(tai_tempalloc(hp)); - end; -// ait_section : -// begin -// if tai_section(hp).sectype<>sec_none then -// WriteSection(tai_section(hp).sectype,tai_section(hp).name^,tai_section(hp).secorder, -// tai_section(hp).secalign,tai_section(hp).secflags,tai_section(hp).secprogbits) -// else -// begin -//{$ifdef EXTDEBUG} -// writer.AsmWrite(asminfo^.comment); -// writer.AsmWriteln(' sec_none'); -//{$endif EXTDEBUG} -// end; -// end; -// ait_align : -// begin -// doalign(tai_align_abstract(hp).aligntype,tai_align_abstract(hp).use_op,tai_align_abstract(hp).fillop,tai_align_abstract(hp).maxbytes,last_align,lasthp); -// end; - ait_label : - begin - if tai_label(hp).labsym.is_used then - begin - writer.AsmWrite(ApplyAsmSymbolRestrictions(tai_label(hp).labsym.name)); - if tai_label(hp).labsym.bind in [AB_GLOBAL,AB_PRIVATE_EXTERN] then - writer.AsmWriteLn('::') - else - writer.AsmWriteLn(':'); - end; - end; - ait_symbol : - begin - writer.AsmWrite(asminfo^.comment); - writer.AsmWrite('ait_symbol '); - writer.AsmWrite(tai_symbol(hp).sym.name); - writer.AsmWrite(' is_global='+tostr(Ord(tai_symbol(hp).is_global))+' has_value='+tostr(Ord(tai_symbol(hp).has_value))); - writer.AsmWrite(' size='+tostr(tai_symbol(hp).size)); - writer.AsmWrite(' value='+tostr(tai_symbol(hp).value)); - writer.AsmWrite(' sym.typ='); - Str(tai_symbol(hp).sym.typ,s); - writer.AsmWrite(s); - writer.AsmWrite(' sym.bind='); - Str(tai_symbol(hp).sym.bind,s); - writer.AsmWrite(s); - writer.AsmLn; - writer.AsmWriteLn(asminfo^.comment+'TODO: implement'); - // TODO: resolve errors such as "LLVM ERROR: data symbols must have a size set with .size: RTTI_$SYSTEM_$$_formal" - //if not(tai_symbol(hp).has_value) then - // begin - // //if tai_symbol(hp).is_global then - // // writer.AsmWriteLn(ApplyAsmSymbolRestrictions(tai_symbol(hp).sym.name) + '::') - // //else - // writer.AsmWriteLn(ApplyAsmSymbolRestrictions(tai_symbol(hp).sym.name) + ':'); - // end - //else - // begin - // if tai_symbol(hp).is_global then - // writer.AsmWriteLn(ApplyAsmSymbolRestrictions(tai_symbol(hp).sym.name) + '==' + tostr(tai_symbol(hp).value)) - // else - // writer.AsmWriteLn(ApplyAsmSymbolRestrictions(tai_symbol(hp).sym.name) + '=' + tostr(tai_symbol(hp).value)); - // end; - end; - ait_symbol_end : - begin - writer.AsmWrite(asminfo^.comment); - writer.AsmWrite('ait_symbol_end '); - writer.AsmWrite(tai_symbol_end(hp).sym.name); - writer.AsmWrite(' sym.typ='); - Str(tai_symbol_end(hp).sym.typ,s); - writer.AsmWrite(s); - writer.AsmWrite(' sym.bind='); - Str(tai_symbol_end(hp).sym.bind,s); - writer.AsmWrite(s); - writer.AsmLn; - end; - ait_datablock : - begin - if tai_datablock(hp).is_global or SmartAsm then - writer.AsmWrite(ApplyAsmSymbolRestrictions(tai_datablock(hp).sym.name) + '::') - else - writer.AsmWrite(ApplyAsmSymbolRestrictions(tai_datablock(hp).sym.name) + ':'); - {if SmartAsm then - AddSymbol(tai_datablock(hp).sym.name,true);} - writer.AsmWriteLn(#9'.rs'#9+tostr(tai_datablock(hp).size)); - end; - ait_realconst: - WriteRealConstAsBytes(tai_realconst(hp),#9'.db'#9,do_line); -// ait_const: -// begin -// consttype:=tai_const(hp).consttype; -// case consttype of -// aitconst_uleb128bit: -// WriteDecodedUleb128(qword(tai_const(hp).value)); -// aitconst_sleb128bit: -// WriteDecodedSleb128(int64(tai_const(hp).value)); -// aitconst_64bit, -// aitconst_64bit_unaligned, -// aitconst_32bit, -// aitconst_32bit_unaligned: -// begin -// writer.AsmWrite(#9'.dw'#9); -// l:=0; -// tokens:=1; -// repeat -// if assigned(tai_const(hp).sym) then -// begin -// if assigned(tai_const(hp).endsym) then -// s:=ApplyAsmSymbolRestrictions(tai_const(hp).endsym.name)+'-'+ApplyAsmSymbolRestrictions(tai_const(hp).sym.name) -// else -// s:=ApplyAsmSymbolRestrictions(tai_const(hp).sym.name); -// if tai_const(hp).value<>0 then -// s:=s+tostr_with_plus(tai_const(hp).value); -// if consttype in [aitconst_64bit,aitconst_64bit_unaligned] then -// s:=s+',0,0,0' -// else -// s:=s+',0'; -// end -// else -// if consttype in [aitconst_64bit,aitconst_64bit_unaligned] then -// s:=tostr(Word(tai_const(hp).value)) +','+tostr(Word(tai_const(hp).value shr 16))+','+ -// tostr(Word(tai_const(hp).value shr 32))+','+tostr(Word(tai_const(hp).value shr 48)) -// else -// s:=tostr(Word(tai_const(hp).value))+','+tostr(Word(tai_const(hp).value shr 16)); -// writer.AsmWrite(s); -// inc(l,length(s)); -// inc(tokens); -// if (l>line_length) or -// (tokens>max_tokens) or -// (hp.next=nil) or -// (tai(hp.next).typ<>ait_const) or -// (tai_const(hp.next).consttype<>consttype) then -// break; -// hp:=tai(hp.next); -// writer.AsmWrite(','); -// until false; -// { Substract section start for secrel32 type } -// {if consttype=aitconst_secrel32_symbol then -// writer.AsmWrite(' - $$');} -// writer.AsmLn; -// end; -// {aitconst_128bit,} -// aitconst_16bit, -// aitconst_8bit, -// aitconst_16bit_unaligned{, -// aitconst_rva_symbol, -// aitconst_secrel32_symbol} : -// begin -// writer.AsmWrite(ait_const2str[consttype]); -// l:=0; -// tokens:=1; -// repeat -// if assigned(tai_const(hp).sym) then -// begin -// if assigned(tai_const(hp).endsym) then -// s:=ApplyAsmSymbolRestrictions(tai_const(hp).endsym.name)+'-'+ApplyAsmSymbolRestrictions(tai_const(hp).sym.name) -// else -// s:=ApplyAsmSymbolRestrictions(tai_const(hp).sym.name); -// if tai_const(hp).value<>0 then -// s:=s+tostr_with_plus(tai_const(hp).value); -// end -// else -// s:=tostr(tai_const(hp).value); -// writer.AsmWrite(s); -// inc(l,length(s)); -// inc(tokens); -// if (l>line_length) or -// (tokens>max_tokens) or -// (hp.next=nil) or -// (tai(hp.next).typ<>ait_const) or -// (tai_const(hp.next).consttype<>consttype) then -// break; -// hp:=tai(hp.next); -// writer.AsmWrite(','); -// until false; -// { Substract section start for secrel32 type } -// if consttype=aitconst_secrel32_symbol then -// writer.AsmWrite(' - $$'); -// writer.AsmLn; -// end; -// else -// begin -// writer.AsmWrite(asminfo^.comment); -// writer.AsmWrite('WARNING: not yet implemented in assembler output: '); -// Str(consttype,s); -// writer.AsmWriteLn(s); -// end; -// end; -// end; -// ait_string : -// begin -// pos:=0; -// for i:=1 to tai_string(hp).len do -// begin -// if pos=0 then -// begin -// writer.AsmWrite(#9'.ascii'#9'"'); -// pos:=20; -// end; -// ch:=tai_string(hp).str[i-1]; -// case ch of -// #0, {This can't be done by range, because a bug in FPC} -// #1..#31, -// #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7); -// '"' : s:='\"'; -// '\' : s:='\\'; -// else -// s:=ch; -// end; -// writer.AsmWrite(s); -// inc(pos,length(s)); -// if (pos>line_length) or (i=tai_string(hp).len) then -// begin -// writer.AsmWriteLn('"'); -// pos:=0; -// end; -// end; -// end; -// ait_instruction : -// begin -// WriteInstruction(taicpu(hp)); -// end; - ait_directive : - begin - case tai_directive(hp).directive of - asd_cpu : - writer.AsmWriteLn('; CPU '+tai_directive(hp).name); - else - begin - writer.AsmWrite(asminfo^.comment); - writer.AsmWrite('WARNING: not yet implemented in assembler output: ait_directive.'); - Str(tai_directive(hp).directive,s); - writer.AsmWriteLn(s); - end; - end; - end; -// ait_cutobject : -// begin -// if SmartAsm then -// begin -// { only reset buffer if nothing has changed } -// if not writer.ClearIfEmpty then -// begin -// {if SmartAsm then -// begin -// WriteSmartExternals; -// FreeExternChainList; -// end; -// WriteGroups;} -// writer.AsmClose; -// DoAssemble; -// writer.AsmCreate(tai_cutobject(hp).place); -// {ResetSectionsList; -// WriteHeader;} -// end; -// { avoid empty files } -// LastSecType:=sec_none; -// LastSecName:=''; -// LastSecOrder:=secorder_default; -// LastAlign:=1; -// while assigned(hp.next) and (tai(hp.next).typ in [ait_cutobject,ait_section,ait_comment]) do -// begin -// if tai(hp.next).typ=ait_section then -// begin -// LastSecType:=tai_section(hp.next).sectype; -// LastSecName:=tai_section(hp.next).name^; -// LastSecOrder:=tai_section(hp.next).secorder; -// LastAlign:=tai_section(hp.next).secalign; -// end; -// hp:=tai(hp.next); -// end; -// if LastSecType<>sec_none then -// WriteSection(LastSecType,LastSecName,LastSecOrder,LastAlign); -// writer.MarkEmpty; -// //NewObject:=true; -// end; -// end; - ait_marker : - if tai_marker(hp).kind=mark_NoLineInfoStart then - inc(InlineLevel) - else if tai_marker(hp).kind=mark_NoLineInfoEnd then - dec(InlineLevel); - ait_stab, - ait_force_line, - ait_function_name : ; - else - begin - writer.AsmWrite(asminfo^.comment); - writer.AsmWrite('WARNING: not yet implemented in assembler output: '); - Str(hp.typ,s); - writer.AsmWriteLn(s); - end; - end; - lasthp:=hp; - hp:=tai(hp.next); - end; + Result:=inherited sectionname(atype, aname, aorder)+',"",@'; end; - procedure TLLVMMachineCodePlaygroundAssembler.WriteAsmList; - var - hal: TAsmListType; - begin - for hal:=low(TasmlistType) to high(TasmlistType) do - begin - writer.AsmWriteLn(asminfo^.comment+'Begin asmlist '+AsmListTypeStr[hal]); - writetree(current_asmdata.asmlists[hal]); - writer.AsmWriteLn(asminfo^.comment+'End asmlist '+AsmListTypeStr[hal]); - end; - end; - const as_wasm32_llvm_mc_info : tasminfo = ( diff --git a/compiler/wasm32/itcpugas.pas b/compiler/wasm32/itcpugas.pas new file mode 100644 index 0000000000..d307c07a01 --- /dev/null +++ b/compiler/wasm32/itcpugas.pas @@ -0,0 +1,51 @@ +{ + Copyright (c) 1998-2012 by Florian Klaempfl and others + + This unit contains the WebAssembly GAS instruction tables + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + **************************************************************************** +} +unit itcpugas; + +{$i fpcdefs.inc} + +interface + + uses + cpubase,cgbase, + itcpuwasm; + + + const + { Standard opcode string table (for each tasmop enumeration). The + opcode strings should conform to the names as defined by the + processor manufacturer. + } + gas_op2str : op2strtable = ({$i strinst.inc}); + + function gas_regname(r:Tregister):string; + + +implementation + + + function gas_regname(r:Tregister):string; + begin + result:=generic_regname(r); + end; + +end. diff --git a/compiler/wasm32/itcpuwasm.pas b/compiler/wasm32/itcpuwasm.pas index 7bdfffddbd..40323c4b36 100644 --- a/compiler/wasm32/itcpuwasm.pas +++ b/compiler/wasm32/itcpuwasm.pas @@ -29,53 +29,7 @@ interface cpubase,cgbase; const - wasm_op2str : op2strtable = ( '', - // control flow - 'block', 'loop', 'br', 'br_if', 'br_table', 'if', 'else', 'end', - 'return', 'unreachable', - // basic - 'nop', 'drop', 'i32.const', 'i64.const', 'f32.const', 'f64.const', - 'get_local', 'set_local', 'tee_local', 'get_global', 'set_global', - 'select', 'call', 'call_indirect', - // integer - 'i32.add', 'i64.add', 'i32.sub', 'i64.sub', 'i32.mul', 'i64.mul', - 'i32.div_s', 'i64.div_s', 'i32.div_u', 'i64.div_u', 'i32.rem_s', 'i64.rem_s', - 'i32.rem_u', 'i64.rem_u', 'i32.and', 'i64.and', 'i32.or', 'i64.or', - 'i32.xor', 'i64.xor', 'i32.shl', 'i64.shl', 'i32.shr_s', 'i64.shr_s', - 'i32.shr_u', 'i64.shr_u', 'i32.rotl', 'i64.rotl', 'i32.rotr', 'i64.rotr', - 'i32.clz', 'i64.clz', 'i32.ctz', 'i64.ctz', 'i32.popcnt', 'i64.popcnt', - 'i32.eqz', 'i64.eqz', - // floating point - 'f32.add', 'f64.add', 'f32.sub', 'f64.sub', 'f32.mul', 'f64.mul', - 'f32.div', 'f64.div', 'f32.sqrt', 'f64.sqrt', 'f32.min', 'f64.min', - 'f32.max', 'f64.max', 'f32.ceil', 'f64.ceil', 'f32.floor', 'f64.floor', - 'f32.trunc', 'f64.trunc', 'f32.nearest', 'f64.nearest', 'f32.abs', 'f64.abs', - 'f32.neg', 'f64.neg', 'f32.copysign', 'f64.copysign', - // integer compare - 'i32.eq', 'i64.eq', 'i32.ne', 'i64.ne', 'i32.lt_s', 'i64.lt_s', - 'i32.lt_u', 'i64.lt_u', 'i32.le_s', 'i64.le_s', 'i32.le_u', 'i64.le_u', - 'i32.gt_s', 'i64.gt_s', 'i32.gt_u', 'i64.gt_u', 'i32.ge_s', 'i64.ge_s', - 'i32.ge_u', 'i64.ge_u', - // floating point compare - 'f32.eq', 'f64.eq', 'f32.ne', 'f64.ne', 'f32.lt', 'f64.lt', - 'f32.le', 'f64.le', 'f32.gt', 'f64.gt', 'f32.ge', 'f64.gt', - // conversion - 'i32.wrap/i64', 'i64.extend_s/i32', 'i64.extend_u/i32', - 'i32.trunc_s/f32', 'i32.trunc_s/f64', 'i64.trunc_s/f32', 'i64.trunc_s/f64', - 'i32.trunc_u/f32', 'i32.trunc_u/f64', 'i64.trunc_u/f32', 'i64.trunc_u/f64', - 'f32.demote/f64', 'f64.promote/f32', - 'f32.convert_s/i32', 'f32.convert_s/i64', 'f64.convert_s/i32', 'f64.convert_s/i64', - 'f32.convert_u/i32', 'f32.convert_u/i64', 'f64.convert_u/i32', 'f64.convert_u/i64', - 'i32.reinterpret/f32', 'i64.reinterpret/f64', 'f32.reinterpret/i32', 'f64.reinterpret/i64', - // load/store - 'i32.load', 'i64.load', 'f32.load', 'f64.load', - 'i32.store', 'i64.store', 'f32.store', 'f64.store', - 'i32.load8_s', 'i32.load16_s', 'i64.load8_s', 'i64.load16_s', 'i64.load32_s', - 'i32.load8_u', 'i32.load16_u', 'i64.load8_u', 'i64.load16_u', 'i64.load32_u', - 'i32.store8', 'i32.store16', 'i64.store8', 'i64.store16', 'i64.store32', - // additional memory - 'grow_memory', 'current_memory' - ); + wasm_op2str : op2strtable = ({$i strinst.inc}); implementation diff --git a/compiler/wasm32/strinst.inc b/compiler/wasm32/strinst.inc new file mode 100644 index 0000000000..d34e57a24b --- /dev/null +++ b/compiler/wasm32/strinst.inc @@ -0,0 +1,69 @@ +{ + Copyright (c) 2016 by Karoly Balogh + + This include file contains the WebAssembly instruction string table + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + **************************************************************************** +} + + '', + // control flow + 'block', 'loop', 'br', 'br_if', 'br_table', 'if', 'else', 'end', + 'return', 'unreachable', + // basic + 'nop', 'drop', 'i32.const', 'i64.const', 'f32.const', 'f64.const', + 'get_local', 'set_local', 'tee_local', 'get_global', 'set_global', + 'select', 'call', 'call_indirect', + // integer + 'i32.add', 'i64.add', 'i32.sub', 'i64.sub', 'i32.mul', 'i64.mul', + 'i32.div_s', 'i64.div_s', 'i32.div_u', 'i64.div_u', 'i32.rem_s', 'i64.rem_s', + 'i32.rem_u', 'i64.rem_u', 'i32.and', 'i64.and', 'i32.or', 'i64.or', + 'i32.xor', 'i64.xor', 'i32.shl', 'i64.shl', 'i32.shr_s', 'i64.shr_s', + 'i32.shr_u', 'i64.shr_u', 'i32.rotl', 'i64.rotl', 'i32.rotr', 'i64.rotr', + 'i32.clz', 'i64.clz', 'i32.ctz', 'i64.ctz', 'i32.popcnt', 'i64.popcnt', + 'i32.eqz', 'i64.eqz', + // floating point + 'f32.add', 'f64.add', 'f32.sub', 'f64.sub', 'f32.mul', 'f64.mul', + 'f32.div', 'f64.div', 'f32.sqrt', 'f64.sqrt', 'f32.min', 'f64.min', + 'f32.max', 'f64.max', 'f32.ceil', 'f64.ceil', 'f32.floor', 'f64.floor', + 'f32.trunc', 'f64.trunc', 'f32.nearest', 'f64.nearest', 'f32.abs', 'f64.abs', + 'f32.neg', 'f64.neg', 'f32.copysign', 'f64.copysign', + // integer compare + 'i32.eq', 'i64.eq', 'i32.ne', 'i64.ne', 'i32.lt_s', 'i64.lt_s', + 'i32.lt_u', 'i64.lt_u', 'i32.le_s', 'i64.le_s', 'i32.le_u', 'i64.le_u', + 'i32.gt_s', 'i64.gt_s', 'i32.gt_u', 'i64.gt_u', 'i32.ge_s', 'i64.ge_s', + 'i32.ge_u', 'i64.ge_u', + // floating point compare + 'f32.eq', 'f64.eq', 'f32.ne', 'f64.ne', 'f32.lt', 'f64.lt', + 'f32.le', 'f64.le', 'f32.gt', 'f64.gt', 'f32.ge', 'f64.gt', + // conversion + 'i32.wrap/i64', 'i64.extend_s/i32', 'i64.extend_u/i32', + 'i32.trunc_s/f32', 'i32.trunc_s/f64', 'i64.trunc_s/f32', 'i64.trunc_s/f64', + 'i32.trunc_u/f32', 'i32.trunc_u/f64', 'i64.trunc_u/f32', 'i64.trunc_u/f64', + 'f32.demote/f64', 'f64.promote/f32', + 'f32.convert_s/i32', 'f32.convert_s/i64', 'f64.convert_s/i32', 'f64.convert_s/i64', + 'f32.convert_u/i32', 'f32.convert_u/i64', 'f64.convert_u/i32', 'f64.convert_u/i64', + 'i32.reinterpret/f32', 'i64.reinterpret/f64', 'f32.reinterpret/i32', 'f64.reinterpret/i64', + // load/store + 'i32.load', 'i64.load', 'f32.load', 'f64.load', + 'i32.store', 'i64.store', 'f32.store', 'f64.store', + 'i32.load8_s', 'i32.load16_s', 'i64.load8_s', 'i64.load16_s', 'i64.load32_s', + 'i32.load8_u', 'i32.load16_u', 'i64.load8_u', 'i64.load16_u', 'i64.load32_u', + 'i32.store8', 'i32.store16', 'i64.store8', 'i64.store16', 'i64.store32', + // additional memory + 'grow_memory', 'current_memory' +