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