blob: eba9b80d32861a1f312729315abd900c6e8d2d38 [file] [log] [blame]
JF Bastien5ca0bac2015-07-10 18:23:10 +00001// WebAssemblyInstrMemory.td-WebAssembly Memory codegen support -*- tablegen -*-
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
JF Bastien5ca0bac2015-07-10 18:23:10 +00006//
7//===----------------------------------------------------------------------===//
8///
9/// \file
Adrian Prantl5f8f34e42018-05-01 15:54:18 +000010/// WebAssembly Memory operand code-gen constructs.
JF Bastien5ca0bac2015-07-10 18:23:10 +000011///
12//===----------------------------------------------------------------------===//
13
Dan Gohman9c54d3b2015-11-25 18:13:18 +000014// TODO:
JF Bastien73ff6af2015-08-31 22:24:11 +000015// - HasAddr64
JF Bastien73ff6af2015-08-31 22:24:11 +000016// - WebAssemblyTargetLowering having to do with atomics
Dan Gohman4b9d7912015-12-15 22:01:29 +000017// - Each has optional alignment.
JF Bastien73ff6af2015-08-31 22:24:11 +000018
19// WebAssembly has i8/i16/i32/i64/f32/f64 memory types, but doesn't have i8/i16
20// local types. These memory-only types instead zero- or sign-extend into local
21// types when loading, and truncate when storing.
22
Dan Gohman4b9d7912015-12-15 22:01:29 +000023// WebAssembly constant offsets are performed as unsigned with infinite
24// precision, so we need to check for NoUnsignedWrap so that we don't fold an
25// offset for an add that needs wrapping.
Dan Gohmanf225a632016-01-11 22:05:44 +000026def regPlusImm : PatFrag<(ops node:$addr, node:$off),
Dan Gohman4b9d7912015-12-15 22:01:29 +000027 (add node:$addr, node:$off),
Derek Schuff2fa36042017-05-01 16:49:39 +000028 [{ return N->getFlags().hasNoUnsignedWrap(); }]>;
Dan Gohman4b9d7912015-12-15 22:01:29 +000029
Dan Gohman3b09d272016-02-22 20:04:02 +000030// Treat an 'or' node as an 'add' if the or'ed bits are known to be zero.
31def or_is_add : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{
32 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))
33 return CurDAG->MaskedValueIsZero(N->getOperand(0), CN->getAPIntValue());
34
Simon Pilgrimca8bca22018-12-21 15:25:37 +000035 KnownBits Known0 = CurDAG->computeKnownBits(N->getOperand(0), 0);
36 KnownBits Known1 = CurDAG->computeKnownBits(N->getOperand(1), 0);
Craig Topper053cf4d2017-04-28 08:15:33 +000037 return (~Known0.Zero & ~Known1.Zero) == 0;
Dan Gohman3b09d272016-02-22 20:04:02 +000038}]>;
39
Dan Gohmanf225a632016-01-11 22:05:44 +000040// We don't need a regPlusES because external symbols never have constant
41// offsets folded into them, so we can just use add.
42
Derek Schuff885dc592017-10-05 21:18:42 +000043// Defines atomic and non-atomic loads, regular and extending.
Wouter van Oortmerssen48dac312018-06-18 21:22:44 +000044multiclass WebAssemblyLoad<WebAssemblyRegClass rc, string Name, int Opcode> {
Thomas Lively972d7d52019-03-09 04:31:37 +000045 let mayLoad = 1, UseNamedOperandTable = 1 in
Wouter van Oortmerssen48dac312018-06-18 21:22:44 +000046 defm "": I<(outs rc:$dst),
47 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
48 (outs), (ins P2Align:$p2align, offset32_op:$off),
49 [], !strconcat(Name, "\t$dst, ${off}(${addr})${p2align}"),
Wouter van Oortmerssen8a9cb242018-08-27 15:45:51 +000050 !strconcat(Name, "\t${off}${p2align}"), Opcode>;
Wouter van Oortmerssen48dac312018-06-18 21:22:44 +000051}
Derek Schuff0f3bc0f2017-08-31 21:51:48 +000052
JF Bastien73ff6af2015-08-31 22:24:11 +000053// Basic load.
Dan Gohman48abaa92016-10-25 00:17:11 +000054// FIXME: When we can break syntax compatibility, reorder the fields in the
55// asmstrings to match the binary encoding.
Wouter van Oortmerssen48dac312018-06-18 21:22:44 +000056defm LOAD_I32 : WebAssemblyLoad<I32, "i32.load", 0x28>;
57defm LOAD_I64 : WebAssemblyLoad<I64, "i64.load", 0x29>;
58defm LOAD_F32 : WebAssemblyLoad<F32, "f32.load", 0x2a>;
59defm LOAD_F64 : WebAssemblyLoad<F64, "f64.load", 0x2b>;
JF Bastien73ff6af2015-08-31 22:24:11 +000060
Dan Gohman4b9d7912015-12-15 22:01:29 +000061// Select loads with no constant offset.
Heejin Ahnd31bc982018-07-09 20:18:21 +000062class LoadPatNoOffset<ValueType ty, PatFrag kind, NI inst> :
63 Pat<(ty (kind I32:$addr)), (inst 0, 0, I32:$addr)>;
Derek Schuff0f3bc0f2017-08-31 21:51:48 +000064
65def : LoadPatNoOffset<i32, load, LOAD_I32>;
66def : LoadPatNoOffset<i64, load, LOAD_I64>;
67def : LoadPatNoOffset<f32, load, LOAD_F32>;
68def : LoadPatNoOffset<f64, load, LOAD_F64>;
69
Dan Gohman4b9d7912015-12-15 22:01:29 +000070
71// Select loads with a constant offset.
Derek Schuff0f3bc0f2017-08-31 21:51:48 +000072
73// Pattern with address + immediate offset
Heejin Ahnd31bc982018-07-09 20:18:21 +000074class LoadPatImmOff<ValueType ty, PatFrag kind, PatFrag operand, NI inst> :
75 Pat<(ty (kind (operand I32:$addr, imm:$off))), (inst 0, imm:$off, I32:$addr)>;
Derek Schuff0f3bc0f2017-08-31 21:51:48 +000076
77def : LoadPatImmOff<i32, load, regPlusImm, LOAD_I32>;
78def : LoadPatImmOff<i64, load, regPlusImm, LOAD_I64>;
79def : LoadPatImmOff<f32, load, regPlusImm, LOAD_F32>;
80def : LoadPatImmOff<f64, load, regPlusImm, LOAD_F64>;
81def : LoadPatImmOff<i32, load, or_is_add, LOAD_I32>;
82def : LoadPatImmOff<i64, load, or_is_add, LOAD_I64>;
83def : LoadPatImmOff<f32, load, or_is_add, LOAD_F32>;
84def : LoadPatImmOff<f64, load, or_is_add, LOAD_F64>;
85
Dan Gohman4b9d7912015-12-15 22:01:29 +000086// Select loads with just a constant offset.
Heejin Ahnd31bc982018-07-09 20:18:21 +000087class LoadPatOffsetOnly<ValueType ty, PatFrag kind, NI inst> :
88 Pat<(ty (kind imm:$off)), (inst 0, imm:$off, (CONST_I32 0))>;
Derek Schuff0f3bc0f2017-08-31 21:51:48 +000089
90def : LoadPatOffsetOnly<i32, load, LOAD_I32>;
91def : LoadPatOffsetOnly<i64, load, LOAD_I64>;
92def : LoadPatOffsetOnly<f32, load, LOAD_F32>;
93def : LoadPatOffsetOnly<f64, load, LOAD_F64>;
94
Heejin Ahnd31bc982018-07-09 20:18:21 +000095class LoadPatGlobalAddrOffOnly<ValueType ty, PatFrag kind, NI inst> :
96 Pat<(ty (kind (WebAssemblywrapper tglobaladdr:$off))),
Sam Clegg492f7522019-03-26 19:46:15 +000097 (inst 0, tglobaladdr:$off, (CONST_I32 0))>, Requires<[IsNotPIC]>;
Derek Schuff0f3bc0f2017-08-31 21:51:48 +000098
99def : LoadPatGlobalAddrOffOnly<i32, load, LOAD_I32>;
100def : LoadPatGlobalAddrOffOnly<i64, load, LOAD_I64>;
101def : LoadPatGlobalAddrOffOnly<f32, load, LOAD_F32>;
102def : LoadPatGlobalAddrOffOnly<f64, load, LOAD_F64>;
103
JF Bastien73ff6af2015-08-31 22:24:11 +0000104// Extending load.
Wouter van Oortmerssen48dac312018-06-18 21:22:44 +0000105defm LOAD8_S_I32 : WebAssemblyLoad<I32, "i32.load8_s", 0x2c>;
106defm LOAD8_U_I32 : WebAssemblyLoad<I32, "i32.load8_u", 0x2d>;
107defm LOAD16_S_I32 : WebAssemblyLoad<I32, "i32.load16_s", 0x2e>;
108defm LOAD16_U_I32 : WebAssemblyLoad<I32, "i32.load16_u", 0x2f>;
109defm LOAD8_S_I64 : WebAssemblyLoad<I64, "i64.load8_s", 0x30>;
110defm LOAD8_U_I64 : WebAssemblyLoad<I64, "i64.load8_u", 0x31>;
111defm LOAD16_S_I64 : WebAssemblyLoad<I64, "i64.load16_s", 0x32>;
112defm LOAD16_U_I64 : WebAssemblyLoad<I64, "i64.load16_u", 0x33>;
113defm LOAD32_S_I64 : WebAssemblyLoad<I64, "i64.load32_s", 0x34>;
114defm LOAD32_U_I64 : WebAssemblyLoad<I64, "i64.load32_u", 0x35>;
JF Bastien73ff6af2015-08-31 22:24:11 +0000115
Derek Schuff9d779522015-12-05 00:26:39 +0000116// Select extending loads with no constant offset.
Derek Schuff0f3bc0f2017-08-31 21:51:48 +0000117def : LoadPatNoOffset<i32, sextloadi8, LOAD8_S_I32>;
118def : LoadPatNoOffset<i32, zextloadi8, LOAD8_U_I32>;
119def : LoadPatNoOffset<i32, sextloadi16, LOAD16_S_I32>;
120def : LoadPatNoOffset<i32, zextloadi16, LOAD16_U_I32>;
121def : LoadPatNoOffset<i64, sextloadi8, LOAD8_S_I64>;
122def : LoadPatNoOffset<i64, zextloadi8, LOAD8_U_I64>;
123def : LoadPatNoOffset<i64, sextloadi16, LOAD16_S_I64>;
124def : LoadPatNoOffset<i64, zextloadi16, LOAD16_U_I64>;
125def : LoadPatNoOffset<i64, sextloadi32, LOAD32_S_I64>;
126def : LoadPatNoOffset<i64, zextloadi32, LOAD32_U_I64>;
Derek Schuff9d779522015-12-05 00:26:39 +0000127
Dan Gohman4b9d7912015-12-15 22:01:29 +0000128// Select extending loads with a constant offset.
Derek Schuff0f3bc0f2017-08-31 21:51:48 +0000129def : LoadPatImmOff<i32, sextloadi8, regPlusImm, LOAD8_S_I32>;
130def : LoadPatImmOff<i32, zextloadi8, regPlusImm, LOAD8_U_I32>;
131def : LoadPatImmOff<i32, sextloadi16, regPlusImm, LOAD16_S_I32>;
132def : LoadPatImmOff<i32, zextloadi16, regPlusImm, LOAD16_U_I32>;
133def : LoadPatImmOff<i64, sextloadi8, regPlusImm, LOAD8_S_I64>;
134def : LoadPatImmOff<i64, zextloadi8, regPlusImm, LOAD8_U_I64>;
135def : LoadPatImmOff<i64, sextloadi16, regPlusImm, LOAD16_S_I64>;
136def : LoadPatImmOff<i64, zextloadi16, regPlusImm, LOAD16_U_I64>;
137def : LoadPatImmOff<i64, sextloadi32, regPlusImm, LOAD32_S_I64>;
138def : LoadPatImmOff<i64, zextloadi32, regPlusImm, LOAD32_U_I64>;
139
140def : LoadPatImmOff<i32, sextloadi8, or_is_add, LOAD8_S_I32>;
141def : LoadPatImmOff<i32, zextloadi8, or_is_add, LOAD8_U_I32>;
142def : LoadPatImmOff<i32, sextloadi16, or_is_add, LOAD16_S_I32>;
143def : LoadPatImmOff<i32, zextloadi16, or_is_add, LOAD16_U_I32>;
144def : LoadPatImmOff<i64, sextloadi8, or_is_add, LOAD8_S_I64>;
145def : LoadPatImmOff<i64, zextloadi8, or_is_add, LOAD8_U_I64>;
146def : LoadPatImmOff<i64, sextloadi16, or_is_add, LOAD16_S_I64>;
147def : LoadPatImmOff<i64, zextloadi16, or_is_add, LOAD16_U_I64>;
148def : LoadPatImmOff<i64, sextloadi32, or_is_add, LOAD32_S_I64>;
149def : LoadPatImmOff<i64, zextloadi32, or_is_add, LOAD32_U_I64>;
150
Dan Gohman4b9d7912015-12-15 22:01:29 +0000151// Select extending loads with just a constant offset.
Derek Schuff0f3bc0f2017-08-31 21:51:48 +0000152def : LoadPatOffsetOnly<i32, sextloadi8, LOAD8_S_I32>;
153def : LoadPatOffsetOnly<i32, zextloadi8, LOAD8_U_I32>;
154def : LoadPatOffsetOnly<i32, sextloadi16, LOAD16_S_I32>;
155def : LoadPatOffsetOnly<i32, zextloadi16, LOAD16_U_I32>;
156
157def : LoadPatOffsetOnly<i64, sextloadi8, LOAD8_S_I64>;
158def : LoadPatOffsetOnly<i64, zextloadi8, LOAD8_U_I64>;
159def : LoadPatOffsetOnly<i64, sextloadi16, LOAD16_S_I64>;
160def : LoadPatOffsetOnly<i64, zextloadi16, LOAD16_U_I64>;
161def : LoadPatOffsetOnly<i64, sextloadi32, LOAD32_S_I64>;
162def : LoadPatOffsetOnly<i64, zextloadi32, LOAD32_U_I64>;
163
164def : LoadPatGlobalAddrOffOnly<i32, sextloadi8, LOAD8_S_I32>;
165def : LoadPatGlobalAddrOffOnly<i32, zextloadi8, LOAD8_U_I32>;
166def : LoadPatGlobalAddrOffOnly<i32, sextloadi16, LOAD16_S_I32>;
167def : LoadPatGlobalAddrOffOnly<i32, zextloadi16, LOAD16_U_I32>;
168def : LoadPatGlobalAddrOffOnly<i64, sextloadi8, LOAD8_S_I64>;
169def : LoadPatGlobalAddrOffOnly<i64, zextloadi8, LOAD8_U_I64>;
170def : LoadPatGlobalAddrOffOnly<i64, sextloadi16, LOAD16_S_I64>;
171def : LoadPatGlobalAddrOffOnly<i64, zextloadi16, LOAD16_U_I64>;
172def : LoadPatGlobalAddrOffOnly<i64, sextloadi32, LOAD32_S_I64>;
173def : LoadPatGlobalAddrOffOnly<i64, zextloadi32, LOAD32_U_I64>;
174
Dan Gohman4b9d7912015-12-15 22:01:29 +0000175// Resolve "don't care" extending loads to zero-extending loads. This is
176// somewhat arbitrary, but zero-extending is conceptually simpler.
177
178// Select "don't care" extending loads with no constant offset.
Derek Schuff0f3bc0f2017-08-31 21:51:48 +0000179def : LoadPatNoOffset<i32, extloadi8, LOAD8_U_I32>;
180def : LoadPatNoOffset<i32, extloadi16, LOAD16_U_I32>;
181def : LoadPatNoOffset<i64, extloadi8, LOAD8_U_I64>;
182def : LoadPatNoOffset<i64, extloadi16, LOAD16_U_I64>;
183def : LoadPatNoOffset<i64, extloadi32, LOAD32_U_I64>;
184
Dan Gohman4b9d7912015-12-15 22:01:29 +0000185// Select "don't care" extending loads with a constant offset.
Derek Schuff0f3bc0f2017-08-31 21:51:48 +0000186def : LoadPatImmOff<i32, extloadi8, regPlusImm, LOAD8_U_I32>;
187def : LoadPatImmOff<i32, extloadi16, regPlusImm, LOAD16_U_I32>;
188def : LoadPatImmOff<i64, extloadi8, regPlusImm, LOAD8_U_I64>;
189def : LoadPatImmOff<i64, extloadi16, regPlusImm, LOAD16_U_I64>;
190def : LoadPatImmOff<i64, extloadi32, regPlusImm, LOAD32_U_I64>;
191def : LoadPatImmOff<i32, extloadi8, or_is_add, LOAD8_U_I32>;
192def : LoadPatImmOff<i32, extloadi16, or_is_add, LOAD16_U_I32>;
193def : LoadPatImmOff<i64, extloadi8, or_is_add, LOAD8_U_I64>;
194def : LoadPatImmOff<i64, extloadi16, or_is_add, LOAD16_U_I64>;
195def : LoadPatImmOff<i64, extloadi32, or_is_add, LOAD32_U_I64>;
Derek Schuff0f3bc0f2017-08-31 21:51:48 +0000196
Dan Gohman4b9d7912015-12-15 22:01:29 +0000197// Select "don't care" extending loads with just a constant offset.
Derek Schuff0f3bc0f2017-08-31 21:51:48 +0000198def : LoadPatOffsetOnly<i32, extloadi8, LOAD8_U_I32>;
199def : LoadPatOffsetOnly<i32, extloadi16, LOAD16_U_I32>;
200def : LoadPatOffsetOnly<i64, extloadi8, LOAD8_U_I64>;
201def : LoadPatOffsetOnly<i64, extloadi16, LOAD16_U_I64>;
202def : LoadPatOffsetOnly<i64, extloadi32, LOAD32_U_I64>;
203def : LoadPatGlobalAddrOffOnly<i32, extloadi8, LOAD8_U_I32>;
204def : LoadPatGlobalAddrOffOnly<i32, extloadi16, LOAD16_U_I32>;
205def : LoadPatGlobalAddrOffOnly<i64, extloadi8, LOAD8_U_I64>;
206def : LoadPatGlobalAddrOffOnly<i64, extloadi16, LOAD16_U_I64>;
207def : LoadPatGlobalAddrOffOnly<i64, extloadi32, LOAD32_U_I64>;
Derek Schuff0f3bc0f2017-08-31 21:51:48 +0000208
Derek Schuffa2726e92018-03-30 17:02:50 +0000209// Defines atomic and non-atomic stores, regular and truncating
Wouter van Oortmerssen48dac312018-06-18 21:22:44 +0000210multiclass WebAssemblyStore<WebAssemblyRegClass rc, string Name, int Opcode> {
Thomas Lively972d7d52019-03-09 04:31:37 +0000211 let mayStore = 1, UseNamedOperandTable = 1 in
Wouter van Oortmerssen48dac312018-06-18 21:22:44 +0000212 defm "" : I<(outs),
213 (ins P2Align:$p2align, offset32_op:$off, I32:$addr, rc:$val),
214 (outs),
215 (ins P2Align:$p2align, offset32_op:$off), [],
216 !strconcat(Name, "\t${off}(${addr})${p2align}, $val"),
Wouter van Oortmerssen8a9cb242018-08-27 15:45:51 +0000217 !strconcat(Name, "\t${off}${p2align}"), Opcode>;
Wouter van Oortmerssen48dac312018-06-18 21:22:44 +0000218}
JF Bastien73ff6af2015-08-31 22:24:11 +0000219// Basic store.
220// Note: WebAssembly inverts SelectionDAG's usual operand order.
Wouter van Oortmerssen48dac312018-06-18 21:22:44 +0000221defm STORE_I32 : WebAssemblyStore<I32, "i32.store", 0x36>;
222defm STORE_I64 : WebAssemblyStore<I64, "i64.store", 0x37>;
223defm STORE_F32 : WebAssemblyStore<F32, "f32.store", 0x38>;
224defm STORE_F64 : WebAssemblyStore<F64, "f64.store", 0x39>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000225
Dan Gohman4b9d7912015-12-15 22:01:29 +0000226// Select stores with no constant offset.
Wouter van Oortmerssen48dac312018-06-18 21:22:44 +0000227class StorePatNoOffset<ValueType ty, PatFrag node, NI inst> :
Heejin Ahnd31bc982018-07-09 20:18:21 +0000228 Pat<(node ty:$val, I32:$addr), (inst 0, 0, I32:$addr, ty:$val)>;
Derek Schuffa2726e92018-03-30 17:02:50 +0000229
230def : StorePatNoOffset<i32, store, STORE_I32>;
231def : StorePatNoOffset<i64, store, STORE_I64>;
232def : StorePatNoOffset<f32, store, STORE_F32>;
233def : StorePatNoOffset<f64, store, STORE_F64>;
Derek Schuff9d779522015-12-05 00:26:39 +0000234
Dan Gohman4b9d7912015-12-15 22:01:29 +0000235// Select stores with a constant offset.
Heejin Ahnd31bc982018-07-09 20:18:21 +0000236class StorePatImmOff<ValueType ty, PatFrag kind, PatFrag operand, NI inst> :
237 Pat<(kind ty:$val, (operand I32:$addr, imm:$off)),
238 (inst 0, imm:$off, I32:$addr, ty:$val)>;
Derek Schuffa2726e92018-03-30 17:02:50 +0000239
240def : StorePatImmOff<i32, store, regPlusImm, STORE_I32>;
241def : StorePatImmOff<i64, store, regPlusImm, STORE_I64>;
242def : StorePatImmOff<f32, store, regPlusImm, STORE_F32>;
243def : StorePatImmOff<f64, store, regPlusImm, STORE_F64>;
244def : StorePatImmOff<i32, store, or_is_add, STORE_I32>;
245def : StorePatImmOff<i64, store, or_is_add, STORE_I64>;
246def : StorePatImmOff<f32, store, or_is_add, STORE_F32>;
247def : StorePatImmOff<f64, store, or_is_add, STORE_F64>;
248
Dan Gohman4b9d7912015-12-15 22:01:29 +0000249// Select stores with just a constant offset.
Heejin Ahnd31bc982018-07-09 20:18:21 +0000250class StorePatOffsetOnly<ValueType ty, PatFrag kind, NI inst> :
251 Pat<(kind ty:$val, imm:$off), (inst 0, imm:$off, (CONST_I32 0), ty:$val)>;
Derek Schuffa2726e92018-03-30 17:02:50 +0000252def : StorePatOffsetOnly<i32, store, STORE_I32>;
253def : StorePatOffsetOnly<i64, store, STORE_I64>;
254def : StorePatOffsetOnly<f32, store, STORE_F32>;
255def : StorePatOffsetOnly<f64, store, STORE_F64>;
256
Heejin Ahnd31bc982018-07-09 20:18:21 +0000257class StorePatGlobalAddrOffOnly<ValueType ty, PatFrag kind, NI inst> :
258 Pat<(kind ty:$val, (WebAssemblywrapper tglobaladdr:$off)),
Sam Clegg492f7522019-03-26 19:46:15 +0000259 (inst 0, tglobaladdr:$off, (CONST_I32 0), ty:$val)>, Requires<[IsNotPIC]>;
Derek Schuffa2726e92018-03-30 17:02:50 +0000260def : StorePatGlobalAddrOffOnly<i32, store, STORE_I32>;
261def : StorePatGlobalAddrOffOnly<i64, store, STORE_I64>;
262def : StorePatGlobalAddrOffOnly<f32, store, STORE_F32>;
263def : StorePatGlobalAddrOffOnly<f64, store, STORE_F64>;
264
JF Bastien73ff6af2015-08-31 22:24:11 +0000265// Truncating store.
Wouter van Oortmerssen48dac312018-06-18 21:22:44 +0000266defm STORE8_I32 : WebAssemblyStore<I32, "i32.store8", 0x3a>;
267defm STORE16_I32 : WebAssemblyStore<I32, "i32.store16", 0x3b>;
268defm STORE8_I64 : WebAssemblyStore<I64, "i64.store8", 0x3c>;
269defm STORE16_I64 : WebAssemblyStore<I64, "i64.store16", 0x3d>;
270defm STORE32_I64 : WebAssemblyStore<I64, "i64.store32", 0x3e>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000271
Dan Gohman4b9d7912015-12-15 22:01:29 +0000272// Select truncating stores with no constant offset.
Derek Schuffa2726e92018-03-30 17:02:50 +0000273def : StorePatNoOffset<i32, truncstorei8, STORE8_I32>;
274def : StorePatNoOffset<i32, truncstorei16, STORE16_I32>;
275def : StorePatNoOffset<i64, truncstorei8, STORE8_I64>;
276def : StorePatNoOffset<i64, truncstorei16, STORE16_I64>;
277def : StorePatNoOffset<i64, truncstorei32, STORE32_I64>;
JF Bastien73ff6af2015-08-31 22:24:11 +0000278
Dan Gohman4b9d7912015-12-15 22:01:29 +0000279// Select truncating stores with a constant offset.
Derek Schuffa2726e92018-03-30 17:02:50 +0000280def : StorePatImmOff<i32, truncstorei8, regPlusImm, STORE8_I32>;
281def : StorePatImmOff<i32, truncstorei16, regPlusImm, STORE16_I32>;
282def : StorePatImmOff<i64, truncstorei8, regPlusImm, STORE8_I64>;
283def : StorePatImmOff<i64, truncstorei16, regPlusImm, STORE16_I64>;
284def : StorePatImmOff<i64, truncstorei32, regPlusImm, STORE32_I64>;
285def : StorePatImmOff<i32, truncstorei8, or_is_add, STORE8_I32>;
286def : StorePatImmOff<i32, truncstorei16, or_is_add, STORE16_I32>;
287def : StorePatImmOff<i64, truncstorei8, or_is_add, STORE8_I64>;
288def : StorePatImmOff<i64, truncstorei16, or_is_add, STORE16_I64>;
289def : StorePatImmOff<i64, truncstorei32, or_is_add, STORE32_I64>;
290
Dan Gohman4b9d7912015-12-15 22:01:29 +0000291// Select truncating stores with just a constant offset.
Derek Schuffa2726e92018-03-30 17:02:50 +0000292def : StorePatOffsetOnly<i32, truncstorei8, STORE8_I32>;
293def : StorePatOffsetOnly<i32, truncstorei16, STORE16_I32>;
294def : StorePatOffsetOnly<i64, truncstorei8, STORE8_I64>;
295def : StorePatOffsetOnly<i64, truncstorei16, STORE16_I64>;
296def : StorePatOffsetOnly<i64, truncstorei32, STORE32_I64>;
297def : StorePatGlobalAddrOffOnly<i32, truncstorei8, STORE8_I32>;
298def : StorePatGlobalAddrOffOnly<i32, truncstorei16, STORE16_I32>;
299def : StorePatGlobalAddrOffOnly<i64, truncstorei8, STORE8_I64>;
300def : StorePatGlobalAddrOffOnly<i64, truncstorei16, STORE16_I64>;
301def : StorePatGlobalAddrOffOnly<i64, truncstorei32, STORE32_I64>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000302
Derek Schuff31680dd2016-05-02 17:25:22 +0000303// Current memory size.
Wouter van Oortmerssen48dac312018-06-18 21:22:44 +0000304defm MEMORY_SIZE_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
305 (outs), (ins i32imm:$flags),
306 [(set I32:$dst,
307 (int_wasm_memory_size (i32 imm:$flags)))],
308 "memory.size\t$dst, $flags", "memory.size\t$flags",
309 0x3f>,
310 Requires<[HasAddr32]>;
Dan Gohmanbaba8c62015-10-02 20:10:26 +0000311
Dan Gohmand7ffb912015-11-05 20:16:59 +0000312// Grow memory.
Wouter van Oortmerssen48dac312018-06-18 21:22:44 +0000313defm MEMORY_GROW_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
Wouter van Oortmerssen8a9cb242018-08-27 15:45:51 +0000314 (outs), (ins i32imm:$flags),
Wouter van Oortmerssen48dac312018-06-18 21:22:44 +0000315 [(set I32:$dst,
316 (int_wasm_memory_grow (i32 imm:$flags),
317 I32:$delta))],
318 "memory.grow\t$dst, $flags, $delta",
Wouter van Oortmerssen8a9cb242018-08-27 15:45:51 +0000319 "memory.grow\t$flags", 0x40>,
Wouter van Oortmerssen48dac312018-06-18 21:22:44 +0000320 Requires<[HasAddr32]>;