1// WebAssemblyInstrMemory.td-WebAssembly Memory codegen support -*- 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 Memory operand code-gen constructs. 12/// 13//===----------------------------------------------------------------------===// 14 15// TODO: 16// - HasAddr64 17// - WebAssemblyTargetLowering having to do with atomics 18// - Each has optional alignment. 19 20// WebAssembly has i8/i16/i32/i64/f32/f64 memory types, but doesn't have i8/i16 21// local types. These memory-only types instead zero- or sign-extend into local 22// types when loading, and truncate when storing. 23 24// WebAssembly constant offsets are performed as unsigned with infinite 25// precision, so we need to check for NoUnsignedWrap so that we don't fold an 26// offset for an add that needs wrapping. 27def regPlusImm : PatFrag<(ops node:$addr, node:$off), 28 (add node:$addr, node:$off), 29 [{ return N->getFlags()->hasNoUnsignedWrap(); }]>; 30 31// Treat an 'or' node as an 'add' if the or'ed bits are known to be zero. 32def or_is_add : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{ 33 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1))) 34 return CurDAG->MaskedValueIsZero(N->getOperand(0), CN->getAPIntValue()); 35 36 APInt KnownZero0, KnownOne0; 37 CurDAG->computeKnownBits(N->getOperand(0), KnownZero0, KnownOne0, 0); 38 APInt KnownZero1, KnownOne1; 39 CurDAG->computeKnownBits(N->getOperand(1), KnownZero1, KnownOne1, 0); 40 return (~KnownZero0 & ~KnownZero1) == 0; 41}]>; 42 43// GlobalAddresses are conceptually unsigned values, so we can also fold them 44// into immediate values as long as the add is 'nuw'. 45// TODO: We'd like to also match GA offsets but there are cases where the 46// register can have a negative value. Find out what more we can do. 47def regPlusGA : PatFrag<(ops node:$addr, node:$off), 48 (add node:$addr, node:$off), 49 [{ 50 return N->getFlags()->hasNoUnsignedWrap(); 51}]>; 52 53// We don't need a regPlusES because external symbols never have constant 54// offsets folded into them, so we can just use add. 55 56let Defs = [ARGUMENTS] in { 57 58// Basic load. 59def LOAD_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr, 60 P2Align:$p2align), [], 61 "i32.load\t$dst, ${off}(${addr})${p2align}", 0x2a>; 62def LOAD_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr, 63 P2Align:$p2align), [], 64 "i64.load\t$dst, ${off}(${addr})${p2align}", 0x2b>; 65def LOAD_F32 : I<(outs F32:$dst), (ins i32imm:$off, I32:$addr, 66 P2Align:$p2align), [], 67 "f32.load\t$dst, ${off}(${addr})${p2align}", 0x2c>; 68def LOAD_F64 : I<(outs F64:$dst), (ins i32imm:$off, I32:$addr, 69 P2Align:$p2align), [], 70 "f64.load\t$dst, ${off}(${addr})${p2align}", 0x2d>; 71 72} // Defs = [ARGUMENTS] 73 74// Select loads with no constant offset. 75def : Pat<(i32 (load I32:$addr)), (LOAD_I32 0, $addr, 0)>; 76def : Pat<(i64 (load I32:$addr)), (LOAD_I64 0, $addr, 0)>; 77def : Pat<(f32 (load I32:$addr)), (LOAD_F32 0, $addr, 0)>; 78def : Pat<(f64 (load I32:$addr)), (LOAD_F64 0, $addr, 0)>; 79 80// Select loads with a constant offset. 81def : Pat<(i32 (load (regPlusImm I32:$addr, imm:$off))), 82 (LOAD_I32 imm:$off, $addr, 0)>; 83def : Pat<(i64 (load (regPlusImm I32:$addr, imm:$off))), 84 (LOAD_I64 imm:$off, $addr, 0)>; 85def : Pat<(f32 (load (regPlusImm I32:$addr, imm:$off))), 86 (LOAD_F32 imm:$off, $addr, 0)>; 87def : Pat<(f64 (load (regPlusImm I32:$addr, imm:$off))), 88 (LOAD_F64 imm:$off, $addr, 0)>; 89def : Pat<(i32 (load (or_is_add I32:$addr, imm:$off))), 90 (LOAD_I32 imm:$off, $addr, 0)>; 91def : Pat<(i64 (load (or_is_add I32:$addr, imm:$off))), 92 (LOAD_I64 imm:$off, $addr, 0)>; 93def : Pat<(f32 (load (or_is_add I32:$addr, imm:$off))), 94 (LOAD_F32 imm:$off, $addr, 0)>; 95def : Pat<(f64 (load (or_is_add I32:$addr, imm:$off))), 96 (LOAD_F64 imm:$off, $addr, 0)>; 97def : Pat<(i32 (load (regPlusGA I32:$addr, 98 (WebAssemblywrapper tglobaladdr:$off)))), 99 (LOAD_I32 tglobaladdr:$off, $addr, 0)>; 100def : Pat<(i64 (load (regPlusGA I32:$addr, 101 (WebAssemblywrapper tglobaladdr:$off)))), 102 (LOAD_I64 tglobaladdr:$off, $addr, 0)>; 103def : Pat<(f32 (load (regPlusGA I32:$addr, 104 (WebAssemblywrapper tglobaladdr:$off)))), 105 (LOAD_F32 tglobaladdr:$off, $addr, 0)>; 106def : Pat<(f64 (load (regPlusGA I32:$addr, 107 (WebAssemblywrapper tglobaladdr:$off)))), 108 (LOAD_F64 tglobaladdr:$off, $addr, 0)>; 109def : Pat<(i32 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))), 110 (LOAD_I32 texternalsym:$off, $addr, 0)>; 111def : Pat<(i64 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))), 112 (LOAD_I64 texternalsym:$off, $addr, 0)>; 113def : Pat<(f32 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))), 114 (LOAD_F32 texternalsym:$off, $addr, 0)>; 115def : Pat<(f64 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))), 116 (LOAD_F64 texternalsym:$off, $addr, 0)>; 117 118// Select loads with just a constant offset. 119def : Pat<(i32 (load imm:$off)), (LOAD_I32 imm:$off, (CONST_I32 0), 0)>; 120def : Pat<(i64 (load imm:$off)), (LOAD_I64 imm:$off, (CONST_I32 0), 0)>; 121def : Pat<(f32 (load imm:$off)), (LOAD_F32 imm:$off, (CONST_I32 0), 0)>; 122def : Pat<(f64 (load imm:$off)), (LOAD_F64 imm:$off, (CONST_I32 0), 0)>; 123def : Pat<(i32 (load (WebAssemblywrapper tglobaladdr:$off))), 124 (LOAD_I32 tglobaladdr:$off, (CONST_I32 0), 0)>; 125def : Pat<(i64 (load (WebAssemblywrapper tglobaladdr:$off))), 126 (LOAD_I64 tglobaladdr:$off, (CONST_I32 0), 0)>; 127def : Pat<(f32 (load (WebAssemblywrapper tglobaladdr:$off))), 128 (LOAD_F32 tglobaladdr:$off, (CONST_I32 0), 0)>; 129def : Pat<(f64 (load (WebAssemblywrapper tglobaladdr:$off))), 130 (LOAD_F64 tglobaladdr:$off, (CONST_I32 0), 0)>; 131def : Pat<(i32 (load (WebAssemblywrapper texternalsym:$off))), 132 (LOAD_I32 texternalsym:$off, (CONST_I32 0), 0)>; 133def : Pat<(i64 (load (WebAssemblywrapper texternalsym:$off))), 134 (LOAD_I64 texternalsym:$off, (CONST_I32 0), 0)>; 135def : Pat<(f32 (load (WebAssemblywrapper texternalsym:$off))), 136 (LOAD_F32 texternalsym:$off, (CONST_I32 0), 0)>; 137def : Pat<(f64 (load (WebAssemblywrapper texternalsym:$off))), 138 (LOAD_F64 texternalsym:$off, (CONST_I32 0), 0)>; 139 140let Defs = [ARGUMENTS] in { 141 142// Extending load. 143def LOAD8_S_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr, 144 P2Align:$p2align), [], 145 "i32.load8_s\t$dst, ${off}(${addr})${p2align}", 0x20>; 146def LOAD8_U_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr, 147 P2Align:$p2align), [], 148 "i32.load8_u\t$dst, ${off}(${addr})${p2align}", 0x21>; 149def LOAD16_S_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr, 150 P2Align:$p2align), [], 151 "i32.load16_s\t$dst, ${off}(${addr})${p2align}", 0x22>; 152def LOAD16_U_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr, 153 P2Align:$p2align), [], 154 "i32.load16_u\t$dst, ${off}(${addr})${p2align}", 0x23>; 155def LOAD8_S_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr, 156 P2Align:$p2align), [], 157 "i64.load8_s\t$dst, ${off}(${addr})${p2align}", 0x24>; 158def LOAD8_U_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr, 159 P2Align:$p2align), [], 160 "i64.load8_u\t$dst, ${off}(${addr})${p2align}", 0x25>; 161def LOAD16_S_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr, 162 P2Align:$p2align), [], 163 "i64.load16_s\t$dst, ${off}(${addr})${p2align}", 0x26>; 164def LOAD16_U_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr, 165 P2Align:$p2align), [], 166 "i64.load16_u\t$dst, ${off}(${addr})${p2align}", 0x27>; 167def LOAD32_S_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr, 168 P2Align:$p2align), [], 169 "i64.load32_s\t$dst, ${off}(${addr})${p2align}", 0x28>; 170def LOAD32_U_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr, 171 P2Align:$p2align), [], 172 "i64.load32_u\t$dst, ${off}(${addr})${p2align}", 0x29>; 173 174} // Defs = [ARGUMENTS] 175 176// Select extending loads with no constant offset. 177def : Pat<(i32 (sextloadi8 I32:$addr)), (LOAD8_S_I32 0, $addr, 0)>; 178def : Pat<(i32 (zextloadi8 I32:$addr)), (LOAD8_U_I32 0, $addr, 0)>; 179def : Pat<(i32 (sextloadi16 I32:$addr)), (LOAD16_S_I32 0, $addr, 0)>; 180def : Pat<(i32 (zextloadi16 I32:$addr)), (LOAD16_U_I32 0, $addr, 0)>; 181def : Pat<(i64 (sextloadi8 I32:$addr)), (LOAD8_S_I64 0, $addr, 0)>; 182def : Pat<(i64 (zextloadi8 I32:$addr)), (LOAD8_U_I64 0, $addr, 0)>; 183def : Pat<(i64 (sextloadi16 I32:$addr)), (LOAD16_S_I64 0, $addr, 0)>; 184def : Pat<(i64 (zextloadi16 I32:$addr)), (LOAD16_U_I64 0, $addr, 0)>; 185def : Pat<(i64 (sextloadi32 I32:$addr)), (LOAD32_S_I64 0, $addr, 0)>; 186def : Pat<(i64 (zextloadi32 I32:$addr)), (LOAD32_U_I64 0, $addr, 0)>; 187 188// Select extending loads with a constant offset. 189def : Pat<(i32 (sextloadi8 (regPlusImm I32:$addr, imm:$off))), 190 (LOAD8_S_I32 imm:$off, $addr, 0)>; 191def : Pat<(i32 (zextloadi8 (regPlusImm I32:$addr, imm:$off))), 192 (LOAD8_U_I32 imm:$off, $addr, 0)>; 193def : Pat<(i32 (sextloadi16 (regPlusImm I32:$addr, imm:$off))), 194 (LOAD16_S_I32 imm:$off, $addr, 0)>; 195def : Pat<(i32 (zextloadi16 (regPlusImm I32:$addr, imm:$off))), 196 (LOAD16_U_I32 imm:$off, $addr, 0)>; 197def : Pat<(i64 (sextloadi8 (regPlusImm I32:$addr, imm:$off))), 198 (LOAD8_S_I64 imm:$off, $addr, 0)>; 199def : Pat<(i64 (zextloadi8 (regPlusImm I32:$addr, imm:$off))), 200 (LOAD8_U_I64 imm:$off, $addr, 0)>; 201def : Pat<(i64 (sextloadi16 (regPlusImm I32:$addr, imm:$off))), 202 (LOAD16_S_I64 imm:$off, $addr, 0)>; 203def : Pat<(i64 (zextloadi16 (regPlusImm I32:$addr, imm:$off))), 204 (LOAD16_U_I64 imm:$off, $addr, 0)>; 205def : Pat<(i64 (sextloadi32 (regPlusImm I32:$addr, imm:$off))), 206 (LOAD32_S_I64 imm:$off, $addr, 0)>; 207def : Pat<(i64 (zextloadi32 (regPlusImm I32:$addr, imm:$off))), 208 (LOAD32_U_I64 imm:$off, $addr, 0)>; 209def : Pat<(i32 (sextloadi8 (or_is_add I32:$addr, imm:$off))), 210 (LOAD8_S_I32 imm:$off, $addr, 0)>; 211def : Pat<(i32 (zextloadi8 (or_is_add I32:$addr, imm:$off))), 212 (LOAD8_U_I32 imm:$off, $addr, 0)>; 213def : Pat<(i32 (sextloadi16 (or_is_add I32:$addr, imm:$off))), 214 (LOAD16_S_I32 imm:$off, $addr, 0)>; 215def : Pat<(i32 (zextloadi16 (or_is_add I32:$addr, imm:$off))), 216 (LOAD16_U_I32 imm:$off, $addr, 0)>; 217def : Pat<(i64 (sextloadi8 (or_is_add I32:$addr, imm:$off))), 218 (LOAD8_S_I64 imm:$off, $addr, 0)>; 219def : Pat<(i64 (zextloadi8 (or_is_add I32:$addr, imm:$off))), 220 (LOAD8_U_I64 imm:$off, $addr, 0)>; 221def : Pat<(i64 (sextloadi16 (or_is_add I32:$addr, imm:$off))), 222 (LOAD16_S_I64 imm:$off, $addr, 0)>; 223def : Pat<(i64 (zextloadi16 (or_is_add I32:$addr, imm:$off))), 224 (LOAD16_U_I64 imm:$off, $addr, 0)>; 225def : Pat<(i64 (sextloadi32 (or_is_add I32:$addr, imm:$off))), 226 (LOAD32_S_I64 imm:$off, $addr, 0)>; 227def : Pat<(i64 (zextloadi32 (or_is_add I32:$addr, imm:$off))), 228 (LOAD32_U_I64 imm:$off, $addr, 0)>; 229def : Pat<(i32 (sextloadi8 (regPlusGA I32:$addr, 230 (WebAssemblywrapper tglobaladdr:$off)))), 231 (LOAD8_S_I32 tglobaladdr:$off, $addr, 0)>; 232def : Pat<(i32 (zextloadi8 (regPlusGA I32:$addr, 233 (WebAssemblywrapper tglobaladdr:$off)))), 234 (LOAD8_U_I32 tglobaladdr:$off, $addr, 0)>; 235def : Pat<(i32 (sextloadi16 (regPlusGA I32:$addr, 236 (WebAssemblywrapper tglobaladdr:$off)))), 237 (LOAD16_S_I32 tglobaladdr:$off, $addr, 0)>; 238def : Pat<(i32 (zextloadi16 (regPlusGA I32:$addr, 239 (WebAssemblywrapper tglobaladdr:$off)))), 240 (LOAD16_U_I32 tglobaladdr:$off, $addr, 0)>; 241def : Pat<(i64 (sextloadi8 (regPlusGA I32:$addr, 242 (WebAssemblywrapper tglobaladdr:$off)))), 243 (LOAD8_S_I64 tglobaladdr:$off, $addr, 0)>; 244def : Pat<(i64 (zextloadi8 (regPlusGA I32:$addr, 245 (WebAssemblywrapper tglobaladdr:$off)))), 246 (LOAD8_U_I64 tglobaladdr:$off, $addr, 0)>; 247def : Pat<(i64 (sextloadi16 (regPlusGA I32:$addr, 248 (WebAssemblywrapper tglobaladdr:$off)))), 249 (LOAD16_S_I64 tglobaladdr:$off, $addr, 0)>; 250def : Pat<(i64 (zextloadi16 (regPlusGA I32:$addr, 251 (WebAssemblywrapper tglobaladdr:$off)))), 252 (LOAD16_U_I64 tglobaladdr:$off, $addr, 0)>; 253def : Pat<(i64 (sextloadi32 (regPlusGA I32:$addr, 254 (WebAssemblywrapper tglobaladdr:$off)))), 255 (LOAD32_S_I64 tglobaladdr:$off, $addr, 0)>; 256def : Pat<(i64 (zextloadi32 (regPlusGA I32:$addr, 257 (WebAssemblywrapper tglobaladdr:$off)))), 258 (LOAD32_U_I64 tglobaladdr:$off, $addr, 0)>; 259def : Pat<(i32 (sextloadi8 (add I32:$addr, 260 (WebAssemblywrapper texternalsym:$off)))), 261 (LOAD8_S_I32 texternalsym:$off, $addr, 0)>; 262def : Pat<(i32 (zextloadi8 (add I32:$addr, 263 (WebAssemblywrapper texternalsym:$off)))), 264 (LOAD8_U_I32 texternalsym:$off, $addr, 0)>; 265def : Pat<(i32 (sextloadi16 (add I32:$addr, 266 (WebAssemblywrapper texternalsym:$off)))), 267 (LOAD16_S_I32 texternalsym:$off, $addr, 0)>; 268def : Pat<(i32 (zextloadi16 (add I32:$addr, 269 (WebAssemblywrapper texternalsym:$off)))), 270 (LOAD16_U_I32 texternalsym:$off, $addr, 0)>; 271def : Pat<(i64 (sextloadi8 (add I32:$addr, 272 (WebAssemblywrapper texternalsym:$off)))), 273 (LOAD8_S_I64 texternalsym:$off, $addr, 0)>; 274def : Pat<(i64 (zextloadi8 (add I32:$addr, 275 (WebAssemblywrapper texternalsym:$off)))), 276 (LOAD8_U_I64 texternalsym:$off, $addr, 0)>; 277def : Pat<(i64 (sextloadi16 (add I32:$addr, 278 (WebAssemblywrapper texternalsym:$off)))), 279 (LOAD16_S_I64 texternalsym:$off, $addr, 0)>; 280def : Pat<(i64 (zextloadi16 (add I32:$addr, 281 (WebAssemblywrapper texternalsym:$off)))), 282 (LOAD16_U_I64 texternalsym:$off, $addr, 0)>; 283def : Pat<(i64 (sextloadi32 (add I32:$addr, 284 (WebAssemblywrapper texternalsym:$off)))), 285 (LOAD32_S_I64 texternalsym:$off, $addr, 0)>; 286def : Pat<(i64 (zextloadi32 (add I32:$addr, 287 (WebAssemblywrapper texternalsym:$off)))), 288 (LOAD32_U_I64 texternalsym:$off, $addr, 0)>; 289 290// Select extending loads with just a constant offset. 291def : Pat<(i32 (sextloadi8 imm:$off)), 292 (LOAD8_S_I32 imm:$off, (CONST_I32 0), 0)>; 293def : Pat<(i32 (zextloadi8 imm:$off)), 294 (LOAD8_U_I32 imm:$off, (CONST_I32 0), 0)>; 295def : Pat<(i32 (sextloadi16 imm:$off)), 296 (LOAD16_S_I32 imm:$off, (CONST_I32 0), 0)>; 297def : Pat<(i32 (zextloadi16 imm:$off)), 298 (LOAD16_U_I32 imm:$off, (CONST_I32 0), 0)>; 299def : Pat<(i64 (sextloadi8 imm:$off)), 300 (LOAD8_S_I64 imm:$off, (CONST_I32 0), 0)>; 301def : Pat<(i64 (zextloadi8 imm:$off)), 302 (LOAD8_U_I64 imm:$off, (CONST_I32 0), 0)>; 303def : Pat<(i64 (sextloadi16 imm:$off)), 304 (LOAD16_S_I64 imm:$off, (CONST_I32 0), 0)>; 305def : Pat<(i64 (zextloadi16 imm:$off)), 306 (LOAD16_U_I64 imm:$off, (CONST_I32 0), 0)>; 307def : Pat<(i64 (sextloadi32 imm:$off)), 308 (LOAD32_S_I64 imm:$off, (CONST_I32 0), 0)>; 309def : Pat<(i64 (zextloadi32 imm:$off)), 310 (LOAD32_U_I64 imm:$off, (CONST_I32 0), 0)>; 311def : Pat<(i32 (sextloadi8 (WebAssemblywrapper tglobaladdr:$off))), 312 (LOAD8_S_I32 tglobaladdr:$off, (CONST_I32 0), 0)>; 313def : Pat<(i32 (zextloadi8 (WebAssemblywrapper tglobaladdr:$off))), 314 (LOAD8_U_I32 tglobaladdr:$off, (CONST_I32 0), 0)>; 315def : Pat<(i32 (sextloadi16 (WebAssemblywrapper tglobaladdr:$off))), 316 (LOAD16_S_I32 tglobaladdr:$off, (CONST_I32 0), 0)>; 317def : Pat<(i32 (zextloadi16 (WebAssemblywrapper tglobaladdr:$off))), 318 (LOAD16_U_I32 tglobaladdr:$off, (CONST_I32 0), 0)>; 319def : Pat<(i64 (sextloadi8 (WebAssemblywrapper tglobaladdr:$off))), 320 (LOAD8_S_I64 tglobaladdr:$off, (CONST_I32 0), 0)>; 321def : Pat<(i64 (zextloadi8 (WebAssemblywrapper tglobaladdr:$off))), 322 (LOAD8_U_I64 tglobaladdr:$off, (CONST_I32 0), 0)>; 323def : Pat<(i64 (sextloadi16 (WebAssemblywrapper tglobaladdr:$off))), 324 (LOAD16_S_I64 tglobaladdr:$off, (CONST_I32 0), 0)>; 325def : Pat<(i64 (zextloadi16 (WebAssemblywrapper tglobaladdr:$off))), 326 (LOAD16_U_I64 tglobaladdr:$off, (CONST_I32 0), 0)>; 327def : Pat<(i64 (sextloadi32 (WebAssemblywrapper tglobaladdr:$off))), 328 (LOAD32_S_I64 tglobaladdr:$off, (CONST_I32 0), 0)>; 329def : Pat<(i64 (zextloadi32 (WebAssemblywrapper tglobaladdr:$off))), 330 (LOAD32_U_I64 tglobaladdr:$off, (CONST_I32 0), 0)>; 331def : Pat<(i32 (sextloadi8 (WebAssemblywrapper texternalsym:$off))), 332 (LOAD8_S_I32 texternalsym:$off, (CONST_I32 0), 0)>; 333def : Pat<(i32 (zextloadi8 (WebAssemblywrapper texternalsym:$off))), 334 (LOAD8_U_I32 texternalsym:$off, (CONST_I32 0), 0)>; 335def : Pat<(i32 (sextloadi16 (WebAssemblywrapper texternalsym:$off))), 336 (LOAD16_S_I32 texternalsym:$off, (CONST_I32 0), 0)>; 337def : Pat<(i32 (zextloadi16 (WebAssemblywrapper texternalsym:$off))), 338 (LOAD16_U_I32 texternalsym:$off, (CONST_I32 0), 0)>; 339def : Pat<(i64 (sextloadi8 (WebAssemblywrapper texternalsym:$off))), 340 (LOAD8_S_I64 texternalsym:$off, (CONST_I32 0), 0)>; 341def : Pat<(i64 (zextloadi8 (WebAssemblywrapper texternalsym:$off))), 342 (LOAD8_U_I64 texternalsym:$off, (CONST_I32 0), 0)>; 343def : Pat<(i64 (sextloadi16 (WebAssemblywrapper texternalsym:$off))), 344 (LOAD16_S_I64 texternalsym:$off, (CONST_I32 0), 0)>; 345def : Pat<(i64 (zextloadi16 (WebAssemblywrapper texternalsym:$off))), 346 (LOAD16_U_I64 texternalsym:$off, (CONST_I32 0), 0)>; 347def : Pat<(i64 (sextloadi32 (WebAssemblywrapper texternalsym:$off))), 348 (LOAD32_S_I64 texternalsym:$off, (CONST_I32 0), 0)>; 349def : Pat<(i64 (zextloadi32 (WebAssemblywrapper texternalsym:$off))), 350 (LOAD32_U_I64 texternalsym:$off, (CONST_I32 0), 0)>; 351 352// Resolve "don't care" extending loads to zero-extending loads. This is 353// somewhat arbitrary, but zero-extending is conceptually simpler. 354 355// Select "don't care" extending loads with no constant offset. 356def : Pat<(i32 (extloadi8 I32:$addr)), (LOAD8_U_I32 0, $addr, 0)>; 357def : Pat<(i32 (extloadi16 I32:$addr)), (LOAD16_U_I32 0, $addr, 0)>; 358def : Pat<(i64 (extloadi8 I32:$addr)), (LOAD8_U_I64 0, $addr, 0)>; 359def : Pat<(i64 (extloadi16 I32:$addr)), (LOAD16_U_I64 0, $addr, 0)>; 360def : Pat<(i64 (extloadi32 I32:$addr)), (LOAD32_U_I64 0, $addr, 0)>; 361 362// Select "don't care" extending loads with a constant offset. 363def : Pat<(i32 (extloadi8 (regPlusImm I32:$addr, imm:$off))), 364 (LOAD8_U_I32 imm:$off, $addr, 0)>; 365def : Pat<(i32 (extloadi16 (regPlusImm I32:$addr, imm:$off))), 366 (LOAD16_U_I32 imm:$off, $addr, 0)>; 367def : Pat<(i64 (extloadi8 (regPlusImm I32:$addr, imm:$off))), 368 (LOAD8_U_I64 imm:$off, $addr, 0)>; 369def : Pat<(i64 (extloadi16 (regPlusImm I32:$addr, imm:$off))), 370 (LOAD16_U_I64 imm:$off, $addr, 0)>; 371def : Pat<(i64 (extloadi32 (regPlusImm I32:$addr, imm:$off))), 372 (LOAD32_U_I64 imm:$off, $addr, 0)>; 373def : Pat<(i32 (extloadi8 (or_is_add I32:$addr, imm:$off))), 374 (LOAD8_U_I32 imm:$off, $addr, 0)>; 375def : Pat<(i32 (extloadi16 (or_is_add I32:$addr, imm:$off))), 376 (LOAD16_U_I32 imm:$off, $addr, 0)>; 377def : Pat<(i64 (extloadi8 (or_is_add I32:$addr, imm:$off))), 378 (LOAD8_U_I64 imm:$off, $addr, 0)>; 379def : Pat<(i64 (extloadi16 (or_is_add I32:$addr, imm:$off))), 380 (LOAD16_U_I64 imm:$off, $addr, 0)>; 381def : Pat<(i64 (extloadi32 (or_is_add I32:$addr, imm:$off))), 382 (LOAD32_U_I64 imm:$off, $addr, 0)>; 383def : Pat<(i32 (extloadi8 (regPlusGA I32:$addr, 384 (WebAssemblywrapper tglobaladdr:$off)))), 385 (LOAD8_U_I32 tglobaladdr:$off, $addr, 0)>; 386def : Pat<(i32 (extloadi16 (regPlusGA I32:$addr, 387 (WebAssemblywrapper tglobaladdr:$off)))), 388 (LOAD16_U_I32 tglobaladdr:$off, $addr, 0)>; 389def : Pat<(i64 (extloadi8 (regPlusGA I32:$addr, 390 (WebAssemblywrapper tglobaladdr:$off)))), 391 (LOAD8_U_I64 tglobaladdr:$off, $addr, 0)>; 392def : Pat<(i64 (extloadi16 (regPlusGA I32:$addr, 393 (WebAssemblywrapper tglobaladdr:$off)))), 394 (LOAD16_U_I64 tglobaladdr:$off, $addr, 0)>; 395def : Pat<(i64 (extloadi32 (regPlusGA I32:$addr, 396 (WebAssemblywrapper tglobaladdr:$off)))), 397 (LOAD32_U_I64 tglobaladdr:$off, $addr, 0)>; 398def : Pat<(i32 (extloadi8 (add I32:$addr, 399 (WebAssemblywrapper texternalsym:$off)))), 400 (LOAD8_U_I32 texternalsym:$off, $addr, 0)>; 401def : Pat<(i32 (extloadi16 (add I32:$addr, 402 (WebAssemblywrapper texternalsym:$off)))), 403 (LOAD16_U_I32 texternalsym:$off, $addr, 0)>; 404def : Pat<(i64 (extloadi8 (add I32:$addr, 405 (WebAssemblywrapper texternalsym:$off)))), 406 (LOAD8_U_I64 texternalsym:$off, $addr, 0)>; 407def : Pat<(i64 (extloadi16 (add I32:$addr, 408 (WebAssemblywrapper texternalsym:$off)))), 409 (LOAD16_U_I64 texternalsym:$off, $addr, 0)>; 410def : Pat<(i64 (extloadi32 (add I32:$addr, 411 (WebAssemblywrapper texternalsym:$off)))), 412 (LOAD32_U_I64 texternalsym:$off, $addr, 0)>; 413 414// Select "don't care" extending loads with just a constant offset. 415def : Pat<(i32 (extloadi8 imm:$off)), 416 (LOAD8_U_I32 imm:$off, (CONST_I32 0), 0)>; 417def : Pat<(i32 (extloadi16 imm:$off)), 418 (LOAD16_U_I32 imm:$off, (CONST_I32 0), 0)>; 419def : Pat<(i64 (extloadi8 imm:$off)), 420 (LOAD8_U_I64 imm:$off, (CONST_I32 0), 0)>; 421def : Pat<(i64 (extloadi16 imm:$off)), 422 (LOAD16_U_I64 imm:$off, (CONST_I32 0), 0)>; 423def : Pat<(i64 (extloadi32 imm:$off)), 424 (LOAD32_U_I64 imm:$off, (CONST_I32 0), 0)>; 425def : Pat<(i32 (extloadi8 (WebAssemblywrapper tglobaladdr:$off))), 426 (LOAD8_U_I32 tglobaladdr:$off, (CONST_I32 0), 0)>; 427def : Pat<(i32 (extloadi16 (WebAssemblywrapper tglobaladdr:$off))), 428 (LOAD16_U_I32 tglobaladdr:$off, (CONST_I32 0), 0)>; 429def : Pat<(i64 (extloadi8 (WebAssemblywrapper tglobaladdr:$off))), 430 (LOAD8_U_I64 tglobaladdr:$off, (CONST_I32 0), 0)>; 431def : Pat<(i64 (extloadi16 (WebAssemblywrapper tglobaladdr:$off))), 432 (LOAD16_U_I64 tglobaladdr:$off, (CONST_I32 0), 0)>; 433def : Pat<(i64 (extloadi32 (WebAssemblywrapper tglobaladdr:$off))), 434 (LOAD32_U_I64 tglobaladdr:$off, (CONST_I32 0), 0)>; 435def : Pat<(i32 (extloadi8 (WebAssemblywrapper texternalsym:$off))), 436 (LOAD8_U_I32 texternalsym:$off, (CONST_I32 0), 0)>; 437def : Pat<(i32 (extloadi16 (WebAssemblywrapper texternalsym:$off))), 438 (LOAD16_U_I32 texternalsym:$off, (CONST_I32 0), 0)>; 439def : Pat<(i64 (extloadi8 (WebAssemblywrapper texternalsym:$off))), 440 (LOAD8_U_I64 texternalsym:$off, (CONST_I32 0), 0)>; 441def : Pat<(i64 (extloadi16 (WebAssemblywrapper texternalsym:$off))), 442 (LOAD16_U_I64 texternalsym:$off, (CONST_I32 0), 0)>; 443def : Pat<(i64 (extloadi32 (WebAssemblywrapper texternalsym:$off))), 444 (LOAD32_U_I64 tglobaladdr:$off, (CONST_I32 0), 0)>; 445 446let Defs = [ARGUMENTS] in { 447 448// Basic store. 449// Note: WebAssembly inverts SelectionDAG's usual operand order. 450def STORE_I32 : I<(outs), (ins i32imm:$off, I32:$addr, 451 P2Align:$p2align, I32:$val), [], 452 "i32.store\t${off}(${addr})${p2align}, $val", 0x33>; 453def STORE_I64 : I<(outs), (ins i32imm:$off, I32:$addr, 454 P2Align:$p2align, I64:$val), [], 455 "i64.store\t${off}(${addr})${p2align}, $val", 0x34>; 456def STORE_F32 : I<(outs), (ins i32imm:$off, I32:$addr, 457 P2Align:$p2align, F32:$val), [], 458 "f32.store\t${off}(${addr})${p2align}, $val", 0x35>; 459def STORE_F64 : I<(outs), (ins i32imm:$off, I32:$addr, 460 P2Align:$p2align, F64:$val), [], 461 "f64.store\t${off}(${addr})${p2align}, $val", 0x36>; 462 463} // Defs = [ARGUMENTS] 464 465// Select stores with no constant offset. 466def : Pat<(store I32:$val, I32:$addr), (STORE_I32 0, I32:$addr, 0, I32:$val)>; 467def : Pat<(store I64:$val, I32:$addr), (STORE_I64 0, I32:$addr, 0, I64:$val)>; 468def : Pat<(store F32:$val, I32:$addr), (STORE_F32 0, I32:$addr, 0, F32:$val)>; 469def : Pat<(store F64:$val, I32:$addr), (STORE_F64 0, I32:$addr, 0, F64:$val)>; 470 471// Select stores with a constant offset. 472def : Pat<(store I32:$val, (regPlusImm I32:$addr, imm:$off)), 473 (STORE_I32 imm:$off, I32:$addr, 0, I32:$val)>; 474def : Pat<(store I64:$val, (regPlusImm I32:$addr, imm:$off)), 475 (STORE_I64 imm:$off, I32:$addr, 0, I64:$val)>; 476def : Pat<(store F32:$val, (regPlusImm I32:$addr, imm:$off)), 477 (STORE_F32 imm:$off, I32:$addr, 0, F32:$val)>; 478def : Pat<(store F64:$val, (regPlusImm I32:$addr, imm:$off)), 479 (STORE_F64 imm:$off, I32:$addr, 0, F64:$val)>; 480def : Pat<(store I32:$val, (or_is_add I32:$addr, imm:$off)), 481 (STORE_I32 imm:$off, I32:$addr, 0, I32:$val)>; 482def : Pat<(store I64:$val, (or_is_add I32:$addr, imm:$off)), 483 (STORE_I64 imm:$off, I32:$addr, 0, I64:$val)>; 484def : Pat<(store F32:$val, (or_is_add I32:$addr, imm:$off)), 485 (STORE_F32 imm:$off, I32:$addr, 0, F32:$val)>; 486def : Pat<(store F64:$val, (or_is_add I32:$addr, imm:$off)), 487 (STORE_F64 imm:$off, I32:$addr, 0, F64:$val)>; 488def : Pat<(store I32:$val, (regPlusGA I32:$addr, 489 (WebAssemblywrapper tglobaladdr:$off))), 490 (STORE_I32 tglobaladdr:$off, I32:$addr, 0, I32:$val)>; 491def : Pat<(store I64:$val, (regPlusGA I32:$addr, 492 (WebAssemblywrapper tglobaladdr:$off))), 493 (STORE_I64 tglobaladdr:$off, I32:$addr, 0, I64:$val)>; 494def : Pat<(store F32:$val, (regPlusGA I32:$addr, 495 (WebAssemblywrapper tglobaladdr:$off))), 496 (STORE_F32 tglobaladdr:$off, I32:$addr, 0, F32:$val)>; 497def : Pat<(store F64:$val, (regPlusGA I32:$addr, 498 (WebAssemblywrapper tglobaladdr:$off))), 499 (STORE_F64 tglobaladdr:$off, I32:$addr, 0, F64:$val)>; 500def : Pat<(store I32:$val, (add I32:$addr, 501 (WebAssemblywrapper texternalsym:$off))), 502 (STORE_I32 texternalsym:$off, I32:$addr, 0, I32:$val)>; 503def : Pat<(store I64:$val, (add I32:$addr, 504 (WebAssemblywrapper texternalsym:$off))), 505 (STORE_I64 texternalsym:$off, I32:$addr, 0, I64:$val)>; 506def : Pat<(store F32:$val, (add I32:$addr, 507 (WebAssemblywrapper texternalsym:$off))), 508 (STORE_F32 texternalsym:$off, I32:$addr, 0, F32:$val)>; 509def : Pat<(store F64:$val, (add I32:$addr, 510 (WebAssemblywrapper texternalsym:$off))), 511 (STORE_F64 texternalsym:$off, I32:$addr, 0, F64:$val)>; 512 513// Select stores with just a constant offset. 514def : Pat<(store I32:$val, imm:$off), 515 (STORE_I32 imm:$off, (CONST_I32 0), 0, I32:$val)>; 516def : Pat<(store I64:$val, imm:$off), 517 (STORE_I64 imm:$off, (CONST_I32 0), 0, I64:$val)>; 518def : Pat<(store F32:$val, imm:$off), 519 (STORE_F32 imm:$off, (CONST_I32 0), 0, F32:$val)>; 520def : Pat<(store F64:$val, imm:$off), 521 (STORE_F64 imm:$off, (CONST_I32 0), 0, F64:$val)>; 522def : Pat<(store I32:$val, (WebAssemblywrapper tglobaladdr:$off)), 523 (STORE_I32 tglobaladdr:$off, (CONST_I32 0), 0, I32:$val)>; 524def : Pat<(store I64:$val, (WebAssemblywrapper tglobaladdr:$off)), 525 (STORE_I64 tglobaladdr:$off, (CONST_I32 0), 0, I64:$val)>; 526def : Pat<(store F32:$val, (WebAssemblywrapper tglobaladdr:$off)), 527 (STORE_F32 tglobaladdr:$off, (CONST_I32 0), 0, F32:$val)>; 528def : Pat<(store F64:$val, (WebAssemblywrapper tglobaladdr:$off)), 529 (STORE_F64 tglobaladdr:$off, (CONST_I32 0), 0, F64:$val)>; 530def : Pat<(store I32:$val, (WebAssemblywrapper texternalsym:$off)), 531 (STORE_I32 texternalsym:$off, (CONST_I32 0), 0, I32:$val)>; 532def : Pat<(store I64:$val, (WebAssemblywrapper texternalsym:$off)), 533 (STORE_I64 texternalsym:$off, (CONST_I32 0), 0, I64:$val)>; 534def : Pat<(store F32:$val, (WebAssemblywrapper texternalsym:$off)), 535 (STORE_F32 texternalsym:$off, (CONST_I32 0), 0, F32:$val)>; 536def : Pat<(store F64:$val, (WebAssemblywrapper texternalsym:$off)), 537 (STORE_F64 texternalsym:$off, (CONST_I32 0), 0, F64:$val)>; 538 539let Defs = [ARGUMENTS] in { 540 541// Truncating store. 542def STORE8_I32 : I<(outs), (ins i32imm:$off, I32:$addr, 543 P2Align:$p2align, I32:$val), [], 544 "i32.store8\t${off}(${addr})${p2align}, $val", 0x2e>; 545def STORE16_I32 : I<(outs), (ins i32imm:$off, I32:$addr, 546 P2Align:$p2align, I32:$val), [], 547 "i32.store16\t${off}(${addr})${p2align}, $val", 0x2f>; 548def STORE8_I64 : I<(outs), (ins i32imm:$off, I32:$addr, 549 P2Align:$p2align, I64:$val), [], 550 "i64.store8\t${off}(${addr})${p2align}, $val", 0x30>; 551def STORE16_I64 : I<(outs), (ins i32imm:$off, I32:$addr, 552 P2Align:$p2align, I64:$val), [], 553 "i64.store16\t${off}(${addr})${p2align}, $val", 0x31>; 554def STORE32_I64 : I<(outs), (ins i32imm:$off, I32:$addr, 555 P2Align:$p2align, I64:$val), [], 556 "i64.store32\t${off}(${addr})${p2align}, $val", 0x32>; 557 558} // Defs = [ARGUMENTS] 559 560// Select truncating stores with no constant offset. 561def : Pat<(truncstorei8 I32:$val, I32:$addr), 562 (STORE8_I32 0, I32:$addr, 0, I32:$val)>; 563def : Pat<(truncstorei16 I32:$val, I32:$addr), 564 (STORE16_I32 0, I32:$addr, 0, I32:$val)>; 565def : Pat<(truncstorei8 I64:$val, I32:$addr), 566 (STORE8_I64 0, I32:$addr, 0, I64:$val)>; 567def : Pat<(truncstorei16 I64:$val, I32:$addr), 568 (STORE16_I64 0, I32:$addr, 0, I64:$val)>; 569def : Pat<(truncstorei32 I64:$val, I32:$addr), 570 (STORE32_I64 0, I32:$addr, 0, I64:$val)>; 571 572// Select truncating stores with a constant offset. 573def : Pat<(truncstorei8 I32:$val, (regPlusImm I32:$addr, imm:$off)), 574 (STORE8_I32 imm:$off, I32:$addr, 0, I32:$val)>; 575def : Pat<(truncstorei16 I32:$val, (regPlusImm I32:$addr, imm:$off)), 576 (STORE16_I32 imm:$off, I32:$addr, 0, I32:$val)>; 577def : Pat<(truncstorei8 I64:$val, (regPlusImm I32:$addr, imm:$off)), 578 (STORE8_I64 imm:$off, I32:$addr, 0, I64:$val)>; 579def : Pat<(truncstorei16 I64:$val, (regPlusImm I32:$addr, imm:$off)), 580 (STORE16_I64 imm:$off, I32:$addr, 0, I64:$val)>; 581def : Pat<(truncstorei32 I64:$val, (regPlusImm I32:$addr, imm:$off)), 582 (STORE32_I64 imm:$off, I32:$addr, 0, I64:$val)>; 583def : Pat<(truncstorei8 I32:$val, (or_is_add I32:$addr, imm:$off)), 584 (STORE8_I32 imm:$off, I32:$addr, 0, I32:$val)>; 585def : Pat<(truncstorei16 I32:$val, (or_is_add I32:$addr, imm:$off)), 586 (STORE16_I32 imm:$off, I32:$addr, 0, I32:$val)>; 587def : Pat<(truncstorei8 I64:$val, (or_is_add I32:$addr, imm:$off)), 588 (STORE8_I64 imm:$off, I32:$addr, 0, I64:$val)>; 589def : Pat<(truncstorei16 I64:$val, (or_is_add I32:$addr, imm:$off)), 590 (STORE16_I64 imm:$off, I32:$addr, 0, I64:$val)>; 591def : Pat<(truncstorei32 I64:$val, (or_is_add I32:$addr, imm:$off)), 592 (STORE32_I64 imm:$off, I32:$addr, 0, I64:$val)>; 593def : Pat<(truncstorei8 I32:$val, 594 (regPlusGA I32:$addr, 595 (WebAssemblywrapper tglobaladdr:$off))), 596 (STORE8_I32 tglobaladdr:$off, I32:$addr, 0, I32:$val)>; 597def : Pat<(truncstorei16 I32:$val, 598 (regPlusGA I32:$addr, 599 (WebAssemblywrapper tglobaladdr:$off))), 600 (STORE16_I32 tglobaladdr:$off, I32:$addr, 0, I32:$val)>; 601def : Pat<(truncstorei8 I64:$val, 602 (regPlusGA I32:$addr, 603 (WebAssemblywrapper tglobaladdr:$off))), 604 (STORE8_I64 tglobaladdr:$off, I32:$addr, 0, I64:$val)>; 605def : Pat<(truncstorei16 I64:$val, 606 (regPlusGA I32:$addr, 607 (WebAssemblywrapper tglobaladdr:$off))), 608 (STORE16_I64 tglobaladdr:$off, I32:$addr, 0, I64:$val)>; 609def : Pat<(truncstorei32 I64:$val, 610 (regPlusGA I32:$addr, 611 (WebAssemblywrapper tglobaladdr:$off))), 612 (STORE32_I64 tglobaladdr:$off, I32:$addr, 0, I64:$val)>; 613def : Pat<(truncstorei8 I32:$val, (add I32:$addr, 614 (WebAssemblywrapper texternalsym:$off))), 615 (STORE8_I32 texternalsym:$off, I32:$addr, 0, I32:$val)>; 616def : Pat<(truncstorei16 I32:$val, 617 (add I32:$addr, 618 (WebAssemblywrapper texternalsym:$off))), 619 (STORE16_I32 texternalsym:$off, I32:$addr, 0, I32:$val)>; 620def : Pat<(truncstorei8 I64:$val, 621 (add I32:$addr, 622 (WebAssemblywrapper texternalsym:$off))), 623 (STORE8_I64 texternalsym:$off, I32:$addr, 0, I64:$val)>; 624def : Pat<(truncstorei16 I64:$val, 625 (add I32:$addr, 626 (WebAssemblywrapper texternalsym:$off))), 627 (STORE16_I64 texternalsym:$off, I32:$addr, 0, I64:$val)>; 628def : Pat<(truncstorei32 I64:$val, 629 (add I32:$addr, 630 (WebAssemblywrapper texternalsym:$off))), 631 (STORE32_I64 texternalsym:$off, I32:$addr, 0, I64:$val)>; 632 633// Select truncating stores with just a constant offset. 634def : Pat<(truncstorei8 I32:$val, imm:$off), 635 (STORE8_I32 imm:$off, (CONST_I32 0), 0, I32:$val)>; 636def : Pat<(truncstorei16 I32:$val, imm:$off), 637 (STORE16_I32 imm:$off, (CONST_I32 0), 0, I32:$val)>; 638def : Pat<(truncstorei8 I64:$val, imm:$off), 639 (STORE8_I64 imm:$off, (CONST_I32 0), 0, I64:$val)>; 640def : Pat<(truncstorei16 I64:$val, imm:$off), 641 (STORE16_I64 imm:$off, (CONST_I32 0), 0, I64:$val)>; 642def : Pat<(truncstorei32 I64:$val, imm:$off), 643 (STORE32_I64 imm:$off, (CONST_I32 0), 0, I64:$val)>; 644def : Pat<(truncstorei8 I32:$val, (WebAssemblywrapper tglobaladdr:$off)), 645 (STORE8_I32 tglobaladdr:$off, (CONST_I32 0), 0, I32:$val)>; 646def : Pat<(truncstorei16 I32:$val, (WebAssemblywrapper tglobaladdr:$off)), 647 (STORE16_I32 tglobaladdr:$off, (CONST_I32 0), 0, I32:$val)>; 648def : Pat<(truncstorei8 I64:$val, (WebAssemblywrapper tglobaladdr:$off)), 649 (STORE8_I64 tglobaladdr:$off, (CONST_I32 0), 0, I64:$val)>; 650def : Pat<(truncstorei16 I64:$val, (WebAssemblywrapper tglobaladdr:$off)), 651 (STORE16_I64 tglobaladdr:$off, (CONST_I32 0), 0, I64:$val)>; 652def : Pat<(truncstorei32 I64:$val, (WebAssemblywrapper tglobaladdr:$off)), 653 (STORE32_I64 tglobaladdr:$off, (CONST_I32 0), 0, I64:$val)>; 654def : Pat<(truncstorei8 I32:$val, (WebAssemblywrapper texternalsym:$off)), 655 (STORE8_I32 texternalsym:$off, (CONST_I32 0), 0, I32:$val)>; 656def : Pat<(truncstorei16 I32:$val, (WebAssemblywrapper texternalsym:$off)), 657 (STORE16_I32 texternalsym:$off, (CONST_I32 0), 0, I32:$val)>; 658def : Pat<(truncstorei8 I64:$val, (WebAssemblywrapper texternalsym:$off)), 659 (STORE8_I64 texternalsym:$off, (CONST_I32 0), 0, I64:$val)>; 660def : Pat<(truncstorei16 I64:$val, (WebAssemblywrapper texternalsym:$off)), 661 (STORE16_I64 texternalsym:$off, (CONST_I32 0), 0, I64:$val)>; 662def : Pat<(truncstorei32 I64:$val, (WebAssemblywrapper texternalsym:$off)), 663 (STORE32_I64 texternalsym:$off, (CONST_I32 0), 0, I64:$val)>; 664 665let Defs = [ARGUMENTS] in { 666 667// Current memory size. 668def CURRENT_MEMORY_I32 : I<(outs I32:$dst), (ins), 669 [(set I32:$dst, (int_wasm_current_memory))], 670 "current_memory\t$dst", 0x3b>, 671 Requires<[HasAddr32]>; 672def CURRENT_MEMORY_I64 : I<(outs I64:$dst), (ins), 673 [(set I64:$dst, (int_wasm_current_memory))], 674 "current_memory\t$dst">, 675 Requires<[HasAddr64]>; 676 677// Grow memory. 678def GROW_MEMORY_I32 : I<(outs), (ins I32:$delta), 679 [(int_wasm_grow_memory I32:$delta)], 680 "grow_memory\t$delta", 0x39>, 681 Requires<[HasAddr32]>; 682def GROW_MEMORY_I64 : I<(outs), (ins I64:$delta), 683 [(int_wasm_grow_memory I64:$delta)], 684 "grow_memory\t$delta">, 685 Requires<[HasAddr64]>; 686 687} // Defs = [ARGUMENTS] 688