WebAssemblyInstrInfo.td revision 344779
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/// 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 HasUnimplementedSIMD128 : 24 Predicate<"Subtarget->hasUnimplementedSIMD128()">, 25 AssemblerPredicate<"FeatureUnimplementedSIMD128", "unimplemented-simd128">; 26def HasAtomics : Predicate<"Subtarget->hasAtomics()">, 27 AssemblerPredicate<"FeatureAtomics", "atomics">; 28def HasNontrappingFPToInt : 29 Predicate<"Subtarget->hasNontrappingFPToInt()">, 30 AssemblerPredicate<"FeatureNontrappingFPToInt", 31 "nontrapping-fptoint">; 32def NotHasNontrappingFPToInt : 33 Predicate<"!Subtarget->hasNontrappingFPToInt()">, 34 AssemblerPredicate<"!FeatureNontrappingFPToInt", 35 "nontrapping-fptoint">; 36def HasSignExt : 37 Predicate<"Subtarget->hasSignExt()">, 38 AssemblerPredicate<"FeatureSignExt", 39 "sign-ext">; 40def NotHasSignExt : 41 Predicate<"!Subtarget->hasSignExt()">, 42 AssemblerPredicate<"!FeatureSignExt", 43 "sign-ext">; 44 45def HasExceptionHandling : 46 Predicate<"Subtarget->hasExceptionHandling()">, 47 AssemblerPredicate<"FeatureExceptionHandling", 48 "exception-handling">; 49 50def NotHasExceptionHandling : 51 Predicate<"!Subtarget->hasExceptionHandling()">, 52 AssemblerPredicate<"!FeatureExceptionHandling", 53 "exception-handling">; 54 55//===----------------------------------------------------------------------===// 56// WebAssembly-specific DAG Node Types. 57//===----------------------------------------------------------------------===// 58 59def SDT_WebAssemblyCallSeqStart : SDCallSeqStart<[SDTCisVT<0, iPTR>, 60 SDTCisVT<1, iPTR>]>; 61def SDT_WebAssemblyCallSeqEnd : 62 SDCallSeqEnd<[SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>; 63def SDT_WebAssemblyCall0 : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; 64def SDT_WebAssemblyCall1 : SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>; 65def SDT_WebAssemblyBrTable : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; 66def SDT_WebAssemblyArgument : SDTypeProfile<1, 1, [SDTCisVT<1, i32>]>; 67def SDT_WebAssemblyReturn : SDTypeProfile<0, -1, []>; 68def SDT_WebAssemblyWrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, 69 SDTCisPtrTy<0>]>; 70def SDT_WebAssemblyThrow : SDTypeProfile<0, 2, [SDTCisPtrTy<0>]>; 71 72//===----------------------------------------------------------------------===// 73// WebAssembly-specific DAG Nodes. 74//===----------------------------------------------------------------------===// 75 76def WebAssemblycallseq_start : 77 SDNode<"ISD::CALLSEQ_START", SDT_WebAssemblyCallSeqStart, 78 [SDNPHasChain, SDNPOutGlue]>; 79def WebAssemblycallseq_end : 80 SDNode<"ISD::CALLSEQ_END", SDT_WebAssemblyCallSeqEnd, 81 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 82def WebAssemblycall0 : SDNode<"WebAssemblyISD::CALL0", 83 SDT_WebAssemblyCall0, 84 [SDNPHasChain, SDNPVariadic]>; 85def WebAssemblycall1 : SDNode<"WebAssemblyISD::CALL1", 86 SDT_WebAssemblyCall1, 87 [SDNPHasChain, SDNPVariadic]>; 88def WebAssemblybr_table : SDNode<"WebAssemblyISD::BR_TABLE", 89 SDT_WebAssemblyBrTable, 90 [SDNPHasChain, SDNPVariadic]>; 91def WebAssemblyargument : SDNode<"WebAssemblyISD::ARGUMENT", 92 SDT_WebAssemblyArgument>; 93def WebAssemblyreturn : SDNode<"WebAssemblyISD::RETURN", 94 SDT_WebAssemblyReturn, [SDNPHasChain]>; 95def WebAssemblywrapper : SDNode<"WebAssemblyISD::Wrapper", 96 SDT_WebAssemblyWrapper>; 97def WebAssemblythrow : SDNode<"WebAssemblyISD::THROW", SDT_WebAssemblyThrow, 98 [SDNPHasChain]>; 99 100//===----------------------------------------------------------------------===// 101// WebAssembly-specific Operands. 102//===----------------------------------------------------------------------===// 103 104let OperandNamespace = "WebAssembly" in { 105 106let OperandType = "OPERAND_BASIC_BLOCK" in 107def bb_op : Operand<OtherVT>; 108 109let OperandType = "OPERAND_LOCAL" in 110def local_op : Operand<i32>; 111 112let OperandType = "OPERAND_GLOBAL" in 113def global_op : Operand<i32>; 114 115let OperandType = "OPERAND_I32IMM" in 116def i32imm_op : Operand<i32>; 117 118let OperandType = "OPERAND_I64IMM" in 119def i64imm_op : Operand<i64>; 120 121let OperandType = "OPERAND_F32IMM" in 122def f32imm_op : Operand<f32>; 123 124let OperandType = "OPERAND_F64IMM" in 125def f64imm_op : Operand<f64>; 126 127let OperandType = "OPERAND_VEC_I8IMM" in 128def vec_i8imm_op : Operand<i32>; 129 130let OperandType = "OPERAND_VEC_I16IMM" in 131def vec_i16imm_op : Operand<i32>; 132 133let OperandType = "OPERAND_VEC_I32IMM" in 134def vec_i32imm_op : Operand<i32>; 135 136let OperandType = "OPERAND_VEC_I64IMM" in 137def vec_i64imm_op : Operand<i64>; 138 139let OperandType = "OPERAND_FUNCTION32" in 140def function32_op : Operand<i32>; 141 142let OperandType = "OPERAND_OFFSET32" in 143def offset32_op : Operand<i32>; 144 145let OperandType = "OPERAND_P2ALIGN" in { 146def P2Align : Operand<i32> { 147 let PrintMethod = "printWebAssemblyP2AlignOperand"; 148} 149 150let OperandType = "OPERAND_EVENT" in 151def event_op : Operand<i32>; 152 153} // OperandType = "OPERAND_P2ALIGN" 154 155let OperandType = "OPERAND_SIGNATURE" in { 156def Signature : Operand<i32> { 157 let PrintMethod = "printWebAssemblySignatureOperand"; 158} 159} // OperandType = "OPERAND_SIGNATURE" 160 161let OperandType = "OPERAND_TYPEINDEX" in 162def TypeIndex : Operand<i32>; 163 164} // OperandNamespace = "WebAssembly" 165 166//===----------------------------------------------------------------------===// 167// WebAssembly Register to Stack instruction mapping 168//===----------------------------------------------------------------------===// 169 170class StackRel; 171def getStackOpcode : InstrMapping { 172 let FilterClass = "StackRel"; 173 let RowFields = ["BaseName"]; 174 let ColFields = ["StackBased"]; 175 let KeyCol = ["false"]; 176 let ValueCols = [["true"]]; 177} 178 179//===----------------------------------------------------------------------===// 180// WebAssembly Instruction Format Definitions. 181//===----------------------------------------------------------------------===// 182 183include "WebAssemblyInstrFormats.td" 184 185//===----------------------------------------------------------------------===// 186// Additional instructions. 187//===----------------------------------------------------------------------===// 188 189multiclass ARGUMENT<WebAssemblyRegClass reg, ValueType vt> { 190 let hasSideEffects = 1, isCodeGenOnly = 1, 191 Defs = []<Register>, Uses = [ARGUMENTS] in 192 defm ARGUMENT_#vt : 193 I<(outs reg:$res), (ins i32imm:$argno), (outs), (ins i32imm:$argno), 194 [(set (vt reg:$res), (WebAssemblyargument timm:$argno))]>; 195} 196defm "": ARGUMENT<I32, i32>; 197defm "": ARGUMENT<I64, i64>; 198defm "": ARGUMENT<F32, f32>; 199defm "": ARGUMENT<F64, f64>; 200defm "": ARGUMENT<EXCEPT_REF, ExceptRef>; 201 202// local.get and local.set are not generated by instruction selection; they 203// are implied by virtual register uses and defs. 204multiclass LOCAL<WebAssemblyRegClass vt> { 205let hasSideEffects = 0 in { 206 // COPY is not an actual instruction in wasm, but since we allow local.get and 207 // local.set to be implicit during most of codegen, we can have a COPY which 208 // is actually a no-op because all the work is done in the implied local.get 209 // and local.set. COPYs are eliminated (and replaced with 210 // local.get/local.set) in the ExplicitLocals pass. 211 let isAsCheapAsAMove = 1, isCodeGenOnly = 1 in 212 defm COPY_#vt : I<(outs vt:$res), (ins vt:$src), (outs), (ins), [], 213 "local.copy\t$res, $src", "local.copy">; 214 215 // TEE is similar to COPY, but writes two copies of its result. Typically 216 // this would be used to stackify one result and write the other result to a 217 // local. 218 let isAsCheapAsAMove = 1, isCodeGenOnly = 1 in 219 defm TEE_#vt : I<(outs vt:$res, vt:$also), (ins vt:$src), (outs), (ins), [], 220 "local.tee\t$res, $also, $src", "local.tee">; 221 222 // This is the actual local.get instruction in wasm. These are made explicit 223 // by the ExplicitLocals pass. It has mayLoad because it reads from a wasm 224 // local, which is a side effect not otherwise modeled in LLVM. 225 let mayLoad = 1, isAsCheapAsAMove = 1 in 226 defm LOCAL_GET_#vt : I<(outs vt:$res), (ins local_op:$local), 227 (outs), (ins local_op:$local), [], 228 "local.get\t$res, $local", "local.get\t$local", 0x20>; 229 230 // This is the actual local.set instruction in wasm. These are made explicit 231 // by the ExplicitLocals pass. It has mayStore because it writes to a wasm 232 // local, which is a side effect not otherwise modeled in LLVM. 233 let mayStore = 1, isAsCheapAsAMove = 1 in 234 defm LOCAL_SET_#vt : I<(outs), (ins local_op:$local, vt:$src), 235 (outs), (ins local_op:$local), [], 236 "local.set\t$local, $src", "local.set\t$local", 0x21>; 237 238 // This is the actual local.tee instruction in wasm. TEEs are turned into 239 // LOCAL_TEEs by the ExplicitLocals pass. It has mayStore for the same reason 240 // as LOCAL_SET. 241 let mayStore = 1, isAsCheapAsAMove = 1 in 242 defm LOCAL_TEE_#vt : I<(outs vt:$res), (ins local_op:$local, vt:$src), 243 (outs), (ins local_op:$local), [], 244 "local.tee\t$res, $local, $src", "local.tee\t$local", 245 0x22>; 246 247 // Unused values must be dropped in some contexts. 248 defm DROP_#vt : I<(outs), (ins vt:$src), (outs), (ins), [], 249 "drop\t$src", "drop", 0x1a>; 250 251 let mayLoad = 1 in 252 defm GLOBAL_GET_#vt : I<(outs vt:$res), (ins global_op:$local), 253 (outs), (ins global_op:$local), [], 254 "global.get\t$res, $local", "global.get\t$local", 255 0x23>; 256 257 let mayStore = 1 in 258 defm GLOBAL_SET_#vt : I<(outs), (ins global_op:$local, vt:$src), 259 (outs), (ins global_op:$local), [], 260 "global.set\t$local, $src", "global.set\t$local", 261 0x24>; 262 263} // hasSideEffects = 0 264} 265defm "" : LOCAL<I32>; 266defm "" : LOCAL<I64>; 267defm "" : LOCAL<F32>; 268defm "" : LOCAL<F64>; 269defm "" : LOCAL<V128>, Requires<[HasSIMD128]>; 270defm "" : LOCAL<EXCEPT_REF>, Requires<[HasExceptionHandling]>; 271 272let isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1 in { 273defm CONST_I32 : I<(outs I32:$res), (ins i32imm_op:$imm), 274 (outs), (ins i32imm_op:$imm), 275 [(set I32:$res, imm:$imm)], 276 "i32.const\t$res, $imm", "i32.const\t$imm", 0x41>; 277defm CONST_I64 : I<(outs I64:$res), (ins i64imm_op:$imm), 278 (outs), (ins i64imm_op:$imm), 279 [(set I64:$res, imm:$imm)], 280 "i64.const\t$res, $imm", "i64.const\t$imm", 0x42>; 281defm CONST_F32 : I<(outs F32:$res), (ins f32imm_op:$imm), 282 (outs), (ins f32imm_op:$imm), 283 [(set F32:$res, fpimm:$imm)], 284 "f32.const\t$res, $imm", "f32.const\t$imm", 0x43>; 285defm CONST_F64 : I<(outs F64:$res), (ins f64imm_op:$imm), 286 (outs), (ins f64imm_op:$imm), 287 [(set F64:$res, fpimm:$imm)], 288 "f64.const\t$res, $imm", "f64.const\t$imm", 0x44>; 289} // isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1 290 291def : Pat<(i32 (WebAssemblywrapper tglobaladdr:$addr)), 292 (CONST_I32 tglobaladdr:$addr)>; 293def : Pat<(i32 (WebAssemblywrapper texternalsym:$addr)), 294 (CONST_I32 texternalsym:$addr)>; 295def : Pat<(i32 (WebAssemblywrapper mcsym:$sym)), (CONST_I32 mcsym:$sym)>; 296def : Pat<(i64 (WebAssemblywrapper mcsym:$sym)), (CONST_I64 mcsym:$sym)>; 297 298//===----------------------------------------------------------------------===// 299// Additional sets of instructions. 300//===----------------------------------------------------------------------===// 301 302include "WebAssemblyInstrMemory.td" 303include "WebAssemblyInstrCall.td" 304include "WebAssemblyInstrControl.td" 305include "WebAssemblyInstrInteger.td" 306include "WebAssemblyInstrConv.td" 307include "WebAssemblyInstrFloat.td" 308include "WebAssemblyInstrAtomics.td" 309include "WebAssemblyInstrSIMD.td" 310include "WebAssemblyInstrExceptRef.td" 311