WebAssemblyInstrInfo.td revision 341825
150120Swpaul// WebAssemblyInstrInfo.td-Describe the WebAssembly Instructions-*- tablegen -*- 250120Swpaul// 350120Swpaul// The LLVM Compiler Infrastructure 450120Swpaul// 550120Swpaul// This file is distributed under the University of Illinois Open Source 650120Swpaul// License. See LICENSE.TXT for details. 750120Swpaul// 850120Swpaul//===----------------------------------------------------------------------===// 950120Swpaul/// 1050120Swpaul/// \file 1150120Swpaul/// WebAssembly Instruction definitions. 1250120Swpaul/// 1350120Swpaul//===----------------------------------------------------------------------===// 1450120Swpaul 1550120Swpaul//===----------------------------------------------------------------------===// 1650120Swpaul// WebAssembly Instruction Predicate Definitions. 1750120Swpaul//===----------------------------------------------------------------------===// 1850120Swpaul 1950120Swpauldef HasAddr32 : Predicate<"!Subtarget->hasAddr64()">; 2050120Swpauldef HasAddr64 : Predicate<"Subtarget->hasAddr64()">; 2150120Swpauldef HasSIMD128 : Predicate<"Subtarget->hasSIMD128()">, 2250120Swpaul AssemblerPredicate<"FeatureSIMD128", "simd128">; 2350120Swpauldef HasAtomics : Predicate<"Subtarget->hasAtomics()">, 2450120Swpaul AssemblerPredicate<"FeatureAtomics", "atomics">; 2550120Swpauldef HasNontrappingFPToInt : 2650120Swpaul Predicate<"Subtarget->hasNontrappingFPToInt()">, 2750120Swpaul AssemblerPredicate<"FeatureNontrappingFPToInt", 2850120Swpaul "nontrapping-fptoint">; 2950120Swpauldef NotHasNontrappingFPToInt : 3050120Swpaul Predicate<"!Subtarget->hasNontrappingFPToInt()">, 3150120Swpaul AssemblerPredicate<"!FeatureNontrappingFPToInt", 3250120Swpaul "nontrapping-fptoint">; 3350120Swpauldef HasSignExt : 3450120Swpaul Predicate<"Subtarget->hasSignExt()">, 3550120Swpaul AssemblerPredicate<"FeatureSignExt", 3650120Swpaul "sign-ext">; 3750120Swpauldef NotHasSignExt : 3850120Swpaul Predicate<"!Subtarget->hasSignExt()">, 3950120Swpaul AssemblerPredicate<"!FeatureSignExt", 4050120Swpaul "sign-ext">; 4150120Swpaul 4250120Swpauldef HasExceptionHandling : 4350120Swpaul Predicate<"Subtarget->hasExceptionHandling()">, 4450120Swpaul AssemblerPredicate<"FeatureExceptionHandling", 4550120Swpaul "exception-handling">; 4650120Swpaul 4750120Swpauldef NotHasExceptionHandling : 4850120Swpaul Predicate<"!Subtarget->hasExceptionHandling()">, 4950120Swpaul AssemblerPredicate<"!FeatureExceptionHandling", 5050120Swpaul "exception-handling">; 5150120Swpaul 5250120Swpaul//===----------------------------------------------------------------------===// 5350120Swpaul// WebAssembly-specific DAG Node Types. 5450120Swpaul//===----------------------------------------------------------------------===// 5550120Swpaul 5650120Swpauldef SDT_WebAssemblyCallSeqStart : SDCallSeqStart<[SDTCisVT<0, iPTR>, 5750120Swpaul SDTCisVT<1, iPTR>]>; 5850120Swpauldef SDT_WebAssemblyCallSeqEnd : 5950120Swpaul SDCallSeqEnd<[SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>; 6050120Swpauldef SDT_WebAssemblyCall0 : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; 6150120Swpauldef SDT_WebAssemblyCall1 : SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>; 6250120Swpauldef SDT_WebAssemblyBrTable : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; 6350477Speterdef SDT_WebAssemblyArgument : SDTypeProfile<1, 1, [SDTCisVT<1, i32>]>; 6450120Swpauldef SDT_WebAssemblyReturn : SDTypeProfile<0, -1, []>; 6550120Swpauldef SDT_WebAssemblyWrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, 6650120Swpaul SDTCisPtrTy<0>]>; 6750120Swpaul 6850120Swpaul//===----------------------------------------------------------------------===// 6950120Swpaul// WebAssembly-specific DAG Nodes. 7050120Swpaul//===----------------------------------------------------------------------===// 7150120Swpaul 7250120Swpauldef WebAssemblycallseq_start : 7350120Swpaul SDNode<"ISD::CALLSEQ_START", SDT_WebAssemblyCallSeqStart, 7450120Swpaul [SDNPHasChain, SDNPOutGlue]>; 7550120Swpauldef WebAssemblycallseq_end : 7650120Swpaul SDNode<"ISD::CALLSEQ_END", SDT_WebAssemblyCallSeqEnd, 7750120Swpaul [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 7850120Swpauldef WebAssemblycall0 : SDNode<"WebAssemblyISD::CALL0", 7950120Swpaul SDT_WebAssemblyCall0, 8050120Swpaul [SDNPHasChain, SDNPVariadic]>; 8150120Swpauldef WebAssemblycall1 : SDNode<"WebAssemblyISD::CALL1", 8250120Swpaul SDT_WebAssemblyCall1, 8350120Swpaul [SDNPHasChain, SDNPVariadic]>; 8450120Swpauldef WebAssemblybr_table : SDNode<"WebAssemblyISD::BR_TABLE", 8550120Swpaul SDT_WebAssemblyBrTable, 8650120Swpaul [SDNPHasChain, SDNPVariadic]>; 8750120Swpauldef WebAssemblyargument : SDNode<"WebAssemblyISD::ARGUMENT", 8850120Swpaul SDT_WebAssemblyArgument>; 8950120Swpauldef WebAssemblyreturn : SDNode<"WebAssemblyISD::RETURN", 9050120Swpaul SDT_WebAssemblyReturn, [SDNPHasChain]>; 9150120Swpauldef WebAssemblywrapper : SDNode<"WebAssemblyISD::Wrapper", 9250120Swpaul SDT_WebAssemblyWrapper>; 9350120Swpaul 9450120Swpaul//===----------------------------------------------------------------------===// 9550120Swpaul// WebAssembly-specific Operands. 9650120Swpaul//===----------------------------------------------------------------------===// 9750120Swpaul 9850120Swpaullet OperandNamespace = "WebAssembly" in { 9950120Swpaul 10050120Swpaullet OperandType = "OPERAND_BASIC_BLOCK" in 10150120Swpauldef bb_op : Operand<OtherVT>; 10250120Swpaul 10350120Swpaullet OperandType = "OPERAND_LOCAL" in 10450120Swpauldef local_op : Operand<i32>; 10550120Swpaul 10650120Swpaullet OperandType = "OPERAND_GLOBAL" in 10750120Swpauldef global_op : Operand<i32>; 10850120Swpaul 10969925Swpaullet OperandType = "OPERAND_I32IMM" in 11050120Swpauldef i32imm_op : Operand<i32>; 11150120Swpaul 11250120Swpaullet OperandType = "OPERAND_I64IMM" in 11350120Swpauldef i64imm_op : Operand<i64>; 11450120Swpaul 11569925Swpaullet OperandType = "OPERAND_F32IMM" in 11669925Swpauldef f32imm_op : Operand<f32>; 11769925Swpaul 11869925Swpaullet OperandType = "OPERAND_F64IMM" in 11969925Swpauldef f64imm_op : Operand<f64>; 12069925Swpaul 12169925Swpaullet OperandType = "OPERAND_FUNCTION32" in 12269925Swpauldef function32_op : Operand<i32>; 12369925Swpaul 12469925Swpaullet OperandType = "OPERAND_OFFSET32" in 12550120Swpauldef offset32_op : Operand<i32>; 12650120Swpaul 12750120Swpaullet OperandType = "OPERAND_P2ALIGN" in { 12850120Swpauldef P2Align : Operand<i32> { 12950120Swpaul let PrintMethod = "printWebAssemblyP2AlignOperand"; 13050120Swpaul} 13150120Swpaul} // OperandType = "OPERAND_P2ALIGN" 13250120Swpaul 13350120Swpaullet OperandType = "OPERAND_SIGNATURE" in { 13450120Swpauldef Signature : Operand<i32> { 13550120Swpaul let PrintMethod = "printWebAssemblySignatureOperand"; 13650120Swpaul} 13750120Swpaul} // OperandType = "OPERAND_SIGNATURE" 13850120Swpaul 13950120Swpaullet OperandType = "OPERAND_TYPEINDEX" in 14050120Swpauldef TypeIndex : Operand<i32>; 14150120Swpaul 14250120Swpaul} // OperandNamespace = "WebAssembly" 14350120Swpaul 14450120Swpaul//===----------------------------------------------------------------------===// 14584140Sjlemon// WebAssembly Instruction Format Definitions. 14684140Sjlemon//===----------------------------------------------------------------------===// 14784140Sjlemon 14884140Sjlemoninclude "WebAssemblyInstrFormats.td" 14984140Sjlemon 15084140Sjlemon//===----------------------------------------------------------------------===// 15184140Sjlemon// Additional instructions. 15284140Sjlemon//===----------------------------------------------------------------------===// 15384140Sjlemon 15484140Sjlemonmulticlass ARGUMENT<WebAssemblyRegClass vt> { 15584140Sjlemon let hasSideEffects = 1, Uses = [ARGUMENTS], isCodeGenOnly = 1 in 15684140Sjlemon defm ARGUMENT_#vt : I<(outs vt:$res), (ins i32imm:$argno), 15784140Sjlemon (outs), (ins i32imm:$argno), 15884140Sjlemon [(set vt:$res, (WebAssemblyargument timm:$argno))]>; 15984140Sjlemon} 16084140Sjlemonmulticlass SIMD_ARGUMENT<ValueType vt> { 16184140Sjlemon let hasSideEffects = 1, Uses = [ARGUMENTS], isCodeGenOnly = 1 in 16284140Sjlemon defm ARGUMENT_#vt : SIMD_I<(outs V128:$res), (ins i32imm:$argno), 16384140Sjlemon (outs), (ins i32imm:$argno), 16484140Sjlemon [(set (vt V128:$res), 16584140Sjlemon (WebAssemblyargument timm:$argno))]>; 16684140Sjlemon} 16784140Sjlemondefm "": ARGUMENT<I32>; 16884140Sjlemondefm "": ARGUMENT<I64>; 16984140Sjlemondefm "": ARGUMENT<F32>; 17084140Sjlemondefm "": ARGUMENT<F64>; 17184140Sjlemondefm "": ARGUMENT<EXCEPT_REF>; 17284140Sjlemondefm "": SIMD_ARGUMENT<v16i8>; 17384140Sjlemondefm "": SIMD_ARGUMENT<v8i16>; 17484140Sjlemondefm "": SIMD_ARGUMENT<v4i32>; 17584140Sjlemondefm "": SIMD_ARGUMENT<v4f32>; 17684140Sjlemon 17784140Sjlemonlet Defs = [ARGUMENTS] in { 17884140Sjlemon 17984140Sjlemon// get_local and set_local are not generated by instruction selection; they 18084140Sjlemon// are implied by virtual register uses and defs. 18184140Sjlemonmulticlass LOCAL<WebAssemblyRegClass vt> { 18284140Sjlemonlet hasSideEffects = 0 in { 18384140Sjlemon // COPY is not an actual instruction in wasm, but since we allow get_local and 18484140Sjlemon // set_local to be implicit during most of codegen, we can have a COPY which 18584140Sjlemon // is actually a no-op because all the work is done in the implied get_local 18684140Sjlemon // and set_local. COPYs are eliminated (and replaced with 18784140Sjlemon // get_local/set_local) in the ExplicitLocals pass. 18884140Sjlemon let isAsCheapAsAMove = 1, isCodeGenOnly = 1 in 18984140Sjlemon defm COPY_#vt : I<(outs vt:$res), (ins vt:$src), (outs), (ins), [], 19084140Sjlemon "copy_local\t$res, $src", "copy_local">; 19184140Sjlemon 19284140Sjlemon // TEE is similar to COPY, but writes two copies of its result. Typically 19384140Sjlemon // this would be used to stackify one result and write the other result to a 19450120Swpaul // local. 19550120Swpaul let isAsCheapAsAMove = 1, isCodeGenOnly = 1 in 19650120Swpaul defm TEE_#vt : I<(outs vt:$res, vt:$also), (ins vt:$src), (outs), (ins), [], 19750120Swpaul "tee_local\t$res, $also, $src", "tee_local">; 19850120Swpaul 19950120Swpaul // This is the actual get_local instruction in wasm. These are made explicit 20050120Swpaul // by the ExplicitLocals pass. It has mayLoad because it reads from a wasm 20150120Swpaul // local, which is a side effect not otherwise modeled in LLVM. 20250120Swpaul let mayLoad = 1, isAsCheapAsAMove = 1 in 20350120Swpaul defm GET_LOCAL_#vt : I<(outs vt:$res), (ins local_op:$local), 20450120Swpaul (outs), (ins local_op:$local), [], 20550120Swpaul "get_local\t$res, $local", "get_local\t$local", 0x20>; 20650120Swpaul 20750120Swpaul // This is the actual set_local instruction in wasm. These are made explicit 20850120Swpaul // by the ExplicitLocals pass. It has mayStore because it writes to a wasm 20950120Swpaul // local, which is a side effect not otherwise modeled in LLVM. 21050120Swpaul let mayStore = 1, isAsCheapAsAMove = 1 in 21150120Swpaul defm SET_LOCAL_#vt : I<(outs), (ins local_op:$local, vt:$src), 21250120Swpaul (outs), (ins local_op:$local), [], 21350120Swpaul "set_local\t$local, $src", "set_local\t$local", 0x21>; 21450120Swpaul 21550120Swpaul // This is the actual tee_local instruction in wasm. TEEs are turned into 21650120Swpaul // TEE_LOCALs by the ExplicitLocals pass. It has mayStore for the same reason 21750120Swpaul // as SET_LOCAL. 21884140Sjlemon let mayStore = 1, isAsCheapAsAMove = 1 in 21984140Sjlemon defm TEE_LOCAL_#vt : I<(outs vt:$res), (ins local_op:$local, vt:$src), 22084140Sjlemon (outs), (ins local_op:$local), [], 22184140Sjlemon "tee_local\t$res, $local, $src", "tee_local\t$local", 22284140Sjlemon 0x22>; 22384140Sjlemon 22484140Sjlemon // Unused values must be dropped in some contexts. 22584140Sjlemon defm DROP_#vt : I<(outs), (ins vt:$src), (outs), (ins), [], 22684140Sjlemon "drop\t$src", "drop", 0x1a>; 22784140Sjlemon 22884140Sjlemon let mayLoad = 1 in 22984140Sjlemon defm GET_GLOBAL_#vt : I<(outs vt:$res), (ins global_op:$local), 23084140Sjlemon (outs), (ins global_op:$local), [], 23184140Sjlemon "get_global\t$res, $local", "get_global\t$local", 23284140Sjlemon 0x23>; 23384140Sjlemon 23484140Sjlemon let mayStore = 1 in 23550120Swpaul defm SET_GLOBAL_#vt : I<(outs), (ins global_op:$local, vt:$src), 23650120Swpaul (outs), (ins global_op:$local), [], 23750120Swpaul "set_global\t$local, $src", "set_global\t$local", 23850120Swpaul 0x24>; 23950120Swpaul 24050120Swpaul} // hasSideEffects = 0 24150120Swpaul} 24250120Swpauldefm "" : LOCAL<I32>; 24350120Swpauldefm "" : LOCAL<I64>; 24450120Swpauldefm "" : LOCAL<F32>; 24550120Swpauldefm "" : LOCAL<F64>; 24650120Swpauldefm "" : LOCAL<V128>, Requires<[HasSIMD128]>; 24750120Swpauldefm "" : LOCAL<EXCEPT_REF>, Requires<[HasExceptionHandling]>; 24850120Swpaul 24950120Swpaullet isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1 in { 25050120Swpauldefm CONST_I32 : I<(outs I32:$res), (ins i32imm_op:$imm), 25150120Swpaul (outs), (ins i32imm_op:$imm), 25250120Swpaul [(set I32:$res, imm:$imm)], 25350120Swpaul "i32.const\t$res, $imm", "i32.const\t$imm", 0x41>; 25450120Swpauldefm CONST_I64 : I<(outs I64:$res), (ins i64imm_op:$imm), 25550120Swpaul (outs), (ins i64imm_op:$imm), 25650120Swpaul [(set I64:$res, imm:$imm)], 25750120Swpaul "i64.const\t$res, $imm", "i64.const\t$imm", 0x42>; 25850120Swpauldefm CONST_F32 : I<(outs F32:$res), (ins f32imm_op:$imm), 25950120Swpaul (outs), (ins f32imm_op:$imm), 26050120Swpaul [(set F32:$res, fpimm:$imm)], 26150120Swpaul "f32.const\t$res, $imm", "f32.const\t$imm", 0x43>; 26250120Swpauldefm CONST_F64 : I<(outs F64:$res), (ins f64imm_op:$imm), 26350120Swpaul (outs), (ins f64imm_op:$imm), 26450120Swpaul [(set F64:$res, fpimm:$imm)], 26550120Swpaul "f64.const\t$res, $imm", "f64.const\t$imm", 0x44>; 26650120Swpaul} // isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1 26750120Swpaul 26850120Swpaul} // Defs = [ARGUMENTS] 26950120Swpaul 27050120Swpauldef : Pat<(i32 (WebAssemblywrapper tglobaladdr:$addr)), 27150120Swpaul (CONST_I32 tglobaladdr:$addr)>; 27250120Swpauldef : Pat<(i32 (WebAssemblywrapper texternalsym:$addr)), 27350120Swpaul (CONST_I32 texternalsym:$addr)>; 27450120Swpaul 27550120Swpaul//===----------------------------------------------------------------------===// 27650120Swpaul// Additional sets of instructions. 27750120Swpaul//===----------------------------------------------------------------------===// 27850120Swpaul 27950120Swpaulinclude "WebAssemblyInstrMemory.td" 28050120Swpaulinclude "WebAssemblyInstrCall.td" 28150120Swpaulinclude "WebAssemblyInstrControl.td" 28250120Swpaulinclude "WebAssemblyInstrInteger.td" 28350120Swpaulinclude "WebAssemblyInstrConv.td" 28450120Swpaulinclude "WebAssemblyInstrFloat.td" 28550120Swpaulinclude "WebAssemblyInstrAtomics.td" 28650120Swpaulinclude "WebAssemblyInstrSIMD.td" 28750120Swpaulinclude "WebAssemblyInstrExceptRef.td" 28850120Swpaul