blob: 660f0abfcabe9f6d026717f8ea241a1693be998a [file] [log] [blame]
JF Bastien5ca0bac2015-07-10 18:23:10 +00001// 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
Dan Gohman9c54d3b2015-11-25 18:13:18 +000015// TODO:
JF Bastien73ff6af2015-08-31 22:24:11 +000016// - HasAddr64
JF Bastien73ff6af2015-08-31 22:24:11 +000017// - WebAssemblyTargetLowering having to do with atomics
Dan Gohman4b9d7912015-12-15 22:01:29 +000018// - Each has optional alignment.
JF Bastien73ff6af2015-08-31 22:24:11 +000019
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
Dan Gohman4b9d7912015-12-15 22:01:29 +000024// 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.
Dan Gohmanf225a632016-01-11 22:05:44 +000027def regPlusImm : PatFrag<(ops node:$addr, node:$off),
Dan Gohman4b9d7912015-12-15 22:01:29 +000028 (add node:$addr, node:$off),
Derek Schuff2fa36042017-05-01 16:49:39 +000029 [{ return N->getFlags().hasNoUnsignedWrap(); }]>;
Dan Gohman4b9d7912015-12-15 22:01:29 +000030
Dan Gohman3b09d272016-02-22 20:04:02 +000031// 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
Craig Topper053cf4d2017-04-28 08:15:33 +000036 KnownBits Known0;
37 CurDAG->computeKnownBits(N->getOperand(0), Known0, 0);
38 KnownBits Known1;
39 CurDAG->computeKnownBits(N->getOperand(1), Known1, 0);
40 return (~Known0.Zero & ~Known1.Zero) == 0;
Dan Gohman3b09d272016-02-22 20:04:02 +000041}]>;
42
Dan Gohmanf225a632016-01-11 22:05:44 +000043// GlobalAddresses are conceptually unsigned values, so we can also fold them
Derek Schuff1b258d32016-08-31 20:27:20 +000044// 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.
Dan Gohmanf225a632016-01-11 22:05:44 +000047def regPlusGA : PatFrag<(ops node:$addr, node:$off),
48 (add node:$addr, node:$off),
49 [{
Derek Schuff2fa36042017-05-01 16:49:39 +000050 return N->getFlags().hasNoUnsignedWrap();
Dan Gohmanf225a632016-01-11 22:05:44 +000051}]>;
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
Dan Gohmanfb3e0592015-11-25 19:36:19 +000056let Defs = [ARGUMENTS] in {
57
Derek Schuff885dc592017-10-05 21:18:42 +000058// Defines atomic and non-atomic loads, regular and extending.
59class WebAssemblyLoad<WebAssemblyRegClass rc, string Name, int Opcode> :
60 I<(outs rc:$dst),
Derek Schuff0f3bc0f2017-08-31 21:51:48 +000061 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
62 [], !strconcat(Name, "\t$dst, ${off}(${addr})${p2align}"), Opcode>;
63
JF Bastien73ff6af2015-08-31 22:24:11 +000064// Basic load.
Dan Gohman48abaa92016-10-25 00:17:11 +000065// FIXME: When we can break syntax compatibility, reorder the fields in the
66// asmstrings to match the binary encoding.
Derek Schuff885dc592017-10-05 21:18:42 +000067def LOAD_I32 : WebAssemblyLoad<I32, "i32.load", 0x28>;
68def LOAD_I64 : WebAssemblyLoad<I64, "i64.load", 0x29>;
69def LOAD_F32 : WebAssemblyLoad<F32, "f32.load", 0x2a>;
70def LOAD_F64 : WebAssemblyLoad<F64, "f64.load", 0x2b>;
JF Bastien73ff6af2015-08-31 22:24:11 +000071
Dan Gohman4b9d7912015-12-15 22:01:29 +000072} // Defs = [ARGUMENTS]
73
74// Select loads with no constant offset.
Derek Schuff0f3bc0f2017-08-31 21:51:48 +000075class LoadPatNoOffset<ValueType ty, PatFrag node, I inst> :
76 Pat<(ty (node I32:$addr)), (inst 0, 0, $addr)>;
77
78def : LoadPatNoOffset<i32, load, LOAD_I32>;
79def : LoadPatNoOffset<i64, load, LOAD_I64>;
80def : LoadPatNoOffset<f32, load, LOAD_F32>;
81def : LoadPatNoOffset<f64, load, LOAD_F64>;
82
Dan Gohman4b9d7912015-12-15 22:01:29 +000083
84// Select loads with a constant offset.
Derek Schuff0f3bc0f2017-08-31 21:51:48 +000085
86// Pattern with address + immediate offset
87class LoadPatImmOff<ValueType ty, PatFrag loadkind, PatFrag operand, I inst> :
88 Pat<(ty (loadkind (operand I32:$addr, imm:$off))),
89 (inst 0, imm:$off, $addr)>;
90
91def : LoadPatImmOff<i32, load, regPlusImm, LOAD_I32>;
92def : LoadPatImmOff<i64, load, regPlusImm, LOAD_I64>;
93def : LoadPatImmOff<f32, load, regPlusImm, LOAD_F32>;
94def : LoadPatImmOff<f64, load, regPlusImm, LOAD_F64>;
95def : LoadPatImmOff<i32, load, or_is_add, LOAD_I32>;
96def : LoadPatImmOff<i64, load, or_is_add, LOAD_I64>;
97def : LoadPatImmOff<f32, load, or_is_add, LOAD_F32>;
98def : LoadPatImmOff<f64, load, or_is_add, LOAD_F64>;
99
100class LoadPatGlobalAddr<ValueType ty, PatFrag loadkind, I inst> :
101 Pat<(ty (loadkind (regPlusGA I32:$addr, (WebAssemblywrapper tglobaladdr:$off)))),
102 (inst 0, tglobaladdr:$off, $addr)>;
103
104def : LoadPatGlobalAddr<i32, load, LOAD_I32>;
105def : LoadPatGlobalAddr<i64, load, LOAD_I64>;
106def : LoadPatGlobalAddr<f32, load, LOAD_F32>;
107def : LoadPatGlobalAddr<f64, load, LOAD_F64>;
108
109class LoadPatExternalSym<ValueType ty, PatFrag loadkind, I inst> :
110 Pat<(ty (loadkind (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
111 (inst 0, texternalsym:$off, $addr)>;
112def : LoadPatExternalSym<i32, load, LOAD_I32>;
113def : LoadPatExternalSym<i64, load, LOAD_I64>;
114def : LoadPatExternalSym<f32, load, LOAD_F32>;
115def : LoadPatExternalSym<f64, load, LOAD_F64>;
116
Dan Gohman4b9d7912015-12-15 22:01:29 +0000117
118// Select loads with just a constant offset.
Derek Schuff0f3bc0f2017-08-31 21:51:48 +0000119class LoadPatOffsetOnly<ValueType ty, PatFrag loadkind, I inst> :
120 Pat<(ty (loadkind imm:$off)), (inst 0, imm:$off, (CONST_I32 0))>;
121
122def : LoadPatOffsetOnly<i32, load, LOAD_I32>;
123def : LoadPatOffsetOnly<i64, load, LOAD_I64>;
124def : LoadPatOffsetOnly<f32, load, LOAD_F32>;
125def : LoadPatOffsetOnly<f64, load, LOAD_F64>;
126
127class LoadPatGlobalAddrOffOnly<ValueType ty, PatFrag loadkind, I inst> :
128 Pat<(ty (loadkind (WebAssemblywrapper tglobaladdr:$off))),
129 (inst 0, tglobaladdr:$off, (CONST_I32 0))>;
130
131def : LoadPatGlobalAddrOffOnly<i32, load, LOAD_I32>;
132def : LoadPatGlobalAddrOffOnly<i64, load, LOAD_I64>;
133def : LoadPatGlobalAddrOffOnly<f32, load, LOAD_F32>;
134def : LoadPatGlobalAddrOffOnly<f64, load, LOAD_F64>;
135
136class LoadPatExternSymOffOnly<ValueType ty, PatFrag loadkind, I inst> :
137 Pat<(ty (loadkind (WebAssemblywrapper texternalsym:$off))),
138 (inst 0, texternalsym:$off, (CONST_I32 0))>;
139def : LoadPatExternSymOffOnly<i32, load, LOAD_I32>;
140def : LoadPatExternSymOffOnly<i64, load, LOAD_I64>;
141def : LoadPatExternSymOffOnly<f32, load, LOAD_F32>;
142def : LoadPatExternSymOffOnly<f64, load, LOAD_F64>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000143
144let Defs = [ARGUMENTS] in {
145
JF Bastien73ff6af2015-08-31 22:24:11 +0000146// Extending load.
Derek Schuff885dc592017-10-05 21:18:42 +0000147def LOAD8_S_I32 : WebAssemblyLoad<I32, "i32.load8_s", 0x2c>;
148def LOAD8_U_I32 : WebAssemblyLoad<I32, "i32.load8_u", 0x2d>;
149def LOAD16_S_I32 : WebAssemblyLoad<I32, "i32.load16_s", 0x2e>;
150def LOAD16_U_I32 : WebAssemblyLoad<I32, "i32.load16_u", 0x2f>;
151def LOAD8_S_I64 : WebAssemblyLoad<I64, "i64.load8_s", 0x30>;
152def LOAD8_U_I64 : WebAssemblyLoad<I64, "i64.load8_u", 0x31>;
153def LOAD16_S_I64 : WebAssemblyLoad<I64, "i64.load16_s", 0x32>;
154def LOAD16_U_I64 : WebAssemblyLoad<I64, "i64.load16_u", 0x32>;
155def LOAD32_S_I64 : WebAssemblyLoad<I64, "i64.load32_s", 0x34>;
156def LOAD32_U_I64 : WebAssemblyLoad<I64, "i64.load32_u", 0x35>;
JF Bastien73ff6af2015-08-31 22:24:11 +0000157
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000158} // Defs = [ARGUMENTS]
159
Derek Schuff9d779522015-12-05 00:26:39 +0000160// Select extending loads with no constant offset.
Derek Schuff0f3bc0f2017-08-31 21:51:48 +0000161def : LoadPatNoOffset<i32, sextloadi8, LOAD8_S_I32>;
162def : LoadPatNoOffset<i32, zextloadi8, LOAD8_U_I32>;
163def : LoadPatNoOffset<i32, sextloadi16, LOAD16_S_I32>;
164def : LoadPatNoOffset<i32, zextloadi16, LOAD16_U_I32>;
165def : LoadPatNoOffset<i64, sextloadi8, LOAD8_S_I64>;
166def : LoadPatNoOffset<i64, zextloadi8, LOAD8_U_I64>;
167def : LoadPatNoOffset<i64, sextloadi16, LOAD16_S_I64>;
168def : LoadPatNoOffset<i64, zextloadi16, LOAD16_U_I64>;
169def : LoadPatNoOffset<i64, sextloadi32, LOAD32_S_I64>;
170def : LoadPatNoOffset<i64, zextloadi32, LOAD32_U_I64>;
Derek Schuff9d779522015-12-05 00:26:39 +0000171
Dan Gohman4b9d7912015-12-15 22:01:29 +0000172// Select extending loads with a constant offset.
Derek Schuff0f3bc0f2017-08-31 21:51:48 +0000173def : LoadPatImmOff<i32, sextloadi8, regPlusImm, LOAD8_S_I32>;
174def : LoadPatImmOff<i32, zextloadi8, regPlusImm, LOAD8_U_I32>;
175def : LoadPatImmOff<i32, sextloadi16, regPlusImm, LOAD16_S_I32>;
176def : LoadPatImmOff<i32, zextloadi16, regPlusImm, LOAD16_U_I32>;
177def : LoadPatImmOff<i64, sextloadi8, regPlusImm, LOAD8_S_I64>;
178def : LoadPatImmOff<i64, zextloadi8, regPlusImm, LOAD8_U_I64>;
179def : LoadPatImmOff<i64, sextloadi16, regPlusImm, LOAD16_S_I64>;
180def : LoadPatImmOff<i64, zextloadi16, regPlusImm, LOAD16_U_I64>;
181def : LoadPatImmOff<i64, sextloadi32, regPlusImm, LOAD32_S_I64>;
182def : LoadPatImmOff<i64, zextloadi32, regPlusImm, LOAD32_U_I64>;
183
184def : LoadPatImmOff<i32, sextloadi8, or_is_add, LOAD8_S_I32>;
185def : LoadPatImmOff<i32, zextloadi8, or_is_add, LOAD8_U_I32>;
186def : LoadPatImmOff<i32, sextloadi16, or_is_add, LOAD16_S_I32>;
187def : LoadPatImmOff<i32, zextloadi16, or_is_add, LOAD16_U_I32>;
188def : LoadPatImmOff<i64, sextloadi8, or_is_add, LOAD8_S_I64>;
189def : LoadPatImmOff<i64, zextloadi8, or_is_add, LOAD8_U_I64>;
190def : LoadPatImmOff<i64, sextloadi16, or_is_add, LOAD16_S_I64>;
191def : LoadPatImmOff<i64, zextloadi16, or_is_add, LOAD16_U_I64>;
192def : LoadPatImmOff<i64, sextloadi32, or_is_add, LOAD32_S_I64>;
193def : LoadPatImmOff<i64, zextloadi32, or_is_add, LOAD32_U_I64>;
194
195def : LoadPatGlobalAddr<i32, sextloadi8, LOAD8_S_I32>;
196def : LoadPatGlobalAddr<i32, zextloadi8, LOAD8_U_I32>;
197def : LoadPatGlobalAddr<i32, sextloadi16, LOAD16_S_I32>;
198def : LoadPatGlobalAddr<i32, zextloadi8, LOAD16_U_I32>;
199
200def : LoadPatGlobalAddr<i64, sextloadi8, LOAD8_S_I64>;
201def : LoadPatGlobalAddr<i64, zextloadi8, LOAD8_U_I64>;
202def : LoadPatGlobalAddr<i64, sextloadi16, LOAD16_S_I64>;
203def : LoadPatGlobalAddr<i64, zextloadi16, LOAD16_U_I64>;
204def : LoadPatGlobalAddr<i64, sextloadi32, LOAD32_S_I64>;
205def : LoadPatGlobalAddr<i64, zextloadi32, LOAD32_U_I64>;
206
207def : LoadPatExternalSym<i32, sextloadi8, LOAD8_S_I32>;
208def : LoadPatExternalSym<i32, zextloadi8, LOAD8_U_I32>;
209def : LoadPatExternalSym<i32, sextloadi16, LOAD16_S_I32>;
210def : LoadPatExternalSym<i32, zextloadi16, LOAD16_U_I32>;
211def : LoadPatExternalSym<i64, sextloadi8, LOAD8_S_I64>;
212def : LoadPatExternalSym<i64, zextloadi8, LOAD8_U_I64>;
213def : LoadPatExternalSym<i64, sextloadi16, LOAD16_S_I64>;
214def : LoadPatExternalSym<i64, zextloadi16, LOAD16_U_I64>;
215def : LoadPatExternalSym<i64, sextloadi32, LOAD32_S_I64>;
216def : LoadPatExternalSym<i64, zextloadi32, LOAD32_U_I64>;
217
Dan Gohman4b9d7912015-12-15 22:01:29 +0000218
219// Select extending loads with just a constant offset.
Derek Schuff0f3bc0f2017-08-31 21:51:48 +0000220def : LoadPatOffsetOnly<i32, sextloadi8, LOAD8_S_I32>;
221def : LoadPatOffsetOnly<i32, zextloadi8, LOAD8_U_I32>;
222def : LoadPatOffsetOnly<i32, sextloadi16, LOAD16_S_I32>;
223def : LoadPatOffsetOnly<i32, zextloadi16, LOAD16_U_I32>;
224
225def : LoadPatOffsetOnly<i64, sextloadi8, LOAD8_S_I64>;
226def : LoadPatOffsetOnly<i64, zextloadi8, LOAD8_U_I64>;
227def : LoadPatOffsetOnly<i64, sextloadi16, LOAD16_S_I64>;
228def : LoadPatOffsetOnly<i64, zextloadi16, LOAD16_U_I64>;
229def : LoadPatOffsetOnly<i64, sextloadi32, LOAD32_S_I64>;
230def : LoadPatOffsetOnly<i64, zextloadi32, LOAD32_U_I64>;
231
232def : LoadPatGlobalAddrOffOnly<i32, sextloadi8, LOAD8_S_I32>;
233def : LoadPatGlobalAddrOffOnly<i32, zextloadi8, LOAD8_U_I32>;
234def : LoadPatGlobalAddrOffOnly<i32, sextloadi16, LOAD16_S_I32>;
235def : LoadPatGlobalAddrOffOnly<i32, zextloadi16, LOAD16_U_I32>;
236def : LoadPatGlobalAddrOffOnly<i64, sextloadi8, LOAD8_S_I64>;
237def : LoadPatGlobalAddrOffOnly<i64, zextloadi8, LOAD8_U_I64>;
238def : LoadPatGlobalAddrOffOnly<i64, sextloadi16, LOAD16_S_I64>;
239def : LoadPatGlobalAddrOffOnly<i64, zextloadi16, LOAD16_U_I64>;
240def : LoadPatGlobalAddrOffOnly<i64, sextloadi32, LOAD32_S_I64>;
241def : LoadPatGlobalAddrOffOnly<i64, zextloadi32, LOAD32_U_I64>;
242
243def : LoadPatExternSymOffOnly<i32, sextloadi8, LOAD8_S_I32>;
244def : LoadPatExternSymOffOnly<i32, zextloadi8, LOAD8_U_I32>;
245def : LoadPatExternSymOffOnly<i32, sextloadi16, LOAD16_S_I32>;
246def : LoadPatExternSymOffOnly<i32, zextloadi16, LOAD16_U_I32>;
247def : LoadPatExternSymOffOnly<i64, sextloadi8, LOAD8_S_I64>;
248def : LoadPatExternSymOffOnly<i64, zextloadi8, LOAD8_U_I64>;
249def : LoadPatExternSymOffOnly<i64, sextloadi16, LOAD16_S_I64>;
250def : LoadPatExternSymOffOnly<i64, zextloadi16, LOAD16_U_I64>;
251def : LoadPatExternSymOffOnly<i64, sextloadi32, LOAD32_S_I64>;
252def : LoadPatExternSymOffOnly<i64, zextloadi32, LOAD32_U_I64>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000253
254// Resolve "don't care" extending loads to zero-extending loads. This is
255// somewhat arbitrary, but zero-extending is conceptually simpler.
256
257// Select "don't care" extending loads with no constant offset.
Derek Schuff0f3bc0f2017-08-31 21:51:48 +0000258def : LoadPatNoOffset<i32, extloadi8, LOAD8_U_I32>;
259def : LoadPatNoOffset<i32, extloadi16, LOAD16_U_I32>;
260def : LoadPatNoOffset<i64, extloadi8, LOAD8_U_I64>;
261def : LoadPatNoOffset<i64, extloadi16, LOAD16_U_I64>;
262def : LoadPatNoOffset<i64, extloadi32, LOAD32_U_I64>;
263
Dan Gohman4b9d7912015-12-15 22:01:29 +0000264// Select "don't care" extending loads with a constant offset.
Derek Schuff0f3bc0f2017-08-31 21:51:48 +0000265def : LoadPatImmOff<i32, extloadi8, regPlusImm, LOAD8_U_I32>;
266def : LoadPatImmOff<i32, extloadi16, regPlusImm, LOAD16_U_I32>;
267def : LoadPatImmOff<i64, extloadi8, regPlusImm, LOAD8_U_I64>;
268def : LoadPatImmOff<i64, extloadi16, regPlusImm, LOAD16_U_I64>;
269def : LoadPatImmOff<i64, extloadi32, regPlusImm, LOAD32_U_I64>;
270def : LoadPatImmOff<i32, extloadi8, or_is_add, LOAD8_U_I32>;
271def : LoadPatImmOff<i32, extloadi16, or_is_add, LOAD16_U_I32>;
272def : LoadPatImmOff<i64, extloadi8, or_is_add, LOAD8_U_I64>;
273def : LoadPatImmOff<i64, extloadi16, or_is_add, LOAD16_U_I64>;
274def : LoadPatImmOff<i64, extloadi32, or_is_add, LOAD32_U_I64>;
275def : LoadPatGlobalAddr<i32, extloadi8, LOAD8_U_I32>;
276def : LoadPatGlobalAddr<i32, extloadi16, LOAD16_U_I32>;
277def : LoadPatGlobalAddr<i64, extloadi8, LOAD8_U_I64>;
278def : LoadPatGlobalAddr<i64, extloadi16, LOAD16_U_I64>;
279def : LoadPatGlobalAddr<i64, extloadi32, LOAD32_U_I64>;
280def : LoadPatExternalSym<i32, extloadi8, LOAD8_U_I32>;
281def : LoadPatExternalSym<i32, extloadi16, LOAD16_U_I32>;
282def : LoadPatExternalSym<i64, extloadi8, LOAD8_U_I64>;
283def : LoadPatExternalSym<i64, extloadi16, LOAD16_U_I64>;
284def : LoadPatExternalSym<i64, extloadi32, LOAD32_U_I64>;
285
Dan Gohman4b9d7912015-12-15 22:01:29 +0000286// Select "don't care" extending loads with just a constant offset.
Derek Schuff0f3bc0f2017-08-31 21:51:48 +0000287def : LoadPatOffsetOnly<i32, extloadi8, LOAD8_U_I32>;
288def : LoadPatOffsetOnly<i32, extloadi16, LOAD16_U_I32>;
289def : LoadPatOffsetOnly<i64, extloadi8, LOAD8_U_I64>;
290def : LoadPatOffsetOnly<i64, extloadi16, LOAD16_U_I64>;
291def : LoadPatOffsetOnly<i64, extloadi32, LOAD32_U_I64>;
292def : LoadPatGlobalAddrOffOnly<i32, extloadi8, LOAD8_U_I32>;
293def : LoadPatGlobalAddrOffOnly<i32, extloadi16, LOAD16_U_I32>;
294def : LoadPatGlobalAddrOffOnly<i64, extloadi8, LOAD8_U_I64>;
295def : LoadPatGlobalAddrOffOnly<i64, extloadi16, LOAD16_U_I64>;
296def : LoadPatGlobalAddrOffOnly<i64, extloadi32, LOAD32_U_I64>;
297def : LoadPatExternSymOffOnly<i32, extloadi8, LOAD8_U_I32>;
298def : LoadPatExternSymOffOnly<i32, extloadi16, LOAD16_U_I32>;
299def : LoadPatExternSymOffOnly<i64, extloadi8, LOAD8_U_I64>;
300def : LoadPatExternSymOffOnly<i64, extloadi16, LOAD16_U_I64>;
301def : LoadPatExternSymOffOnly<i64, extloadi32, LOAD32_U_I64>;
302
Dan Gohman4b9d7912015-12-15 22:01:29 +0000303
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000304let Defs = [ARGUMENTS] in {
305
JF Bastien73ff6af2015-08-31 22:24:11 +0000306// Basic store.
307// Note: WebAssembly inverts SelectionDAG's usual operand order.
Dan Gohman00d734d2016-12-23 03:23:52 +0000308def STORE_I32 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000309 I32:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000310 "i32.store\t${off}(${addr})${p2align}, $val", 0x36>;
Dan Gohman00d734d2016-12-23 03:23:52 +0000311def STORE_I64 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000312 I64:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000313 "i64.store\t${off}(${addr})${p2align}, $val", 0x37>;
Dan Gohman00d734d2016-12-23 03:23:52 +0000314def STORE_F32 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000315 F32:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000316 "f32.store\t${off}(${addr})${p2align}, $val", 0x38>;
Dan Gohman00d734d2016-12-23 03:23:52 +0000317def STORE_F64 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000318 F64:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000319 "f64.store\t${off}(${addr})${p2align}, $val", 0x39>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000320
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000321} // Defs = [ARGUMENTS]
322
Dan Gohman4b9d7912015-12-15 22:01:29 +0000323// Select stores with no constant offset.
Dan Gohman48abaa92016-10-25 00:17:11 +0000324def : Pat<(store I32:$val, I32:$addr), (STORE_I32 0, 0, I32:$addr, I32:$val)>;
325def : Pat<(store I64:$val, I32:$addr), (STORE_I64 0, 0, I32:$addr, I64:$val)>;
326def : Pat<(store F32:$val, I32:$addr), (STORE_F32 0, 0, I32:$addr, F32:$val)>;
327def : Pat<(store F64:$val, I32:$addr), (STORE_F64 0, 0, I32:$addr, F64:$val)>;
Derek Schuff9d779522015-12-05 00:26:39 +0000328
Dan Gohman4b9d7912015-12-15 22:01:29 +0000329// Select stores with a constant offset.
Dan Gohmanf225a632016-01-11 22:05:44 +0000330def : Pat<(store I32:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000331 (STORE_I32 0, imm:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000332def : Pat<(store I64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000333 (STORE_I64 0, imm:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000334def : Pat<(store F32:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000335 (STORE_F32 0, imm:$off, I32:$addr, F32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000336def : Pat<(store F64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000337 (STORE_F64 0, imm:$off, I32:$addr, F64:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000338def : Pat<(store I32:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000339 (STORE_I32 0, imm:$off, I32:$addr, I32:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000340def : Pat<(store I64:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000341 (STORE_I64 0, imm:$off, I32:$addr, I64:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000342def : Pat<(store F32:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000343 (STORE_F32 0, imm:$off, I32:$addr, F32:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000344def : Pat<(store F64:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000345 (STORE_F64 0, imm:$off, I32:$addr, F64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000346def : Pat<(store I32:$val, (regPlusGA I32:$addr,
347 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000348 (STORE_I32 0, tglobaladdr:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000349def : Pat<(store I64:$val, (regPlusGA I32:$addr,
350 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000351 (STORE_I64 0, tglobaladdr:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000352def : Pat<(store F32:$val, (regPlusGA I32:$addr,
353 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000354 (STORE_F32 0, tglobaladdr:$off, I32:$addr, F32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000355def : Pat<(store F64:$val, (regPlusGA I32:$addr,
356 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000357 (STORE_F64 0, tglobaladdr:$off, I32:$addr, F64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000358def : Pat<(store I32:$val, (add I32:$addr,
359 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000360 (STORE_I32 0, texternalsym:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000361def : Pat<(store I64:$val, (add I32:$addr,
362 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000363 (STORE_I64 0, texternalsym:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000364def : Pat<(store F32:$val, (add I32:$addr,
365 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000366 (STORE_F32 0, texternalsym:$off, I32:$addr, F32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000367def : Pat<(store F64:$val, (add I32:$addr,
368 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000369 (STORE_F64 0, texternalsym:$off, I32:$addr, F64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000370
371// Select stores with just a constant offset.
372def : Pat<(store I32:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000373 (STORE_I32 0, imm:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000374def : Pat<(store I64:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000375 (STORE_I64 0, imm:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000376def : Pat<(store F32:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000377 (STORE_F32 0, imm:$off, (CONST_I32 0), F32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000378def : Pat<(store F64:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000379 (STORE_F64 0, imm:$off, (CONST_I32 0), F64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000380def : Pat<(store I32:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000381 (STORE_I32 0, tglobaladdr:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000382def : Pat<(store I64:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000383 (STORE_I64 0, tglobaladdr:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000384def : Pat<(store F32:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000385 (STORE_F32 0, tglobaladdr:$off, (CONST_I32 0), F32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000386def : Pat<(store F64:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000387 (STORE_F64 0, tglobaladdr:$off, (CONST_I32 0), F64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000388def : Pat<(store I32:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000389 (STORE_I32 0, texternalsym:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000390def : Pat<(store I64:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000391 (STORE_I64 0, texternalsym:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000392def : Pat<(store F32:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000393 (STORE_F32 0, texternalsym:$off, (CONST_I32 0), F32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000394def : Pat<(store F64:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000395 (STORE_F64 0, texternalsym:$off, (CONST_I32 0), F64:$val)>;
JF Bastien73ff6af2015-08-31 22:24:11 +0000396
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000397let Defs = [ARGUMENTS] in {
398
JF Bastien73ff6af2015-08-31 22:24:11 +0000399// Truncating store.
Dan Gohman00d734d2016-12-23 03:23:52 +0000400def STORE8_I32 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000401 I32:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000402 "i32.store8\t${off}(${addr})${p2align}, $val", 0x3a>;
Dan Gohman00d734d2016-12-23 03:23:52 +0000403def STORE16_I32 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000404 I32:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000405 "i32.store16\t${off}(${addr})${p2align}, $val", 0x3b>;
Dan Gohman00d734d2016-12-23 03:23:52 +0000406def STORE8_I64 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000407 I64:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000408 "i64.store8\t${off}(${addr})${p2align}, $val", 0x3c>;
Dan Gohman00d734d2016-12-23 03:23:52 +0000409def STORE16_I64 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000410 I64:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000411 "i64.store16\t${off}(${addr})${p2align}, $val", 0x3d>;
Dan Gohman00d734d2016-12-23 03:23:52 +0000412def STORE32_I64 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000413 I64:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000414 "i64.store32\t${off}(${addr})${p2align}, $val", 0x3e>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000415
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000416} // Defs = [ARGUMENTS]
417
Dan Gohman4b9d7912015-12-15 22:01:29 +0000418// Select truncating stores with no constant offset.
Dan Gohman7054ac12015-11-23 21:16:35 +0000419def : Pat<(truncstorei8 I32:$val, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000420 (STORE8_I32 0, 0, I32:$addr, I32:$val)>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000421def : Pat<(truncstorei16 I32:$val, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000422 (STORE16_I32 0, 0, I32:$addr, I32:$val)>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000423def : Pat<(truncstorei8 I64:$val, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000424 (STORE8_I64 0, 0, I32:$addr, I64:$val)>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000425def : Pat<(truncstorei16 I64:$val, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000426 (STORE16_I64 0, 0, I32:$addr, I64:$val)>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000427def : Pat<(truncstorei32 I64:$val, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000428 (STORE32_I64 0, 0, I32:$addr, I64:$val)>;
JF Bastien73ff6af2015-08-31 22:24:11 +0000429
Dan Gohman4b9d7912015-12-15 22:01:29 +0000430// Select truncating stores with a constant offset.
Dan Gohmanf225a632016-01-11 22:05:44 +0000431def : Pat<(truncstorei8 I32:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000432 (STORE8_I32 0, imm:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000433def : Pat<(truncstorei16 I32:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000434 (STORE16_I32 0, imm:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000435def : Pat<(truncstorei8 I64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000436 (STORE8_I64 0, imm:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000437def : Pat<(truncstorei16 I64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000438 (STORE16_I64 0, imm:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000439def : Pat<(truncstorei32 I64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000440 (STORE32_I64 0, imm:$off, I32:$addr, I64:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000441def : Pat<(truncstorei8 I32:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000442 (STORE8_I32 0, imm:$off, I32:$addr, I32:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000443def : Pat<(truncstorei16 I32:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000444 (STORE16_I32 0, imm:$off, I32:$addr, I32:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000445def : Pat<(truncstorei8 I64:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000446 (STORE8_I64 0, imm:$off, I32:$addr, I64:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000447def : Pat<(truncstorei16 I64:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000448 (STORE16_I64 0, imm:$off, I32:$addr, I64:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000449def : Pat<(truncstorei32 I64:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000450 (STORE32_I64 0, imm:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000451def : Pat<(truncstorei8 I32:$val,
452 (regPlusGA I32:$addr,
453 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000454 (STORE8_I32 0, tglobaladdr:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000455def : Pat<(truncstorei16 I32:$val,
456 (regPlusGA I32:$addr,
457 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000458 (STORE16_I32 0, tglobaladdr:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000459def : Pat<(truncstorei8 I64:$val,
460 (regPlusGA I32:$addr,
461 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000462 (STORE8_I64 0, tglobaladdr:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000463def : Pat<(truncstorei16 I64:$val,
464 (regPlusGA I32:$addr,
465 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000466 (STORE16_I64 0, tglobaladdr:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000467def : Pat<(truncstorei32 I64:$val,
468 (regPlusGA I32:$addr,
469 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000470 (STORE32_I64 0, tglobaladdr:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000471def : Pat<(truncstorei8 I32:$val, (add I32:$addr,
472 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000473 (STORE8_I32 0, texternalsym:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000474def : Pat<(truncstorei16 I32:$val,
475 (add I32:$addr,
476 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000477 (STORE16_I32 0, texternalsym:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000478def : Pat<(truncstorei8 I64:$val,
479 (add I32:$addr,
480 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000481 (STORE8_I64 0, texternalsym:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000482def : Pat<(truncstorei16 I64:$val,
483 (add I32:$addr,
484 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000485 (STORE16_I64 0, texternalsym:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000486def : Pat<(truncstorei32 I64:$val,
487 (add I32:$addr,
488 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000489 (STORE32_I64 0, texternalsym:$off, I32:$addr, I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000490
491// Select truncating stores with just a constant offset.
492def : Pat<(truncstorei8 I32:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000493 (STORE8_I32 0, imm:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000494def : Pat<(truncstorei16 I32:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000495 (STORE16_I32 0, imm:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000496def : Pat<(truncstorei8 I64:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000497 (STORE8_I64 0, imm:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000498def : Pat<(truncstorei16 I64:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000499 (STORE16_I64 0, imm:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000500def : Pat<(truncstorei32 I64:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000501 (STORE32_I64 0, imm:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000502def : Pat<(truncstorei8 I32:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000503 (STORE8_I32 0, tglobaladdr:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000504def : Pat<(truncstorei16 I32:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000505 (STORE16_I32 0, tglobaladdr:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000506def : Pat<(truncstorei8 I64:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000507 (STORE8_I64 0, tglobaladdr:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000508def : Pat<(truncstorei16 I64:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000509 (STORE16_I64 0, tglobaladdr:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000510def : Pat<(truncstorei32 I64:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000511 (STORE32_I64 0, tglobaladdr:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000512def : Pat<(truncstorei8 I32:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000513 (STORE8_I32 0, texternalsym:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000514def : Pat<(truncstorei16 I32:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000515 (STORE16_I32 0, texternalsym:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000516def : Pat<(truncstorei8 I64:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000517 (STORE8_I64 0, texternalsym:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000518def : Pat<(truncstorei16 I64:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000519 (STORE16_I64 0, texternalsym:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000520def : Pat<(truncstorei32 I64:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000521 (STORE32_I64 0, texternalsym:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000522
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000523let Defs = [ARGUMENTS] in {
524
Derek Schuff31680dd2016-05-02 17:25:22 +0000525// Current memory size.
Dan Gohman54649412018-01-23 17:02:02 +0000526def MEM_SIZE_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
527 [(set I32:$dst, (int_wasm_mem_size (i32 imm:$flags)))],
528 "mem.size\t$dst, $flags", 0x3f>,
529 Requires<[HasAddr32]>;
Dan Gohmanf50d9642016-10-25 16:55:52 +0000530def CURRENT_MEMORY_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
531 [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000532 "current_memory\t$dst", 0x3f>,
Derek Schuff31680dd2016-05-02 17:25:22 +0000533 Requires<[HasAddr32]>;
Dan Gohmanbaba8c62015-10-02 20:10:26 +0000534
Dan Gohmand7ffb912015-11-05 20:16:59 +0000535// Grow memory.
Dan Gohman54649412018-01-23 17:02:02 +0000536def MEM_GROW_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
537 [(set I32:$dst,
538 (int_wasm_mem_grow (i32 imm:$flags), I32:$delta))],
539 "mem.grow\t$dst, $flags, $delta", 0x3f>,
540 Requires<[HasAddr32]>;
Dan Gohman73e3aaa2017-01-18 01:02:45 +0000541def GROW_MEMORY_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
Dan Gohmanf50d9642016-10-25 16:55:52 +0000542 [],
Dan Gohman73e3aaa2017-01-18 01:02:45 +0000543 "grow_memory\t$dst, $delta", 0x40>,
Dan Gohmand7ffb912015-11-05 20:16:59 +0000544 Requires<[HasAddr32]>;
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000545
546} // Defs = [ARGUMENTS]
Dan Gohmanf50d9642016-10-25 16:55:52 +0000547
548def : Pat<(int_wasm_current_memory),
549 (CURRENT_MEMORY_I32 0)>;
550def : Pat<(int_wasm_grow_memory I32:$delta),
551 (GROW_MEMORY_I32 0, $delta)>;