1286425Sdim// WebAssemblyInstrMemory.td-WebAssembly Memory codegen support -*- tablegen -*- 2286425Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6286425Sdim// 7286425Sdim//===----------------------------------------------------------------------===// 8286425Sdim/// 9286425Sdim/// \file 10341825Sdim/// WebAssembly Memory operand code-gen constructs. 11286425Sdim/// 12286425Sdim//===----------------------------------------------------------------------===// 13286425Sdim 14296417Sdim// TODO: 15296417Sdim// - HasAddr64 16296417Sdim// - WebAssemblyTargetLowering having to do with atomics 17296417Sdim// - Each has optional alignment. 18296417Sdim 19296417Sdim// WebAssembly has i8/i16/i32/i64/f32/f64 memory types, but doesn't have i8/i16 20296417Sdim// local types. These memory-only types instead zero- or sign-extend into local 21296417Sdim// types when loading, and truncate when storing. 22296417Sdim 23296417Sdim// WebAssembly constant offsets are performed as unsigned with infinite 24296417Sdim// precision, so we need to check for NoUnsignedWrap so that we don't fold an 25296417Sdim// offset for an add that needs wrapping. 26296417Sdimdef regPlusImm : PatFrag<(ops node:$addr, node:$off), 27296417Sdim (add node:$addr, node:$off), 28321369Sdim [{ return N->getFlags().hasNoUnsignedWrap(); }]>; 29296417Sdim 30309124Sdim// Treat an 'or' node as an 'add' if the or'ed bits are known to be zero. 31309124Sdimdef or_is_add : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{ 32309124Sdim if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1))) 33309124Sdim return CurDAG->MaskedValueIsZero(N->getOperand(0), CN->getAPIntValue()); 34309124Sdim 35344779Sdim KnownBits Known0 = CurDAG->computeKnownBits(N->getOperand(0), 0); 36344779Sdim KnownBits Known1 = CurDAG->computeKnownBits(N->getOperand(1), 0); 37321369Sdim return (~Known0.Zero & ~Known1.Zero) == 0; 38309124Sdim}]>; 39309124Sdim 40296417Sdim// We don't need a regPlusES because external symbols never have constant 41296417Sdim// offsets folded into them, so we can just use add. 42296417Sdim 43327952Sdim// Defines atomic and non-atomic loads, regular and extending. 44341825Sdimmulticlass WebAssemblyLoad<WebAssemblyRegClass rc, string Name, int Opcode> { 45353358Sdim let mayLoad = 1, UseNamedOperandTable = 1 in 46341825Sdim defm "": I<(outs rc:$dst), 47341825Sdim (ins P2Align:$p2align, offset32_op:$off, I32:$addr), 48341825Sdim (outs), (ins P2Align:$p2align, offset32_op:$off), 49341825Sdim [], !strconcat(Name, "\t$dst, ${off}(${addr})${p2align}"), 50344779Sdim !strconcat(Name, "\t${off}${p2align}"), Opcode>; 51341825Sdim} 52327952Sdim 53296417Sdim// Basic load. 54314564Sdim// FIXME: When we can break syntax compatibility, reorder the fields in the 55314564Sdim// asmstrings to match the binary encoding. 56341825Sdimdefm LOAD_I32 : WebAssemblyLoad<I32, "i32.load", 0x28>; 57341825Sdimdefm LOAD_I64 : WebAssemblyLoad<I64, "i64.load", 0x29>; 58341825Sdimdefm LOAD_F32 : WebAssemblyLoad<F32, "f32.load", 0x2a>; 59341825Sdimdefm LOAD_F64 : WebAssemblyLoad<F64, "f64.load", 0x2b>; 60296417Sdim 61296417Sdim// Select loads with no constant offset. 62341825Sdimclass LoadPatNoOffset<ValueType ty, PatFrag kind, NI inst> : 63341825Sdim Pat<(ty (kind I32:$addr)), (inst 0, 0, I32:$addr)>; 64296417Sdim 65327952Sdimdef : LoadPatNoOffset<i32, load, LOAD_I32>; 66327952Sdimdef : LoadPatNoOffset<i64, load, LOAD_I64>; 67327952Sdimdef : LoadPatNoOffset<f32, load, LOAD_F32>; 68327952Sdimdef : LoadPatNoOffset<f64, load, LOAD_F64>; 69327952Sdim 70327952Sdim 71296417Sdim// Select loads with a constant offset. 72296417Sdim 73327952Sdim// Pattern with address + immediate offset 74341825Sdimclass LoadPatImmOff<ValueType ty, PatFrag kind, PatFrag operand, NI inst> : 75341825Sdim Pat<(ty (kind (operand I32:$addr, imm:$off))), (inst 0, imm:$off, I32:$addr)>; 76327952Sdim 77327952Sdimdef : LoadPatImmOff<i32, load, regPlusImm, LOAD_I32>; 78327952Sdimdef : LoadPatImmOff<i64, load, regPlusImm, LOAD_I64>; 79327952Sdimdef : LoadPatImmOff<f32, load, regPlusImm, LOAD_F32>; 80327952Sdimdef : LoadPatImmOff<f64, load, regPlusImm, LOAD_F64>; 81327952Sdimdef : LoadPatImmOff<i32, load, or_is_add, LOAD_I32>; 82327952Sdimdef : LoadPatImmOff<i64, load, or_is_add, LOAD_I64>; 83327952Sdimdef : LoadPatImmOff<f32, load, or_is_add, LOAD_F32>; 84327952Sdimdef : LoadPatImmOff<f64, load, or_is_add, LOAD_F64>; 85327952Sdim 86296417Sdim// Select loads with just a constant offset. 87341825Sdimclass LoadPatOffsetOnly<ValueType ty, PatFrag kind, NI inst> : 88341825Sdim Pat<(ty (kind imm:$off)), (inst 0, imm:$off, (CONST_I32 0))>; 89296417Sdim 90327952Sdimdef : LoadPatOffsetOnly<i32, load, LOAD_I32>; 91327952Sdimdef : LoadPatOffsetOnly<i64, load, LOAD_I64>; 92327952Sdimdef : LoadPatOffsetOnly<f32, load, LOAD_F32>; 93327952Sdimdef : LoadPatOffsetOnly<f64, load, LOAD_F64>; 94327952Sdim 95341825Sdimclass LoadPatGlobalAddrOffOnly<ValueType ty, PatFrag kind, NI inst> : 96341825Sdim Pat<(ty (kind (WebAssemblywrapper tglobaladdr:$off))), 97353358Sdim (inst 0, tglobaladdr:$off, (CONST_I32 0))>, Requires<[IsNotPIC]>; 98327952Sdim 99327952Sdimdef : LoadPatGlobalAddrOffOnly<i32, load, LOAD_I32>; 100327952Sdimdef : LoadPatGlobalAddrOffOnly<i64, load, LOAD_I64>; 101327952Sdimdef : LoadPatGlobalAddrOffOnly<f32, load, LOAD_F32>; 102327952Sdimdef : LoadPatGlobalAddrOffOnly<f64, load, LOAD_F64>; 103327952Sdim 104296417Sdim// Extending load. 105341825Sdimdefm LOAD8_S_I32 : WebAssemblyLoad<I32, "i32.load8_s", 0x2c>; 106341825Sdimdefm LOAD8_U_I32 : WebAssemblyLoad<I32, "i32.load8_u", 0x2d>; 107341825Sdimdefm LOAD16_S_I32 : WebAssemblyLoad<I32, "i32.load16_s", 0x2e>; 108341825Sdimdefm LOAD16_U_I32 : WebAssemblyLoad<I32, "i32.load16_u", 0x2f>; 109341825Sdimdefm LOAD8_S_I64 : WebAssemblyLoad<I64, "i64.load8_s", 0x30>; 110341825Sdimdefm LOAD8_U_I64 : WebAssemblyLoad<I64, "i64.load8_u", 0x31>; 111341825Sdimdefm LOAD16_S_I64 : WebAssemblyLoad<I64, "i64.load16_s", 0x32>; 112341825Sdimdefm LOAD16_U_I64 : WebAssemblyLoad<I64, "i64.load16_u", 0x33>; 113341825Sdimdefm LOAD32_S_I64 : WebAssemblyLoad<I64, "i64.load32_s", 0x34>; 114341825Sdimdefm LOAD32_U_I64 : WebAssemblyLoad<I64, "i64.load32_u", 0x35>; 115296417Sdim 116296417Sdim// Select extending loads with no constant offset. 117327952Sdimdef : LoadPatNoOffset<i32, sextloadi8, LOAD8_S_I32>; 118327952Sdimdef : LoadPatNoOffset<i32, zextloadi8, LOAD8_U_I32>; 119327952Sdimdef : LoadPatNoOffset<i32, sextloadi16, LOAD16_S_I32>; 120327952Sdimdef : LoadPatNoOffset<i32, zextloadi16, LOAD16_U_I32>; 121327952Sdimdef : LoadPatNoOffset<i64, sextloadi8, LOAD8_S_I64>; 122327952Sdimdef : LoadPatNoOffset<i64, zextloadi8, LOAD8_U_I64>; 123327952Sdimdef : LoadPatNoOffset<i64, sextloadi16, LOAD16_S_I64>; 124327952Sdimdef : LoadPatNoOffset<i64, zextloadi16, LOAD16_U_I64>; 125327952Sdimdef : LoadPatNoOffset<i64, sextloadi32, LOAD32_S_I64>; 126327952Sdimdef : LoadPatNoOffset<i64, zextloadi32, LOAD32_U_I64>; 127296417Sdim 128296417Sdim// Select extending loads with a constant offset. 129327952Sdimdef : LoadPatImmOff<i32, sextloadi8, regPlusImm, LOAD8_S_I32>; 130327952Sdimdef : LoadPatImmOff<i32, zextloadi8, regPlusImm, LOAD8_U_I32>; 131327952Sdimdef : LoadPatImmOff<i32, sextloadi16, regPlusImm, LOAD16_S_I32>; 132327952Sdimdef : LoadPatImmOff<i32, zextloadi16, regPlusImm, LOAD16_U_I32>; 133327952Sdimdef : LoadPatImmOff<i64, sextloadi8, regPlusImm, LOAD8_S_I64>; 134327952Sdimdef : LoadPatImmOff<i64, zextloadi8, regPlusImm, LOAD8_U_I64>; 135327952Sdimdef : LoadPatImmOff<i64, sextloadi16, regPlusImm, LOAD16_S_I64>; 136327952Sdimdef : LoadPatImmOff<i64, zextloadi16, regPlusImm, LOAD16_U_I64>; 137327952Sdimdef : LoadPatImmOff<i64, sextloadi32, regPlusImm, LOAD32_S_I64>; 138327952Sdimdef : LoadPatImmOff<i64, zextloadi32, regPlusImm, LOAD32_U_I64>; 139296417Sdim 140327952Sdimdef : LoadPatImmOff<i32, sextloadi8, or_is_add, LOAD8_S_I32>; 141327952Sdimdef : LoadPatImmOff<i32, zextloadi8, or_is_add, LOAD8_U_I32>; 142327952Sdimdef : LoadPatImmOff<i32, sextloadi16, or_is_add, LOAD16_S_I32>; 143327952Sdimdef : LoadPatImmOff<i32, zextloadi16, or_is_add, LOAD16_U_I32>; 144327952Sdimdef : LoadPatImmOff<i64, sextloadi8, or_is_add, LOAD8_S_I64>; 145327952Sdimdef : LoadPatImmOff<i64, zextloadi8, or_is_add, LOAD8_U_I64>; 146327952Sdimdef : LoadPatImmOff<i64, sextloadi16, or_is_add, LOAD16_S_I64>; 147327952Sdimdef : LoadPatImmOff<i64, zextloadi16, or_is_add, LOAD16_U_I64>; 148327952Sdimdef : LoadPatImmOff<i64, sextloadi32, or_is_add, LOAD32_S_I64>; 149327952Sdimdef : LoadPatImmOff<i64, zextloadi32, or_is_add, LOAD32_U_I64>; 150327952Sdim 151296417Sdim// Select extending loads with just a constant offset. 152327952Sdimdef : LoadPatOffsetOnly<i32, sextloadi8, LOAD8_S_I32>; 153327952Sdimdef : LoadPatOffsetOnly<i32, zextloadi8, LOAD8_U_I32>; 154327952Sdimdef : LoadPatOffsetOnly<i32, sextloadi16, LOAD16_S_I32>; 155327952Sdimdef : LoadPatOffsetOnly<i32, zextloadi16, LOAD16_U_I32>; 156296417Sdim 157327952Sdimdef : LoadPatOffsetOnly<i64, sextloadi8, LOAD8_S_I64>; 158327952Sdimdef : LoadPatOffsetOnly<i64, zextloadi8, LOAD8_U_I64>; 159327952Sdimdef : LoadPatOffsetOnly<i64, sextloadi16, LOAD16_S_I64>; 160327952Sdimdef : LoadPatOffsetOnly<i64, zextloadi16, LOAD16_U_I64>; 161327952Sdimdef : LoadPatOffsetOnly<i64, sextloadi32, LOAD32_S_I64>; 162327952Sdimdef : LoadPatOffsetOnly<i64, zextloadi32, LOAD32_U_I64>; 163327952Sdim 164327952Sdimdef : LoadPatGlobalAddrOffOnly<i32, sextloadi8, LOAD8_S_I32>; 165327952Sdimdef : LoadPatGlobalAddrOffOnly<i32, zextloadi8, LOAD8_U_I32>; 166327952Sdimdef : LoadPatGlobalAddrOffOnly<i32, sextloadi16, LOAD16_S_I32>; 167327952Sdimdef : LoadPatGlobalAddrOffOnly<i32, zextloadi16, LOAD16_U_I32>; 168327952Sdimdef : LoadPatGlobalAddrOffOnly<i64, sextloadi8, LOAD8_S_I64>; 169327952Sdimdef : LoadPatGlobalAddrOffOnly<i64, zextloadi8, LOAD8_U_I64>; 170327952Sdimdef : LoadPatGlobalAddrOffOnly<i64, sextloadi16, LOAD16_S_I64>; 171327952Sdimdef : LoadPatGlobalAddrOffOnly<i64, zextloadi16, LOAD16_U_I64>; 172327952Sdimdef : LoadPatGlobalAddrOffOnly<i64, sextloadi32, LOAD32_S_I64>; 173327952Sdimdef : LoadPatGlobalAddrOffOnly<i64, zextloadi32, LOAD32_U_I64>; 174327952Sdim 175296417Sdim// Resolve "don't care" extending loads to zero-extending loads. This is 176296417Sdim// somewhat arbitrary, but zero-extending is conceptually simpler. 177296417Sdim 178296417Sdim// Select "don't care" extending loads with no constant offset. 179327952Sdimdef : LoadPatNoOffset<i32, extloadi8, LOAD8_U_I32>; 180327952Sdimdef : LoadPatNoOffset<i32, extloadi16, LOAD16_U_I32>; 181327952Sdimdef : LoadPatNoOffset<i64, extloadi8, LOAD8_U_I64>; 182327952Sdimdef : LoadPatNoOffset<i64, extloadi16, LOAD16_U_I64>; 183327952Sdimdef : LoadPatNoOffset<i64, extloadi32, LOAD32_U_I64>; 184296417Sdim 185296417Sdim// Select "don't care" extending loads with a constant offset. 186327952Sdimdef : LoadPatImmOff<i32, extloadi8, regPlusImm, LOAD8_U_I32>; 187327952Sdimdef : LoadPatImmOff<i32, extloadi16, regPlusImm, LOAD16_U_I32>; 188327952Sdimdef : LoadPatImmOff<i64, extloadi8, regPlusImm, LOAD8_U_I64>; 189327952Sdimdef : LoadPatImmOff<i64, extloadi16, regPlusImm, LOAD16_U_I64>; 190327952Sdimdef : LoadPatImmOff<i64, extloadi32, regPlusImm, LOAD32_U_I64>; 191327952Sdimdef : LoadPatImmOff<i32, extloadi8, or_is_add, LOAD8_U_I32>; 192327952Sdimdef : LoadPatImmOff<i32, extloadi16, or_is_add, LOAD16_U_I32>; 193327952Sdimdef : LoadPatImmOff<i64, extloadi8, or_is_add, LOAD8_U_I64>; 194327952Sdimdef : LoadPatImmOff<i64, extloadi16, or_is_add, LOAD16_U_I64>; 195327952Sdimdef : LoadPatImmOff<i64, extloadi32, or_is_add, LOAD32_U_I64>; 196296417Sdim 197296417Sdim// Select "don't care" extending loads with just a constant offset. 198327952Sdimdef : LoadPatOffsetOnly<i32, extloadi8, LOAD8_U_I32>; 199327952Sdimdef : LoadPatOffsetOnly<i32, extloadi16, LOAD16_U_I32>; 200327952Sdimdef : LoadPatOffsetOnly<i64, extloadi8, LOAD8_U_I64>; 201327952Sdimdef : LoadPatOffsetOnly<i64, extloadi16, LOAD16_U_I64>; 202327952Sdimdef : LoadPatOffsetOnly<i64, extloadi32, LOAD32_U_I64>; 203327952Sdimdef : LoadPatGlobalAddrOffOnly<i32, extloadi8, LOAD8_U_I32>; 204327952Sdimdef : LoadPatGlobalAddrOffOnly<i32, extloadi16, LOAD16_U_I32>; 205327952Sdimdef : LoadPatGlobalAddrOffOnly<i64, extloadi8, LOAD8_U_I64>; 206327952Sdimdef : LoadPatGlobalAddrOffOnly<i64, extloadi16, LOAD16_U_I64>; 207327952Sdimdef : LoadPatGlobalAddrOffOnly<i64, extloadi32, LOAD32_U_I64>; 208296417Sdim 209341825Sdim// Defines atomic and non-atomic stores, regular and truncating 210341825Sdimmulticlass WebAssemblyStore<WebAssemblyRegClass rc, string Name, int Opcode> { 211353358Sdim let mayStore = 1, UseNamedOperandTable = 1 in 212341825Sdim defm "" : I<(outs), 213341825Sdim (ins P2Align:$p2align, offset32_op:$off, I32:$addr, rc:$val), 214341825Sdim (outs), 215341825Sdim (ins P2Align:$p2align, offset32_op:$off), [], 216341825Sdim !strconcat(Name, "\t${off}(${addr})${p2align}, $val"), 217344779Sdim !strconcat(Name, "\t${off}${p2align}"), Opcode>; 218341825Sdim} 219296417Sdim// Basic store. 220296417Sdim// Note: WebAssembly inverts SelectionDAG's usual operand order. 221341825Sdimdefm STORE_I32 : WebAssemblyStore<I32, "i32.store", 0x36>; 222341825Sdimdefm STORE_I64 : WebAssemblyStore<I64, "i64.store", 0x37>; 223341825Sdimdefm STORE_F32 : WebAssemblyStore<F32, "f32.store", 0x38>; 224341825Sdimdefm STORE_F64 : WebAssemblyStore<F64, "f64.store", 0x39>; 225296417Sdim 226296417Sdim// Select stores with no constant offset. 227341825Sdimclass StorePatNoOffset<ValueType ty, PatFrag node, NI inst> : 228341825Sdim Pat<(node ty:$val, I32:$addr), (inst 0, 0, I32:$addr, ty:$val)>; 229296417Sdim 230341825Sdimdef : StorePatNoOffset<i32, store, STORE_I32>; 231341825Sdimdef : StorePatNoOffset<i64, store, STORE_I64>; 232341825Sdimdef : StorePatNoOffset<f32, store, STORE_F32>; 233341825Sdimdef : StorePatNoOffset<f64, store, STORE_F64>; 234341825Sdim 235296417Sdim// Select stores with a constant offset. 236341825Sdimclass StorePatImmOff<ValueType ty, PatFrag kind, PatFrag operand, NI inst> : 237341825Sdim Pat<(kind ty:$val, (operand I32:$addr, imm:$off)), 238341825Sdim (inst 0, imm:$off, I32:$addr, ty:$val)>; 239296417Sdim 240341825Sdimdef : StorePatImmOff<i32, store, regPlusImm, STORE_I32>; 241341825Sdimdef : StorePatImmOff<i64, store, regPlusImm, STORE_I64>; 242341825Sdimdef : StorePatImmOff<f32, store, regPlusImm, STORE_F32>; 243341825Sdimdef : StorePatImmOff<f64, store, regPlusImm, STORE_F64>; 244341825Sdimdef : StorePatImmOff<i32, store, or_is_add, STORE_I32>; 245341825Sdimdef : StorePatImmOff<i64, store, or_is_add, STORE_I64>; 246341825Sdimdef : StorePatImmOff<f32, store, or_is_add, STORE_F32>; 247341825Sdimdef : StorePatImmOff<f64, store, or_is_add, STORE_F64>; 248341825Sdim 249296417Sdim// Select stores with just a constant offset. 250341825Sdimclass StorePatOffsetOnly<ValueType ty, PatFrag kind, NI inst> : 251341825Sdim Pat<(kind ty:$val, imm:$off), (inst 0, imm:$off, (CONST_I32 0), ty:$val)>; 252341825Sdimdef : StorePatOffsetOnly<i32, store, STORE_I32>; 253341825Sdimdef : StorePatOffsetOnly<i64, store, STORE_I64>; 254341825Sdimdef : StorePatOffsetOnly<f32, store, STORE_F32>; 255341825Sdimdef : StorePatOffsetOnly<f64, store, STORE_F64>; 256296417Sdim 257341825Sdimclass StorePatGlobalAddrOffOnly<ValueType ty, PatFrag kind, NI inst> : 258341825Sdim Pat<(kind ty:$val, (WebAssemblywrapper tglobaladdr:$off)), 259353358Sdim (inst 0, tglobaladdr:$off, (CONST_I32 0), ty:$val)>, Requires<[IsNotPIC]>; 260341825Sdimdef : StorePatGlobalAddrOffOnly<i32, store, STORE_I32>; 261341825Sdimdef : StorePatGlobalAddrOffOnly<i64, store, STORE_I64>; 262341825Sdimdef : StorePatGlobalAddrOffOnly<f32, store, STORE_F32>; 263341825Sdimdef : StorePatGlobalAddrOffOnly<f64, store, STORE_F64>; 264341825Sdim 265296417Sdim// Truncating store. 266341825Sdimdefm STORE8_I32 : WebAssemblyStore<I32, "i32.store8", 0x3a>; 267341825Sdimdefm STORE16_I32 : WebAssemblyStore<I32, "i32.store16", 0x3b>; 268341825Sdimdefm STORE8_I64 : WebAssemblyStore<I64, "i64.store8", 0x3c>; 269341825Sdimdefm STORE16_I64 : WebAssemblyStore<I64, "i64.store16", 0x3d>; 270341825Sdimdefm STORE32_I64 : WebAssemblyStore<I64, "i64.store32", 0x3e>; 271296417Sdim 272296417Sdim// Select truncating stores with no constant offset. 273341825Sdimdef : StorePatNoOffset<i32, truncstorei8, STORE8_I32>; 274341825Sdimdef : StorePatNoOffset<i32, truncstorei16, STORE16_I32>; 275341825Sdimdef : StorePatNoOffset<i64, truncstorei8, STORE8_I64>; 276341825Sdimdef : StorePatNoOffset<i64, truncstorei16, STORE16_I64>; 277341825Sdimdef : StorePatNoOffset<i64, truncstorei32, STORE32_I64>; 278296417Sdim 279296417Sdim// Select truncating stores with a constant offset. 280341825Sdimdef : StorePatImmOff<i32, truncstorei8, regPlusImm, STORE8_I32>; 281341825Sdimdef : StorePatImmOff<i32, truncstorei16, regPlusImm, STORE16_I32>; 282341825Sdimdef : StorePatImmOff<i64, truncstorei8, regPlusImm, STORE8_I64>; 283341825Sdimdef : StorePatImmOff<i64, truncstorei16, regPlusImm, STORE16_I64>; 284341825Sdimdef : StorePatImmOff<i64, truncstorei32, regPlusImm, STORE32_I64>; 285341825Sdimdef : StorePatImmOff<i32, truncstorei8, or_is_add, STORE8_I32>; 286341825Sdimdef : StorePatImmOff<i32, truncstorei16, or_is_add, STORE16_I32>; 287341825Sdimdef : StorePatImmOff<i64, truncstorei8, or_is_add, STORE8_I64>; 288341825Sdimdef : StorePatImmOff<i64, truncstorei16, or_is_add, STORE16_I64>; 289341825Sdimdef : StorePatImmOff<i64, truncstorei32, or_is_add, STORE32_I64>; 290296417Sdim 291296417Sdim// Select truncating stores with just a constant offset. 292341825Sdimdef : StorePatOffsetOnly<i32, truncstorei8, STORE8_I32>; 293341825Sdimdef : StorePatOffsetOnly<i32, truncstorei16, STORE16_I32>; 294341825Sdimdef : StorePatOffsetOnly<i64, truncstorei8, STORE8_I64>; 295341825Sdimdef : StorePatOffsetOnly<i64, truncstorei16, STORE16_I64>; 296341825Sdimdef : StorePatOffsetOnly<i64, truncstorei32, STORE32_I64>; 297341825Sdimdef : StorePatGlobalAddrOffOnly<i32, truncstorei8, STORE8_I32>; 298341825Sdimdef : StorePatGlobalAddrOffOnly<i32, truncstorei16, STORE16_I32>; 299341825Sdimdef : StorePatGlobalAddrOffOnly<i64, truncstorei8, STORE8_I64>; 300341825Sdimdef : StorePatGlobalAddrOffOnly<i64, truncstorei16, STORE16_I64>; 301341825Sdimdef : StorePatGlobalAddrOffOnly<i64, truncstorei32, STORE32_I64>; 302296417Sdim 303309124Sdim// Current memory size. 304341825Sdimdefm MEMORY_SIZE_I32 : I<(outs I32:$dst), (ins i32imm:$flags), 305341825Sdim (outs), (ins i32imm:$flags), 306341825Sdim [(set I32:$dst, 307341825Sdim (int_wasm_memory_size (i32 imm:$flags)))], 308341825Sdim "memory.size\t$dst, $flags", "memory.size\t$flags", 309341825Sdim 0x3f>, 310341825Sdim Requires<[HasAddr32]>; 311296417Sdim 312296417Sdim// Grow memory. 313341825Sdimdefm MEMORY_GROW_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta), 314344779Sdim (outs), (ins i32imm:$flags), 315341825Sdim [(set I32:$dst, 316341825Sdim (int_wasm_memory_grow (i32 imm:$flags), 317341825Sdim I32:$delta))], 318341825Sdim "memory.grow\t$dst, $flags, $delta", 319344779Sdim "memory.grow\t$flags", 0x40>, 320341825Sdim Requires<[HasAddr32]>; 321