1// WebAssemblyInstrInfo.td-Describe the WebAssembly Instructions-*- tablegen -*- 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9/// 10/// \file 11/// \brief WebAssembly Instruction definitions. 12/// 13//===----------------------------------------------------------------------===// 14 15//===----------------------------------------------------------------------===// 16// WebAssembly Instruction Predicate Definitions. 17//===----------------------------------------------------------------------===// 18 19def HasAddr32 : Predicate<"!Subtarget->hasAddr64()">; 20def HasAddr64 : Predicate<"Subtarget->hasAddr64()">; 21def HasSIMD128 : Predicate<"Subtarget->hasSIMD128()">, 22 AssemblerPredicate<"FeatureSIMD128", "simd128">; 23def HasAtomics : Predicate<"Subtarget->hasAtomics()">, 24 AssemblerPredicate<"FeatureAtomics", "atomics">; 25def HasNontrappingFPToInt : 26 Predicate<"Subtarget->hasNontrappingFPToInt()">, 27 AssemblerPredicate<"FeatureNontrappingFPToInt", 28 "nontrapping-fptoint">; 29def NotHasNontrappingFPToInt : 30 Predicate<"!Subtarget->hasNontrappingFPToInt()">, 31 AssemblerPredicate<"!FeatureNontrappingFPToInt", 32 "nontrapping-fptoint">; 33def HasSignExt : 34 Predicate<"Subtarget->hasSignExt()">, 35 AssemblerPredicate<"FeatureSignExt", 36 "sign-ext">; 37def NotHasSignExt : 38 Predicate<"!Subtarget->hasSignExt()">, 39 AssemblerPredicate<"!FeatureSignExt", 40 "sign-ext">; 41 42//===----------------------------------------------------------------------===// 43// WebAssembly-specific DAG Node Types. 44//===----------------------------------------------------------------------===// 45 46def SDT_WebAssemblyCallSeqStart : SDCallSeqStart<[SDTCisVT<0, iPTR>, 47 SDTCisVT<1, iPTR>]>; 48def SDT_WebAssemblyCallSeqEnd : 49 SDCallSeqEnd<[SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>; 50def SDT_WebAssemblyCall0 : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; 51def SDT_WebAssemblyCall1 : SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>; 52def SDT_WebAssemblyBrTable : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; 53def SDT_WebAssemblyArgument : SDTypeProfile<1, 1, [SDTCisVT<1, i32>]>; 54def SDT_WebAssemblyReturn : SDTypeProfile<0, -1, []>; 55def SDT_WebAssemblyWrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, 56 SDTCisPtrTy<0>]>; 57 58//===----------------------------------------------------------------------===// 59// WebAssembly-specific DAG Nodes. 60//===----------------------------------------------------------------------===// 61 62def WebAssemblycallseq_start : 63 SDNode<"ISD::CALLSEQ_START", SDT_WebAssemblyCallSeqStart, 64 [SDNPHasChain, SDNPOutGlue]>; 65def WebAssemblycallseq_end : 66 SDNode<"ISD::CALLSEQ_END", SDT_WebAssemblyCallSeqEnd, 67 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 68def WebAssemblycall0 : SDNode<"WebAssemblyISD::CALL0", 69 SDT_WebAssemblyCall0, 70 [SDNPHasChain, SDNPVariadic]>; 71def WebAssemblycall1 : SDNode<"WebAssemblyISD::CALL1", 72 SDT_WebAssemblyCall1, 73 [SDNPHasChain, SDNPVariadic]>; 74def WebAssemblybr_table : SDNode<"WebAssemblyISD::BR_TABLE", 75 SDT_WebAssemblyBrTable, 76 [SDNPHasChain, SDNPVariadic]>; 77def WebAssemblyargument : SDNode<"WebAssemblyISD::ARGUMENT", 78 SDT_WebAssemblyArgument>; 79def WebAssemblyreturn : SDNode<"WebAssemblyISD::RETURN", 80 SDT_WebAssemblyReturn, [SDNPHasChain]>; 81def WebAssemblywrapper : SDNode<"WebAssemblyISD::Wrapper", 82 SDT_WebAssemblyWrapper>; 83 84//===----------------------------------------------------------------------===// 85// WebAssembly-specific Operands. 86//===----------------------------------------------------------------------===// 87 88let OperandNamespace = "WebAssembly" in { 89 90let OperandType = "OPERAND_BASIC_BLOCK" in 91def bb_op : Operand<OtherVT>; 92 93let OperandType = "OPERAND_LOCAL" in 94def local_op : Operand<i32>; 95 96let OperandType = "OPERAND_GLOBAL" in 97def global_op : Operand<i32>; 98 99let OperandType = "OPERAND_I32IMM" in 100def i32imm_op : Operand<i32>; 101 102let OperandType = "OPERAND_I64IMM" in 103def i64imm_op : Operand<i64>; 104 105let OperandType = "OPERAND_F32IMM" in 106def f32imm_op : Operand<f32>; 107 108let OperandType = "OPERAND_F64IMM" in 109def f64imm_op : Operand<f64>; 110 111let OperandType = "OPERAND_FUNCTION32" in 112def function32_op : Operand<i32>; 113 114let OperandType = "OPERAND_OFFSET32" in 115def offset32_op : Operand<i32>; 116 117let OperandType = "OPERAND_P2ALIGN" in { 118def P2Align : Operand<i32> { 119 let PrintMethod = "printWebAssemblyP2AlignOperand"; 120} 121} // OperandType = "OPERAND_P2ALIGN" 122 123let OperandType = "OPERAND_SIGNATURE" in { 124def Signature : Operand<i32> { 125 let PrintMethod = "printWebAssemblySignatureOperand"; 126} 127} // OperandType = "OPERAND_SIGNATURE" 128 129let OperandType = "OPERAND_TYPEINDEX" in 130def TypeIndex : Operand<i32>; 131 132} // OperandNamespace = "WebAssembly" 133 134//===----------------------------------------------------------------------===// 135// WebAssembly Instruction Format Definitions. 136//===----------------------------------------------------------------------===// 137 138include "WebAssemblyInstrFormats.td" 139 140//===----------------------------------------------------------------------===// 141// Additional instructions. 142//===----------------------------------------------------------------------===// 143 144multiclass ARGUMENT<WebAssemblyRegClass vt> { 145 let hasSideEffects = 1, Uses = [ARGUMENTS], isCodeGenOnly = 1 in 146 def ARGUMENT_#vt : I<(outs vt:$res), (ins i32imm:$argno), 147 [(set vt:$res, (WebAssemblyargument timm:$argno))]>; 148} 149multiclass SIMD_ARGUMENT<ValueType vt> { 150 let hasSideEffects = 1, Uses = [ARGUMENTS], isCodeGenOnly = 1 in 151 def ARGUMENT_#vt : SIMD_I<(outs V128:$res), (ins i32imm:$argno), 152 [(set (vt V128:$res), 153 (WebAssemblyargument timm:$argno))]>; 154} 155defm : ARGUMENT<I32>; 156defm : ARGUMENT<I64>; 157defm : ARGUMENT<F32>; 158defm : ARGUMENT<F64>; 159defm : SIMD_ARGUMENT<v16i8>; 160defm : SIMD_ARGUMENT<v8i16>; 161defm : SIMD_ARGUMENT<v4i32>; 162defm : SIMD_ARGUMENT<v4f32>; 163 164let Defs = [ARGUMENTS] in { 165 166// get_local and set_local are not generated by instruction selection; they 167// are implied by virtual register uses and defs. 168multiclass LOCAL<WebAssemblyRegClass vt> { 169let hasSideEffects = 0 in { 170 // COPY is not an actual instruction in wasm, but since we allow get_local and 171 // set_local to be implicit during most of codegen, we can have a COPY which 172 // is actually a no-op because all the work is done in the implied get_local 173 // and set_local. COPYs are eliminated (and replaced with 174 // get_local/set_local) in the ExplicitLocals pass. 175 let isAsCheapAsAMove = 1, isCodeGenOnly = 1 in 176 def COPY_#vt : I<(outs vt:$res), (ins vt:$src), [], "copy_local\t$res, $src">; 177 178 // TEE is similar to COPY, but writes two copies of its result. Typically 179 // this would be used to stackify one result and write the other result to a 180 // local. 181 let isAsCheapAsAMove = 1, isCodeGenOnly = 1 in 182 def TEE_#vt : I<(outs vt:$res, vt:$also), (ins vt:$src), [], 183 "tee_local\t$res, $also, $src">; 184 185 // This is the actual get_local instruction in wasm. These are made explicit 186 // by the ExplicitLocals pass. It has mayLoad because it reads from a wasm 187 // local, which is a side effect not otherwise modeled in LLVM. 188 let mayLoad = 1, isAsCheapAsAMove = 1 in 189 def GET_LOCAL_#vt : I<(outs vt:$res), (ins local_op:$local), [], 190 "get_local\t$res, $local", 0x20>; 191 192 // This is the actual set_local instruction in wasm. These are made explicit 193 // by the ExplicitLocals pass. It has mayStore because it writes to a wasm 194 // local, which is a side effect not otherwise modeled in LLVM. 195 let mayStore = 1, isAsCheapAsAMove = 1 in 196 def SET_LOCAL_#vt : I<(outs), (ins local_op:$local, vt:$src), [], 197 "set_local\t$local, $src", 0x21>; 198 199 // This is the actual tee_local instruction in wasm. TEEs are turned into 200 // TEE_LOCALs by the ExplicitLocals pass. It has mayStore for the same reason 201 // as SET_LOCAL. 202 let mayStore = 1, isAsCheapAsAMove = 1 in 203 def TEE_LOCAL_#vt : I<(outs vt:$res), (ins local_op:$local, vt:$src), [], 204 "tee_local\t$res, $local, $src", 0x22>; 205 206 // Unused values must be dropped in some contexts. 207 def DROP_#vt : I<(outs), (ins vt:$src), [], 208 "drop\t$src", 0x1a>; 209 210 let mayLoad = 1 in 211 def GET_GLOBAL_#vt : I<(outs vt:$res), (ins global_op:$local), [], 212 "get_global\t$res, $local", 0x23>; 213 214 let mayStore = 1 in 215 def SET_GLOBAL_#vt : I<(outs), (ins global_op:$local, vt:$src), [], 216 "set_global\t$local, $src", 0x24>; 217 218} // hasSideEffects = 0 219} 220defm : LOCAL<I32>; 221defm : LOCAL<I64>; 222defm : LOCAL<F32>; 223defm : LOCAL<F64>; 224defm : LOCAL<V128>, Requires<[HasSIMD128]>; 225 226let isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1 in { 227def CONST_I32 : I<(outs I32:$res), (ins i32imm_op:$imm), 228 [(set I32:$res, imm:$imm)], 229 "i32.const\t$res, $imm", 0x41>; 230def CONST_I64 : I<(outs I64:$res), (ins i64imm_op:$imm), 231 [(set I64:$res, imm:$imm)], 232 "i64.const\t$res, $imm", 0x42>; 233def CONST_F32 : I<(outs F32:$res), (ins f32imm_op:$imm), 234 [(set F32:$res, fpimm:$imm)], 235 "f32.const\t$res, $imm", 0x43>; 236def CONST_F64 : I<(outs F64:$res), (ins f64imm_op:$imm), 237 [(set F64:$res, fpimm:$imm)], 238 "f64.const\t$res, $imm", 0x44>; 239} // isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1 240 241} // Defs = [ARGUMENTS] 242 243def : Pat<(i32 (WebAssemblywrapper tglobaladdr:$addr)), 244 (CONST_I32 tglobaladdr:$addr)>; 245def : Pat<(i32 (WebAssemblywrapper texternalsym:$addr)), 246 (CONST_I32 texternalsym:$addr)>; 247 248//===----------------------------------------------------------------------===// 249// Additional sets of instructions. 250//===----------------------------------------------------------------------===// 251 252include "WebAssemblyInstrMemory.td" 253include "WebAssemblyInstrCall.td" 254include "WebAssemblyInstrControl.td" 255include "WebAssemblyInstrInteger.td" 256include "WebAssemblyInstrConv.td" 257include "WebAssemblyInstrFloat.td" 258include "WebAssemblyInstrAtomics.td" 259include "WebAssemblyInstrSIMD.td" 260