blob: 096d1875492b82f7d6573ebde9d8ab5557387a82 [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),
29 [{ return N->getFlags()->hasNoUnsignedWrap(); }]>;
30
Dan Gohmanf225a632016-01-11 22:05:44 +000031// GlobalAddresses are conceptually unsigned values, so we can also fold them
32// into immediate values as long as their offsets are non-negative.
33def regPlusGA : PatFrag<(ops node:$addr, node:$off),
34 (add node:$addr, node:$off),
35 [{
36 return N->getFlags()->hasNoUnsignedWrap() ||
37 (N->getOperand(1)->getOpcode() == WebAssemblyISD::Wrapper &&
38 isa<GlobalAddressSDNode>(N->getOperand(1)->getOperand(0)) &&
39 cast<GlobalAddressSDNode>(N->getOperand(1)->getOperand(0))
40 ->getOffset() >= 0);
41}]>;
42
43// We don't need a regPlusES because external symbols never have constant
44// offsets folded into them, so we can just use add.
45
Dan Gohmanfb3e0592015-11-25 19:36:19 +000046let Defs = [ARGUMENTS] in {
47
JF Bastien73ff6af2015-08-31 22:24:11 +000048// Basic load.
Dan Gohmanbb372242016-01-26 03:39:31 +000049def LOAD_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
50 P2Align:$p2align), [],
51 "i32.load\t$dst, ${off}(${addr})${p2align}">;
52def LOAD_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
53 P2Align:$p2align), [],
54 "i64.load\t$dst, ${off}(${addr})${p2align}">;
55def LOAD_F32 : I<(outs F32:$dst), (ins i32imm:$off, I32:$addr,
56 P2Align:$p2align), [],
57 "f32.load\t$dst, ${off}(${addr})${p2align}">;
58def LOAD_F64 : I<(outs F64:$dst), (ins i32imm:$off, I32:$addr,
59 P2Align:$p2align), [],
60 "f64.load\t$dst, ${off}(${addr})${p2align}">;
JF Bastien73ff6af2015-08-31 22:24:11 +000061
Dan Gohman4b9d7912015-12-15 22:01:29 +000062} // Defs = [ARGUMENTS]
63
64// Select loads with no constant offset.
Dan Gohmanbb372242016-01-26 03:39:31 +000065def : Pat<(i32 (load I32:$addr)), (LOAD_I32 0, $addr, 0)>;
66def : Pat<(i64 (load I32:$addr)), (LOAD_I64 0, $addr, 0)>;
67def : Pat<(f32 (load I32:$addr)), (LOAD_F32 0, $addr, 0)>;
68def : Pat<(f64 (load I32:$addr)), (LOAD_F64 0, $addr, 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +000069
70// Select loads with a constant offset.
Dan Gohmanf225a632016-01-11 22:05:44 +000071def : Pat<(i32 (load (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +000072 (LOAD_I32 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000073def : Pat<(i64 (load (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +000074 (LOAD_I64 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000075def : Pat<(f32 (load (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +000076 (LOAD_F32 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000077def : Pat<(f64 (load (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +000078 (LOAD_F64 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000079def : Pat<(i32 (load (regPlusGA I32:$addr,
80 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +000081 (LOAD_I32 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000082def : Pat<(i64 (load (regPlusGA I32:$addr,
83 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +000084 (LOAD_I64 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000085def : Pat<(f32 (load (regPlusGA I32:$addr,
86 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +000087 (LOAD_F32 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000088def : Pat<(f64 (load (regPlusGA I32:$addr,
89 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +000090 (LOAD_F64 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000091def : Pat<(i32 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +000092 (LOAD_I32 texternalsym:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000093def : Pat<(i64 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +000094 (LOAD_I64 texternalsym:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000095def : Pat<(f32 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +000096 (LOAD_F32 texternalsym:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000097def : Pat<(f64 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +000098 (LOAD_F64 texternalsym:$off, $addr, 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +000099
100// Select loads with just a constant offset.
Dan Gohmanbb372242016-01-26 03:39:31 +0000101def : Pat<(i32 (load imm:$off)), (LOAD_I32 imm:$off, (CONST_I32 0), 0)>;
102def : Pat<(i64 (load imm:$off)), (LOAD_I64 imm:$off, (CONST_I32 0), 0)>;
103def : Pat<(f32 (load imm:$off)), (LOAD_F32 imm:$off, (CONST_I32 0), 0)>;
104def : Pat<(f64 (load imm:$off)), (LOAD_F64 imm:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000105def : Pat<(i32 (load (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000106 (LOAD_I32 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000107def : Pat<(i64 (load (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000108 (LOAD_I64 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000109def : Pat<(f32 (load (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000110 (LOAD_F32 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000111def : Pat<(f64 (load (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000112 (LOAD_F64 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000113def : Pat<(i32 (load (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000114 (LOAD_I32 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000115def : Pat<(i64 (load (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000116 (LOAD_I64 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000117def : Pat<(f32 (load (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000118 (LOAD_F32 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000119def : Pat<(f64 (load (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000120 (LOAD_F64 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000121
122let Defs = [ARGUMENTS] in {
123
JF Bastien73ff6af2015-08-31 22:24:11 +0000124// Extending load.
Dan Gohmanbb372242016-01-26 03:39:31 +0000125def LOAD8_S_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
126 P2Align:$p2align), [],
127 "i32.load8_s\t$dst, ${off}(${addr})${p2align}">;
128def LOAD8_U_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
129 P2Align:$p2align), [],
130 "i32.load8_u\t$dst, ${off}(${addr})${p2align}">;
131def LOAD16_S_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
132 P2Align:$p2align), [],
133 "i32.load16_s\t$dst, ${off}(${addr})${p2align}">;
134def LOAD16_U_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
135 P2Align:$p2align), [],
136 "i32.load16_u\t$dst, ${off}(${addr})${p2align}">;
137def LOAD8_S_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
138 P2Align:$p2align), [],
139 "i64.load8_s\t$dst, ${off}(${addr})${p2align}">;
140def LOAD8_U_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
141 P2Align:$p2align), [],
142 "i64.load8_u\t$dst, ${off}(${addr})${p2align}">;
143def LOAD16_S_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
144 P2Align:$p2align), [],
145 "i64.load16_s\t$dst, ${off}(${addr})${p2align}">;
146def LOAD16_U_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
147 P2Align:$p2align), [],
148 "i64.load16_u\t$dst, ${off}(${addr})${p2align}">;
149def LOAD32_S_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
150 P2Align:$p2align), [],
151 "i64.load32_s\t$dst, ${off}(${addr})${p2align}">;
152def LOAD32_U_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
153 P2Align:$p2align), [],
154 "i64.load32_u\t$dst, ${off}(${addr})${p2align}">;
JF Bastien73ff6af2015-08-31 22:24:11 +0000155
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000156} // Defs = [ARGUMENTS]
157
Derek Schuff9d779522015-12-05 00:26:39 +0000158// Select extending loads with no constant offset.
Dan Gohmanbb372242016-01-26 03:39:31 +0000159def : Pat<(i32 (sextloadi8 I32:$addr)), (LOAD8_S_I32 0, $addr, 0)>;
160def : Pat<(i32 (zextloadi8 I32:$addr)), (LOAD8_U_I32 0, $addr, 0)>;
161def : Pat<(i32 (sextloadi16 I32:$addr)), (LOAD16_S_I32 0, $addr, 0)>;
162def : Pat<(i32 (zextloadi16 I32:$addr)), (LOAD16_U_I32 0, $addr, 0)>;
163def : Pat<(i64 (sextloadi8 I32:$addr)), (LOAD8_S_I64 0, $addr, 0)>;
164def : Pat<(i64 (zextloadi8 I32:$addr)), (LOAD8_U_I64 0, $addr, 0)>;
165def : Pat<(i64 (sextloadi16 I32:$addr)), (LOAD16_S_I64 0, $addr, 0)>;
166def : Pat<(i64 (zextloadi16 I32:$addr)), (LOAD16_U_I64 0, $addr, 0)>;
167def : Pat<(i64 (sextloadi32 I32:$addr)), (LOAD32_S_I64 0, $addr, 0)>;
168def : Pat<(i64 (zextloadi32 I32:$addr)), (LOAD32_U_I64 0, $addr, 0)>;
Derek Schuff9d779522015-12-05 00:26:39 +0000169
Dan Gohman4b9d7912015-12-15 22:01:29 +0000170// Select extending loads with a constant offset.
Dan Gohmanf225a632016-01-11 22:05:44 +0000171def : Pat<(i32 (sextloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000172 (LOAD8_S_I32 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000173def : Pat<(i32 (zextloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000174 (LOAD8_U_I32 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000175def : Pat<(i32 (sextloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000176 (LOAD16_S_I32 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000177def : Pat<(i32 (zextloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000178 (LOAD16_U_I32 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000179def : Pat<(i64 (sextloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000180 (LOAD8_S_I64 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000181def : Pat<(i64 (zextloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000182 (LOAD8_U_I64 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000183def : Pat<(i64 (sextloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000184 (LOAD16_S_I64 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000185def : Pat<(i64 (zextloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000186 (LOAD16_U_I64 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000187def : Pat<(i64 (sextloadi32 (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000188 (LOAD32_S_I64 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000189def : Pat<(i64 (zextloadi32 (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000190 (LOAD32_U_I64 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000191def : Pat<(i32 (sextloadi8 (regPlusGA I32:$addr,
192 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000193 (LOAD8_S_I32 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000194def : Pat<(i32 (zextloadi8 (regPlusGA I32:$addr,
195 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000196 (LOAD8_U_I32 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000197def : Pat<(i32 (sextloadi16 (regPlusGA I32:$addr,
198 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000199 (LOAD16_S_I32 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000200def : Pat<(i32 (zextloadi16 (regPlusGA I32:$addr,
201 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000202 (LOAD16_U_I32 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000203def : Pat<(i64 (sextloadi8 (regPlusGA I32:$addr,
204 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000205 (LOAD8_S_I64 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000206def : Pat<(i64 (zextloadi8 (regPlusGA I32:$addr,
207 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000208 (LOAD8_U_I64 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000209def : Pat<(i64 (sextloadi16 (regPlusGA I32:$addr,
210 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000211 (LOAD16_S_I64 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000212def : Pat<(i64 (zextloadi16 (regPlusGA I32:$addr,
213 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000214 (LOAD16_U_I64 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000215def : Pat<(i64 (sextloadi32 (regPlusGA I32:$addr,
216 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000217 (LOAD32_S_I64 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000218def : Pat<(i64 (zextloadi32 (regPlusGA I32:$addr,
219 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000220 (LOAD32_U_I64 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000221def : Pat<(i32 (sextloadi8 (add I32:$addr,
222 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000223 (LOAD8_S_I32 texternalsym:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000224def : Pat<(i32 (zextloadi8 (add I32:$addr,
225 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000226 (LOAD8_U_I32 texternalsym:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000227def : Pat<(i32 (sextloadi16 (add I32:$addr,
228 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000229 (LOAD16_S_I32 texternalsym:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000230def : Pat<(i32 (zextloadi16 (add I32:$addr,
231 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000232 (LOAD16_U_I32 texternalsym:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000233def : Pat<(i64 (sextloadi8 (add I32:$addr,
234 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000235 (LOAD8_S_I64 texternalsym:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000236def : Pat<(i64 (zextloadi8 (add I32:$addr,
237 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000238 (LOAD8_U_I64 texternalsym:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000239def : Pat<(i64 (sextloadi16 (add I32:$addr,
240 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000241 (LOAD16_S_I64 texternalsym:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000242def : Pat<(i64 (zextloadi16 (add I32:$addr,
243 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000244 (LOAD16_U_I64 texternalsym:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000245def : Pat<(i64 (sextloadi32 (add I32:$addr,
246 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000247 (LOAD32_S_I64 texternalsym:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000248def : Pat<(i64 (zextloadi32 (add I32:$addr,
249 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000250 (LOAD32_U_I64 texternalsym:$off, $addr, 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000251
252// Select extending loads with just a constant offset.
Dan Gohmanbb372242016-01-26 03:39:31 +0000253def : Pat<(i32 (sextloadi8 imm:$off)),
254 (LOAD8_S_I32 imm:$off, (CONST_I32 0), 0)>;
255def : Pat<(i32 (zextloadi8 imm:$off)),
256 (LOAD8_U_I32 imm:$off, (CONST_I32 0), 0)>;
257def : Pat<(i32 (sextloadi16 imm:$off)),
258 (LOAD16_S_I32 imm:$off, (CONST_I32 0), 0)>;
259def : Pat<(i32 (zextloadi16 imm:$off)),
260 (LOAD16_U_I32 imm:$off, (CONST_I32 0), 0)>;
261def : Pat<(i64 (sextloadi8 imm:$off)),
262 (LOAD8_S_I64 imm:$off, (CONST_I32 0), 0)>;
263def : Pat<(i64 (zextloadi8 imm:$off)),
264 (LOAD8_U_I64 imm:$off, (CONST_I32 0), 0)>;
265def : Pat<(i64 (sextloadi16 imm:$off)),
266 (LOAD16_S_I64 imm:$off, (CONST_I32 0), 0)>;
267def : Pat<(i64 (zextloadi16 imm:$off)),
268 (LOAD16_U_I64 imm:$off, (CONST_I32 0), 0)>;
269def : Pat<(i64 (sextloadi32 imm:$off)),
270 (LOAD32_S_I64 imm:$off, (CONST_I32 0), 0)>;
271def : Pat<(i64 (zextloadi32 imm:$off)),
272 (LOAD32_U_I64 imm:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000273def : Pat<(i32 (sextloadi8 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000274 (LOAD8_S_I32 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000275def : Pat<(i32 (zextloadi8 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000276 (LOAD8_U_I32 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000277def : Pat<(i32 (sextloadi16 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000278 (LOAD16_S_I32 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000279def : Pat<(i32 (zextloadi16 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000280 (LOAD16_U_I32 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000281def : Pat<(i64 (sextloadi8 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000282 (LOAD8_S_I64 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000283def : Pat<(i64 (zextloadi8 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000284 (LOAD8_U_I64 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000285def : Pat<(i64 (sextloadi16 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000286 (LOAD16_S_I64 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000287def : Pat<(i64 (zextloadi16 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000288 (LOAD16_U_I64 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000289def : Pat<(i64 (sextloadi32 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000290 (LOAD32_S_I64 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000291def : Pat<(i64 (zextloadi32 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000292 (LOAD32_U_I64 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000293def : Pat<(i32 (sextloadi8 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000294 (LOAD8_S_I32 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000295def : Pat<(i32 (zextloadi8 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000296 (LOAD8_U_I32 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000297def : Pat<(i32 (sextloadi16 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000298 (LOAD16_S_I32 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000299def : Pat<(i32 (zextloadi16 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000300 (LOAD16_U_I32 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000301def : Pat<(i64 (sextloadi8 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000302 (LOAD8_S_I64 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000303def : Pat<(i64 (zextloadi8 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000304 (LOAD8_U_I64 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000305def : Pat<(i64 (sextloadi16 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000306 (LOAD16_S_I64 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000307def : Pat<(i64 (zextloadi16 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000308 (LOAD16_U_I64 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000309def : Pat<(i64 (sextloadi32 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000310 (LOAD32_S_I64 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000311def : Pat<(i64 (zextloadi32 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000312 (LOAD32_U_I64 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000313
314// Resolve "don't care" extending loads to zero-extending loads. This is
315// somewhat arbitrary, but zero-extending is conceptually simpler.
316
317// Select "don't care" extending loads with no constant offset.
Dan Gohmanbb372242016-01-26 03:39:31 +0000318def : Pat<(i32 (extloadi8 I32:$addr)), (LOAD8_U_I32 0, $addr, 0)>;
319def : Pat<(i32 (extloadi16 I32:$addr)), (LOAD16_U_I32 0, $addr, 0)>;
320def : Pat<(i64 (extloadi8 I32:$addr)), (LOAD8_U_I64 0, $addr, 0)>;
321def : Pat<(i64 (extloadi16 I32:$addr)), (LOAD16_U_I64 0, $addr, 0)>;
322def : Pat<(i64 (extloadi32 I32:$addr)), (LOAD32_U_I64 0, $addr, 0)>;
JF Bastien73ff6af2015-08-31 22:24:11 +0000323
Dan Gohman4b9d7912015-12-15 22:01:29 +0000324// Select "don't care" extending loads with a constant offset.
Dan Gohmanf225a632016-01-11 22:05:44 +0000325def : Pat<(i32 (extloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000326 (LOAD8_U_I32 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000327def : Pat<(i32 (extloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000328 (LOAD16_U_I32 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000329def : Pat<(i64 (extloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000330 (LOAD8_U_I64 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000331def : Pat<(i64 (extloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000332 (LOAD16_U_I64 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000333def : Pat<(i64 (extloadi32 (regPlusImm I32:$addr, imm:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000334 (LOAD32_U_I64 imm:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000335def : Pat<(i32 (extloadi8 (regPlusGA I32:$addr,
336 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000337 (LOAD8_U_I32 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000338def : Pat<(i32 (extloadi16 (regPlusGA I32:$addr,
339 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000340 (LOAD16_U_I32 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000341def : Pat<(i64 (extloadi8 (regPlusGA I32:$addr,
342 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000343 (LOAD8_U_I64 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000344def : Pat<(i64 (extloadi16 (regPlusGA I32:$addr,
345 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000346 (LOAD16_U_I64 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000347def : Pat<(i64 (extloadi32 (regPlusGA I32:$addr,
348 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000349 (LOAD32_U_I64 tglobaladdr:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000350def : Pat<(i32 (extloadi8 (add I32:$addr,
351 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000352 (LOAD8_U_I32 texternalsym:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000353def : Pat<(i32 (extloadi16 (add I32:$addr,
354 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000355 (LOAD16_U_I32 texternalsym:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000356def : Pat<(i64 (extloadi8 (add I32:$addr,
357 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000358 (LOAD8_U_I64 texternalsym:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000359def : Pat<(i64 (extloadi16 (add I32:$addr,
360 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000361 (LOAD16_U_I64 texternalsym:$off, $addr, 0)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000362def : Pat<(i64 (extloadi32 (add I32:$addr,
363 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000364 (LOAD32_U_I64 texternalsym:$off, $addr, 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000365
366// Select "don't care" extending loads with just a constant offset.
Dan Gohmanbb372242016-01-26 03:39:31 +0000367def : Pat<(i32 (extloadi8 imm:$off)),
368 (LOAD8_U_I32 imm:$off, (CONST_I32 0), 0)>;
369def : Pat<(i32 (extloadi16 imm:$off)),
370 (LOAD16_U_I32 imm:$off, (CONST_I32 0), 0)>;
371def : Pat<(i64 (extloadi8 imm:$off)),
372 (LOAD8_U_I64 imm:$off, (CONST_I32 0), 0)>;
373def : Pat<(i64 (extloadi16 imm:$off)),
374 (LOAD16_U_I64 imm:$off, (CONST_I32 0), 0)>;
375def : Pat<(i64 (extloadi32 imm:$off)),
376 (LOAD32_U_I64 imm:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000377def : Pat<(i32 (extloadi8 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000378 (LOAD8_U_I32 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000379def : Pat<(i32 (extloadi16 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000380 (LOAD16_U_I32 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000381def : Pat<(i64 (extloadi8 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000382 (LOAD8_U_I64 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000383def : Pat<(i64 (extloadi16 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000384 (LOAD16_U_I64 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000385def : Pat<(i64 (extloadi32 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000386 (LOAD32_U_I64 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000387def : Pat<(i32 (extloadi8 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000388 (LOAD8_U_I32 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000389def : Pat<(i32 (extloadi16 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000390 (LOAD16_U_I32 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000391def : Pat<(i64 (extloadi8 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000392 (LOAD8_U_I64 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000393def : Pat<(i64 (extloadi16 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000394 (LOAD16_U_I64 texternalsym:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000395def : Pat<(i64 (extloadi32 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000396 (LOAD32_U_I64 tglobaladdr:$off, (CONST_I32 0), 0)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000397
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000398let Defs = [ARGUMENTS] in {
399
JF Bastien73ff6af2015-08-31 22:24:11 +0000400// Basic store.
Dan Gohman7054ac12015-11-23 21:16:35 +0000401// Note that we split the patterns out of the instruction definitions because
402// WebAssembly's stores return their operand value, and tablegen doesn't like
403// instruction definition patterns that don't reference all of the output
404// operands.
JF Bastien73ff6af2015-08-31 22:24:11 +0000405// Note: WebAssembly inverts SelectionDAG's usual operand order.
Dan Gohmanbb372242016-01-26 03:39:31 +0000406def STORE_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
407 P2Align:$p2align, I32:$val), [],
408 "i32.store\t$dst, ${off}(${addr})${p2align}, $val">;
409def STORE_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
410 P2Align:$p2align, I64:$val), [],
411 "i64.store\t$dst, ${off}(${addr})${p2align}, $val">;
412def STORE_F32 : I<(outs F32:$dst), (ins i32imm:$off, I32:$addr,
413 P2Align:$p2align, F32:$val), [],
414 "f32.store\t$dst, ${off}(${addr})${p2align}, $val">;
415def STORE_F64 : I<(outs F64:$dst), (ins i32imm:$off, I32:$addr,
416 P2Align:$p2align, F64:$val), [],
417 "f64.store\t$dst, ${off}(${addr})${p2align}, $val">;
Dan Gohman7054ac12015-11-23 21:16:35 +0000418
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000419} // Defs = [ARGUMENTS]
420
Dan Gohman4b9d7912015-12-15 22:01:29 +0000421// Select stores with no constant offset.
Dan Gohmanbb372242016-01-26 03:39:31 +0000422def : Pat<(store I32:$val, I32:$addr), (STORE_I32 0, I32:$addr, 0, I32:$val)>;
423def : Pat<(store I64:$val, I32:$addr), (STORE_I64 0, I32:$addr, 0, I64:$val)>;
424def : Pat<(store F32:$val, I32:$addr), (STORE_F32 0, I32:$addr, 0, F32:$val)>;
425def : Pat<(store F64:$val, I32:$addr), (STORE_F64 0, I32:$addr, 0, F64:$val)>;
Derek Schuff9d779522015-12-05 00:26:39 +0000426
Dan Gohman4b9d7912015-12-15 22:01:29 +0000427// Select stores with a constant offset.
Dan Gohmanf225a632016-01-11 22:05:44 +0000428def : Pat<(store I32:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000429 (STORE_I32 imm:$off, I32:$addr, 0, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000430def : Pat<(store I64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000431 (STORE_I64 imm:$off, I32:$addr, 0, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000432def : Pat<(store F32:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000433 (STORE_F32 imm:$off, I32:$addr, 0, F32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000434def : Pat<(store F64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000435 (STORE_F64 imm:$off, I32:$addr, 0, F64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000436def : Pat<(store I32:$val, (regPlusGA I32:$addr,
437 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000438 (STORE_I32 tglobaladdr:$off, I32:$addr, 0, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000439def : Pat<(store I64:$val, (regPlusGA I32:$addr,
440 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000441 (STORE_I64 tglobaladdr:$off, I32:$addr, 0, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000442def : Pat<(store F32:$val, (regPlusGA I32:$addr,
443 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000444 (STORE_F32 tglobaladdr:$off, I32:$addr, 0, F32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000445def : Pat<(store F64:$val, (regPlusGA I32:$addr,
446 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000447 (STORE_F64 tglobaladdr:$off, I32:$addr, 0, F64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000448def : Pat<(store I32:$val, (add I32:$addr,
449 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000450 (STORE_I32 texternalsym:$off, I32:$addr, 0, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000451def : Pat<(store I64:$val, (add I32:$addr,
452 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000453 (STORE_I64 texternalsym:$off, I32:$addr, 0, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000454def : Pat<(store F32:$val, (add I32:$addr,
455 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000456 (STORE_F32 texternalsym:$off, I32:$addr, 0, F32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000457def : Pat<(store F64:$val, (add I32:$addr,
458 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000459 (STORE_F64 texternalsym:$off, I32:$addr, 0, F64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000460
461// Select stores with just a constant offset.
462def : Pat<(store I32:$val, imm:$off),
Dan Gohmanbb372242016-01-26 03:39:31 +0000463 (STORE_I32 imm:$off, (CONST_I32 0), 0, I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000464def : Pat<(store I64:$val, imm:$off),
Dan Gohmanbb372242016-01-26 03:39:31 +0000465 (STORE_I64 imm:$off, (CONST_I32 0), 0, I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000466def : Pat<(store F32:$val, imm:$off),
Dan Gohmanbb372242016-01-26 03:39:31 +0000467 (STORE_F32 imm:$off, (CONST_I32 0), 0, F32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000468def : Pat<(store F64:$val, imm:$off),
Dan Gohmanbb372242016-01-26 03:39:31 +0000469 (STORE_F64 imm:$off, (CONST_I32 0), 0, F64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000470def : Pat<(store I32:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000471 (STORE_I32 tglobaladdr:$off, (CONST_I32 0), 0, I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000472def : Pat<(store I64:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000473 (STORE_I64 tglobaladdr:$off, (CONST_I32 0), 0, I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000474def : Pat<(store F32:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000475 (STORE_F32 tglobaladdr:$off, (CONST_I32 0), 0, F32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000476def : Pat<(store F64:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000477 (STORE_F64 tglobaladdr:$off, (CONST_I32 0), 0, F64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000478def : Pat<(store I32:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000479 (STORE_I32 texternalsym:$off, (CONST_I32 0), 0, I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000480def : Pat<(store I64:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000481 (STORE_I64 texternalsym:$off, (CONST_I32 0), 0, I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000482def : Pat<(store F32:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000483 (STORE_F32 texternalsym:$off, (CONST_I32 0), 0, F32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000484def : Pat<(store F64:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000485 (STORE_F64 texternalsym:$off, (CONST_I32 0), 0, F64:$val)>;
JF Bastien73ff6af2015-08-31 22:24:11 +0000486
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000487let Defs = [ARGUMENTS] in {
488
JF Bastien73ff6af2015-08-31 22:24:11 +0000489// Truncating store.
Dan Gohmanbb372242016-01-26 03:39:31 +0000490def STORE8_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
491 P2Align:$p2align, I32:$val), [],
492 "i32.store8\t$dst, ${off}(${addr})${p2align}, $val">;
493def STORE16_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
494 P2Align:$p2align, I32:$val), [],
495 "i32.store16\t$dst, ${off}(${addr})${p2align}, $val">;
496def STORE8_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
497 P2Align:$p2align, I64:$val), [],
498 "i64.store8\t$dst, ${off}(${addr})${p2align}, $val">;
499def STORE16_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
500 P2Align:$p2align, I64:$val), [],
501 "i64.store16\t$dst, ${off}(${addr})${p2align}, $val">;
502def STORE32_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
503 P2Align:$p2align, I64:$val), [],
504 "i64.store32\t$dst, ${off}(${addr})${p2align}, $val">;
Dan Gohman7054ac12015-11-23 21:16:35 +0000505
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000506} // Defs = [ARGUMENTS]
507
Dan Gohman4b9d7912015-12-15 22:01:29 +0000508// Select truncating stores with no constant offset.
Dan Gohman7054ac12015-11-23 21:16:35 +0000509def : Pat<(truncstorei8 I32:$val, I32:$addr),
Dan Gohmanbb372242016-01-26 03:39:31 +0000510 (STORE8_I32 0, I32:$addr, 0, I32:$val)>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000511def : Pat<(truncstorei16 I32:$val, I32:$addr),
Dan Gohmanbb372242016-01-26 03:39:31 +0000512 (STORE16_I32 0, I32:$addr, 0, I32:$val)>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000513def : Pat<(truncstorei8 I64:$val, I32:$addr),
Dan Gohmanbb372242016-01-26 03:39:31 +0000514 (STORE8_I64 0, I32:$addr, 0, I64:$val)>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000515def : Pat<(truncstorei16 I64:$val, I32:$addr),
Dan Gohmanbb372242016-01-26 03:39:31 +0000516 (STORE16_I64 0, I32:$addr, 0, I64:$val)>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000517def : Pat<(truncstorei32 I64:$val, I32:$addr),
Dan Gohmanbb372242016-01-26 03:39:31 +0000518 (STORE32_I64 0, I32:$addr, 0, I64:$val)>;
JF Bastien73ff6af2015-08-31 22:24:11 +0000519
Dan Gohman4b9d7912015-12-15 22:01:29 +0000520// Select truncating stores with a constant offset.
Dan Gohmanf225a632016-01-11 22:05:44 +0000521def : Pat<(truncstorei8 I32:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000522 (STORE8_I32 imm:$off, I32:$addr, 0, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000523def : Pat<(truncstorei16 I32:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000524 (STORE16_I32 imm:$off, I32:$addr, 0, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000525def : Pat<(truncstorei8 I64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000526 (STORE8_I64 imm:$off, I32:$addr, 0, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000527def : Pat<(truncstorei16 I64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000528 (STORE16_I64 imm:$off, I32:$addr, 0, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000529def : Pat<(truncstorei32 I64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000530 (STORE32_I64 imm:$off, I32:$addr, 0, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000531def : Pat<(truncstorei8 I32:$val,
532 (regPlusGA I32:$addr,
533 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000534 (STORE8_I32 tglobaladdr:$off, I32:$addr, 0, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000535def : Pat<(truncstorei16 I32:$val,
536 (regPlusGA I32:$addr,
537 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000538 (STORE16_I32 tglobaladdr:$off, I32:$addr, 0, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000539def : Pat<(truncstorei8 I64:$val,
540 (regPlusGA I32:$addr,
541 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000542 (STORE8_I64 tglobaladdr:$off, I32:$addr, 0, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000543def : Pat<(truncstorei16 I64:$val,
544 (regPlusGA I32:$addr,
545 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000546 (STORE16_I64 tglobaladdr:$off, I32:$addr, 0, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000547def : Pat<(truncstorei32 I64:$val,
548 (regPlusGA I32:$addr,
549 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000550 (STORE32_I64 tglobaladdr:$off, I32:$addr, 0, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000551def : Pat<(truncstorei8 I32:$val, (add I32:$addr,
552 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000553 (STORE8_I32 texternalsym:$off, I32:$addr, 0, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000554def : Pat<(truncstorei16 I32:$val,
555 (add I32:$addr,
556 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000557 (STORE16_I32 texternalsym:$off, I32:$addr, 0, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000558def : Pat<(truncstorei8 I64:$val,
559 (add I32:$addr,
560 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000561 (STORE8_I64 texternalsym:$off, I32:$addr, 0, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000562def : Pat<(truncstorei16 I64:$val,
563 (add I32:$addr,
564 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000565 (STORE16_I64 texternalsym:$off, I32:$addr, 0, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000566def : Pat<(truncstorei32 I64:$val,
567 (add I32:$addr,
568 (WebAssemblywrapper texternalsym:$off))),
Dan Gohmanbb372242016-01-26 03:39:31 +0000569 (STORE32_I64 texternalsym:$off, I32:$addr, 0, I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000570
571// Select truncating stores with just a constant offset.
572def : Pat<(truncstorei8 I32:$val, imm:$off),
Dan Gohmanbb372242016-01-26 03:39:31 +0000573 (STORE8_I32 imm:$off, (CONST_I32 0), 0, I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000574def : Pat<(truncstorei16 I32:$val, imm:$off),
Dan Gohmanbb372242016-01-26 03:39:31 +0000575 (STORE16_I32 imm:$off, (CONST_I32 0), 0, I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000576def : Pat<(truncstorei8 I64:$val, imm:$off),
Dan Gohmanbb372242016-01-26 03:39:31 +0000577 (STORE8_I64 imm:$off, (CONST_I32 0), 0, I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000578def : Pat<(truncstorei16 I64:$val, imm:$off),
Dan Gohmanbb372242016-01-26 03:39:31 +0000579 (STORE16_I64 imm:$off, (CONST_I32 0), 0, I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000580def : Pat<(truncstorei32 I64:$val, imm:$off),
Dan Gohmanbb372242016-01-26 03:39:31 +0000581 (STORE32_I64 imm:$off, (CONST_I32 0), 0, I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000582def : Pat<(truncstorei8 I32:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000583 (STORE8_I32 tglobaladdr:$off, (CONST_I32 0), 0, I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000584def : Pat<(truncstorei16 I32:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000585 (STORE16_I32 tglobaladdr:$off, (CONST_I32 0), 0, I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000586def : Pat<(truncstorei8 I64:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000587 (STORE8_I64 tglobaladdr:$off, (CONST_I32 0), 0, I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000588def : Pat<(truncstorei16 I64:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000589 (STORE16_I64 tglobaladdr:$off, (CONST_I32 0), 0, I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000590def : Pat<(truncstorei32 I64:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000591 (STORE32_I64 tglobaladdr:$off, (CONST_I32 0), 0, I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000592def : Pat<(truncstorei8 I32:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000593 (STORE8_I32 texternalsym:$off, (CONST_I32 0), 0, I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000594def : Pat<(truncstorei16 I32:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000595 (STORE16_I32 texternalsym:$off, (CONST_I32 0), 0, I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000596def : Pat<(truncstorei8 I64:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000597 (STORE8_I64 texternalsym:$off, (CONST_I32 0), 0, I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000598def : Pat<(truncstorei16 I64:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000599 (STORE16_I64 texternalsym:$off, (CONST_I32 0), 0, I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000600def : Pat<(truncstorei32 I64:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohmanbb372242016-01-26 03:39:31 +0000601 (STORE32_I64 texternalsym:$off, (CONST_I32 0), 0, I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000602
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000603let Defs = [ARGUMENTS] in {
604
Dan Gohman72f16922015-10-02 19:21:15 +0000605// Memory size.
Dan Gohmanf4333242015-11-13 20:19:11 +0000606def MEMORY_SIZE_I32 : I<(outs I32:$dst), (ins),
Dan Gohmanaf29bd42015-11-05 20:42:30 +0000607 [(set I32:$dst, (int_wasm_memory_size))],
Dan Gohman192dddc2015-11-23 22:37:29 +0000608 "memory_size\t$dst">,
Dan Gohman72f16922015-10-02 19:21:15 +0000609 Requires<[HasAddr32]>;
Dan Gohmanf4333242015-11-13 20:19:11 +0000610def MEMORY_SIZE_I64 : I<(outs I64:$dst), (ins),
Dan Gohmanaf29bd42015-11-05 20:42:30 +0000611 [(set I64:$dst, (int_wasm_memory_size))],
Dan Gohman192dddc2015-11-23 22:37:29 +0000612 "memory_size\t$dst">,
Dan Gohman72f16922015-10-02 19:21:15 +0000613 Requires<[HasAddr64]>;
Dan Gohmanbaba8c62015-10-02 20:10:26 +0000614
Dan Gohmand7ffb912015-11-05 20:16:59 +0000615// Grow memory.
Dan Gohmanf4333242015-11-13 20:19:11 +0000616def GROW_MEMORY_I32 : I<(outs), (ins I32:$delta),
Dan Gohmanaf29bd42015-11-05 20:42:30 +0000617 [(int_wasm_grow_memory I32:$delta)],
Dan Gohman192dddc2015-11-23 22:37:29 +0000618 "grow_memory\t$delta">,
Dan Gohmand7ffb912015-11-05 20:16:59 +0000619 Requires<[HasAddr32]>;
Dan Gohmanf4333242015-11-13 20:19:11 +0000620def GROW_MEMORY_I64 : I<(outs), (ins I64:$delta),
Dan Gohmanaf29bd42015-11-05 20:42:30 +0000621 [(int_wasm_grow_memory I64:$delta)],
Dan Gohman192dddc2015-11-23 22:37:29 +0000622 "grow_memory\t$delta">,
Dan Gohmand7ffb912015-11-05 20:16:59 +0000623 Requires<[HasAddr64]>;
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000624
625} // Defs = [ARGUMENTS]