blob: b39ac5212f8758468f4b3c778b1d1eafa180393a [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 Gohmane3d7b582015-12-15 03:21:48 +000049def LOAD_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr), [],
Dan Gohmand587aa52015-12-21 16:58:49 +000050 "i32.load\t$dst, ${off}(${addr})">;
Dan Gohmane3d7b582015-12-15 03:21:48 +000051def LOAD_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr), [],
Dan Gohmand587aa52015-12-21 16:58:49 +000052 "i64.load\t$dst, ${off}(${addr})">;
Dan Gohmane3d7b582015-12-15 03:21:48 +000053def LOAD_F32 : I<(outs F32:$dst), (ins i32imm:$off, I32:$addr), [],
Dan Gohmand587aa52015-12-21 16:58:49 +000054 "f32.load\t$dst, ${off}(${addr})">;
Dan Gohmane3d7b582015-12-15 03:21:48 +000055def LOAD_F64 : I<(outs F64:$dst), (ins i32imm:$off, I32:$addr), [],
Dan Gohmand587aa52015-12-21 16:58:49 +000056 "f64.load\t$dst, ${off}(${addr})">;
JF Bastien73ff6af2015-08-31 22:24:11 +000057
Dan Gohman4b9d7912015-12-15 22:01:29 +000058} // Defs = [ARGUMENTS]
59
60// Select loads with no constant offset.
61def : Pat<(i32 (load I32:$addr)), (LOAD_I32 0, $addr)>;
62def : Pat<(i64 (load I32:$addr)), (LOAD_I64 0, $addr)>;
63def : Pat<(f32 (load I32:$addr)), (LOAD_F32 0, $addr)>;
64def : Pat<(f64 (load I32:$addr)), (LOAD_F64 0, $addr)>;
65
66// Select loads with a constant offset.
Dan Gohmanf225a632016-01-11 22:05:44 +000067def : Pat<(i32 (load (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +000068 (LOAD_I32 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000069def : Pat<(i64 (load (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +000070 (LOAD_I64 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000071def : Pat<(f32 (load (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +000072 (LOAD_F32 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000073def : Pat<(f64 (load (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +000074 (LOAD_F64 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000075def : Pat<(i32 (load (regPlusGA I32:$addr,
76 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +000077 (LOAD_I32 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000078def : Pat<(i64 (load (regPlusGA I32:$addr,
79 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +000080 (LOAD_I64 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000081def : Pat<(f32 (load (regPlusGA I32:$addr,
82 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +000083 (LOAD_F32 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000084def : Pat<(f64 (load (regPlusGA I32:$addr,
85 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +000086 (LOAD_F64 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000087def : Pat<(i32 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +000088 (LOAD_I32 texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000089def : Pat<(i64 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +000090 (LOAD_I64 texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000091def : Pat<(f32 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +000092 (LOAD_F32 texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000093def : Pat<(f64 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +000094 (LOAD_F64 texternalsym:$off, $addr)>;
95
96// Select loads with just a constant offset.
97def : Pat<(i32 (load imm:$off)), (LOAD_I32 imm:$off, (CONST_I32 0))>;
98def : Pat<(i64 (load imm:$off)), (LOAD_I64 imm:$off, (CONST_I32 0))>;
99def : Pat<(f32 (load imm:$off)), (LOAD_F32 imm:$off, (CONST_I32 0))>;
100def : Pat<(f64 (load imm:$off)), (LOAD_F64 imm:$off, (CONST_I32 0))>;
101def : Pat<(i32 (load (WebAssemblywrapper tglobaladdr:$off))),
102 (LOAD_I32 tglobaladdr:$off, (CONST_I32 0))>;
103def : Pat<(i64 (load (WebAssemblywrapper tglobaladdr:$off))),
104 (LOAD_I64 tglobaladdr:$off, (CONST_I32 0))>;
105def : Pat<(f32 (load (WebAssemblywrapper tglobaladdr:$off))),
106 (LOAD_F32 tglobaladdr:$off, (CONST_I32 0))>;
107def : Pat<(f64 (load (WebAssemblywrapper tglobaladdr:$off))),
108 (LOAD_F64 tglobaladdr:$off, (CONST_I32 0))>;
109def : Pat<(i32 (load (WebAssemblywrapper texternalsym:$off))),
110 (LOAD_I32 texternalsym:$off, (CONST_I32 0))>;
111def : Pat<(i64 (load (WebAssemblywrapper texternalsym:$off))),
112 (LOAD_I64 texternalsym:$off, (CONST_I32 0))>;
113def : Pat<(f32 (load (WebAssemblywrapper texternalsym:$off))),
114 (LOAD_F32 texternalsym:$off, (CONST_I32 0))>;
115def : Pat<(f64 (load (WebAssemblywrapper texternalsym:$off))),
116 (LOAD_F64 texternalsym:$off, (CONST_I32 0))>;
117
118let Defs = [ARGUMENTS] in {
119
JF Bastien73ff6af2015-08-31 22:24:11 +0000120// Extending load.
Dan Gohmane3d7b582015-12-15 03:21:48 +0000121def LOAD8_S_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000122 "i32.load8_s\t$dst, ${off}(${addr})">;
Dan Gohmane3d7b582015-12-15 03:21:48 +0000123def LOAD8_U_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000124 "i32.load8_u\t$dst, ${off}(${addr})">;
Dan Gohmane3d7b582015-12-15 03:21:48 +0000125def LOAD16_S_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000126 "i32.load16_s\t$dst, ${off}(${addr})">;
Dan Gohmane3d7b582015-12-15 03:21:48 +0000127def LOAD16_U_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000128 "i32.load16_u\t$dst, ${off}(${addr})">;
Dan Gohmane3d7b582015-12-15 03:21:48 +0000129def LOAD8_S_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000130 "i64.load8_s\t$dst, ${off}(${addr})">;
Dan Gohmane3d7b582015-12-15 03:21:48 +0000131def LOAD8_U_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000132 "i64.load8_u\t$dst, ${off}(${addr})">;
Dan Gohmane3d7b582015-12-15 03:21:48 +0000133def LOAD16_S_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000134 "i64.load16_s\t$dst, ${off}(${addr})">;
Dan Gohmane3d7b582015-12-15 03:21:48 +0000135def LOAD16_U_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000136 "i64.load16_u\t$dst, ${off}(${addr})">;
Dan Gohmane3d7b582015-12-15 03:21:48 +0000137def LOAD32_S_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000138 "i64.load32_s\t$dst, ${off}(${addr})">;
Dan Gohmane3d7b582015-12-15 03:21:48 +0000139def LOAD32_U_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000140 "i64.load32_u\t$dst, ${off}(${addr})">;
JF Bastien73ff6af2015-08-31 22:24:11 +0000141
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000142} // Defs = [ARGUMENTS]
143
Derek Schuff9d779522015-12-05 00:26:39 +0000144// Select extending loads with no constant offset.
145def : Pat<(i32 (sextloadi8 I32:$addr)), (LOAD8_S_I32 0, $addr)>;
146def : Pat<(i32 (zextloadi8 I32:$addr)), (LOAD8_U_I32 0, $addr)>;
147def : Pat<(i32 (sextloadi16 I32:$addr)), (LOAD16_S_I32 0, $addr)>;
148def : Pat<(i32 (zextloadi16 I32:$addr)), (LOAD16_U_I32 0, $addr)>;
149def : Pat<(i64 (sextloadi8 I32:$addr)), (LOAD8_S_I64 0, $addr)>;
150def : Pat<(i64 (zextloadi8 I32:$addr)), (LOAD8_U_I64 0, $addr)>;
151def : Pat<(i64 (sextloadi16 I32:$addr)), (LOAD16_S_I64 0, $addr)>;
152def : Pat<(i64 (zextloadi16 I32:$addr)), (LOAD16_U_I64 0, $addr)>;
153def : Pat<(i64 (sextloadi32 I32:$addr)), (LOAD32_S_I64 0, $addr)>;
154def : Pat<(i64 (zextloadi32 I32:$addr)), (LOAD32_U_I64 0, $addr)>;
155
Dan Gohman4b9d7912015-12-15 22:01:29 +0000156// Select extending loads with a constant offset.
Dan Gohmanf225a632016-01-11 22:05:44 +0000157def : Pat<(i32 (sextloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000158 (LOAD8_S_I32 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000159def : Pat<(i32 (zextloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000160 (LOAD8_U_I32 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000161def : Pat<(i32 (sextloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000162 (LOAD16_S_I32 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000163def : Pat<(i32 (zextloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000164 (LOAD16_U_I32 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000165def : Pat<(i64 (sextloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000166 (LOAD8_S_I64 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000167def : Pat<(i64 (zextloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000168 (LOAD8_U_I64 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000169def : Pat<(i64 (sextloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000170 (LOAD16_S_I64 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000171def : Pat<(i64 (zextloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000172 (LOAD16_U_I64 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000173def : Pat<(i64 (sextloadi32 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000174 (LOAD32_S_I64 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000175def : Pat<(i64 (zextloadi32 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000176 (LOAD32_U_I64 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000177def : Pat<(i32 (sextloadi8 (regPlusGA I32:$addr,
178 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000179 (LOAD8_S_I32 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000180def : Pat<(i32 (zextloadi8 (regPlusGA I32:$addr,
181 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000182 (LOAD8_U_I32 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000183def : Pat<(i32 (sextloadi16 (regPlusGA I32:$addr,
184 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000185 (LOAD16_S_I32 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000186def : Pat<(i32 (zextloadi16 (regPlusGA I32:$addr,
187 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000188 (LOAD16_U_I32 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000189def : Pat<(i64 (sextloadi8 (regPlusGA I32:$addr,
190 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000191 (LOAD8_S_I64 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000192def : Pat<(i64 (zextloadi8 (regPlusGA I32:$addr,
193 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000194 (LOAD8_U_I64 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000195def : Pat<(i64 (sextloadi16 (regPlusGA I32:$addr,
196 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000197 (LOAD16_S_I64 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000198def : Pat<(i64 (zextloadi16 (regPlusGA I32:$addr,
199 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000200 (LOAD16_U_I64 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000201def : Pat<(i64 (sextloadi32 (regPlusGA I32:$addr,
202 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000203 (LOAD32_S_I64 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000204def : Pat<(i64 (zextloadi32 (regPlusGA I32:$addr,
205 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000206 (LOAD32_U_I64 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000207def : Pat<(i32 (sextloadi8 (add I32:$addr,
208 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000209 (LOAD8_S_I32 texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000210def : Pat<(i32 (zextloadi8 (add I32:$addr,
211 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000212 (LOAD8_U_I32 texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000213def : Pat<(i32 (sextloadi16 (add I32:$addr,
214 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000215 (LOAD16_S_I32 texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000216def : Pat<(i32 (zextloadi16 (add I32:$addr,
217 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000218 (LOAD16_U_I32 texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000219def : Pat<(i64 (sextloadi8 (add I32:$addr,
220 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000221 (LOAD8_S_I64 texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000222def : Pat<(i64 (zextloadi8 (add I32:$addr,
223 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000224 (LOAD8_U_I64 texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000225def : Pat<(i64 (sextloadi16 (add I32:$addr,
226 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000227 (LOAD16_S_I64 texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000228def : Pat<(i64 (zextloadi16 (add I32:$addr,
229 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000230 (LOAD16_U_I64 texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000231def : Pat<(i64 (sextloadi32 (add I32:$addr,
232 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000233 (LOAD32_S_I64 texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000234def : Pat<(i64 (zextloadi32 (add I32:$addr,
235 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000236 (LOAD32_U_I64 texternalsym:$off, $addr)>;
237
238// Select extending loads with just a constant offset.
239def : Pat<(i32 (sextloadi8 imm:$off)), (LOAD8_S_I32 imm:$off, (CONST_I32 0))>;
240def : Pat<(i32 (zextloadi8 imm:$off)), (LOAD8_U_I32 imm:$off, (CONST_I32 0))>;
241def : Pat<(i32 (sextloadi16 imm:$off)), (LOAD16_S_I32 imm:$off, (CONST_I32 0))>;
242def : Pat<(i32 (zextloadi16 imm:$off)), (LOAD16_U_I32 imm:$off, (CONST_I32 0))>;
243def : Pat<(i64 (sextloadi8 imm:$off)), (LOAD8_S_I64 imm:$off, (CONST_I32 0))>;
244def : Pat<(i64 (zextloadi8 imm:$off)), (LOAD8_U_I64 imm:$off, (CONST_I32 0))>;
245def : Pat<(i64 (sextloadi16 imm:$off)), (LOAD16_S_I64 imm:$off, (CONST_I32 0))>;
246def : Pat<(i64 (zextloadi16 imm:$off)), (LOAD16_U_I64 imm:$off, (CONST_I32 0))>;
247def : Pat<(i64 (sextloadi32 imm:$off)), (LOAD32_S_I64 imm:$off, (CONST_I32 0))>;
248def : Pat<(i64 (zextloadi32 imm:$off)), (LOAD32_U_I64 imm:$off, (CONST_I32 0))>;
249def : Pat<(i32 (sextloadi8 (WebAssemblywrapper tglobaladdr:$off))),
250 (LOAD8_S_I32 tglobaladdr:$off, (CONST_I32 0))>;
251def : Pat<(i32 (zextloadi8 (WebAssemblywrapper tglobaladdr:$off))),
252 (LOAD8_U_I32 tglobaladdr:$off, (CONST_I32 0))>;
253def : Pat<(i32 (sextloadi16 (WebAssemblywrapper tglobaladdr:$off))),
254 (LOAD16_S_I32 tglobaladdr:$off, (CONST_I32 0))>;
255def : Pat<(i32 (zextloadi16 (WebAssemblywrapper tglobaladdr:$off))),
256 (LOAD16_U_I32 tglobaladdr:$off, (CONST_I32 0))>;
257def : Pat<(i64 (sextloadi8 (WebAssemblywrapper tglobaladdr:$off))),
258 (LOAD8_S_I64 tglobaladdr:$off, (CONST_I32 0))>;
259def : Pat<(i64 (zextloadi8 (WebAssemblywrapper tglobaladdr:$off))),
260 (LOAD8_U_I64 tglobaladdr:$off, (CONST_I32 0))>;
261def : Pat<(i64 (sextloadi16 (WebAssemblywrapper tglobaladdr:$off))),
262 (LOAD16_S_I64 tglobaladdr:$off, (CONST_I32 0))>;
263def : Pat<(i64 (zextloadi16 (WebAssemblywrapper tglobaladdr:$off))),
264 (LOAD16_U_I64 tglobaladdr:$off, (CONST_I32 0))>;
265def : Pat<(i64 (sextloadi32 (WebAssemblywrapper tglobaladdr:$off))),
266 (LOAD32_S_I64 tglobaladdr:$off, (CONST_I32 0))>;
267def : Pat<(i64 (zextloadi32 (WebAssemblywrapper tglobaladdr:$off))),
268 (LOAD32_U_I64 tglobaladdr:$off, (CONST_I32 0))>;
269def : Pat<(i32 (sextloadi8 (WebAssemblywrapper texternalsym:$off))),
270 (LOAD8_S_I32 texternalsym:$off, (CONST_I32 0))>;
271def : Pat<(i32 (zextloadi8 (WebAssemblywrapper texternalsym:$off))),
272 (LOAD8_U_I32 texternalsym:$off, (CONST_I32 0))>;
273def : Pat<(i32 (sextloadi16 (WebAssemblywrapper texternalsym:$off))),
274 (LOAD16_S_I32 texternalsym:$off, (CONST_I32 0))>;
275def : Pat<(i32 (zextloadi16 (WebAssemblywrapper texternalsym:$off))),
276 (LOAD16_U_I32 texternalsym:$off, (CONST_I32 0))>;
277def : Pat<(i64 (sextloadi8 (WebAssemblywrapper texternalsym:$off))),
278 (LOAD8_S_I64 texternalsym:$off, (CONST_I32 0))>;
279def : Pat<(i64 (zextloadi8 (WebAssemblywrapper texternalsym:$off))),
280 (LOAD8_U_I64 texternalsym:$off, (CONST_I32 0))>;
281def : Pat<(i64 (sextloadi16 (WebAssemblywrapper texternalsym:$off))),
282 (LOAD16_S_I64 texternalsym:$off, (CONST_I32 0))>;
283def : Pat<(i64 (zextloadi16 (WebAssemblywrapper texternalsym:$off))),
284 (LOAD16_U_I64 texternalsym:$off, (CONST_I32 0))>;
285def : Pat<(i64 (sextloadi32 (WebAssemblywrapper texternalsym:$off))),
286 (LOAD32_S_I64 texternalsym:$off, (CONST_I32 0))>;
287def : Pat<(i64 (zextloadi32 (WebAssemblywrapper texternalsym:$off))),
288 (LOAD32_U_I64 texternalsym:$off, (CONST_I32 0))>;
289
290// Resolve "don't care" extending loads to zero-extending loads. This is
291// somewhat arbitrary, but zero-extending is conceptually simpler.
292
293// Select "don't care" extending loads with no constant offset.
Derek Schuff9d779522015-12-05 00:26:39 +0000294def : Pat<(i32 (extloadi8 I32:$addr)), (LOAD8_U_I32 0, $addr)>;
295def : Pat<(i32 (extloadi16 I32:$addr)), (LOAD16_U_I32 0, $addr)>;
296def : Pat<(i64 (extloadi8 I32:$addr)), (LOAD8_U_I64 0, $addr)>;
297def : Pat<(i64 (extloadi16 I32:$addr)), (LOAD16_U_I64 0, $addr)>;
298def : Pat<(i64 (extloadi32 I32:$addr)), (LOAD32_U_I64 0, $addr)>;
JF Bastien73ff6af2015-08-31 22:24:11 +0000299
Dan Gohman4b9d7912015-12-15 22:01:29 +0000300// Select "don't care" extending loads with a constant offset.
Dan Gohmanf225a632016-01-11 22:05:44 +0000301def : Pat<(i32 (extloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000302 (LOAD8_U_I32 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000303def : Pat<(i32 (extloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000304 (LOAD16_U_I32 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000305def : Pat<(i64 (extloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000306 (LOAD8_U_I64 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000307def : Pat<(i64 (extloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000308 (LOAD16_U_I64 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000309def : Pat<(i64 (extloadi32 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000310 (LOAD32_U_I64 imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000311def : Pat<(i32 (extloadi8 (regPlusGA I32:$addr,
312 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000313 (LOAD8_U_I32 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000314def : Pat<(i32 (extloadi16 (regPlusGA I32:$addr,
315 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000316 (LOAD16_U_I32 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000317def : Pat<(i64 (extloadi8 (regPlusGA I32:$addr,
318 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000319 (LOAD8_U_I64 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000320def : Pat<(i64 (extloadi16 (regPlusGA I32:$addr,
321 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000322 (LOAD16_U_I64 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000323def : Pat<(i64 (extloadi32 (regPlusGA I32:$addr,
324 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000325 (LOAD32_U_I64 tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000326def : Pat<(i32 (extloadi8 (add I32:$addr,
327 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000328 (LOAD8_U_I32 texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000329def : Pat<(i32 (extloadi16 (add I32:$addr,
330 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000331 (LOAD16_U_I32 texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000332def : Pat<(i64 (extloadi8 (add I32:$addr,
333 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000334 (LOAD8_U_I64 texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000335def : Pat<(i64 (extloadi16 (add I32:$addr,
336 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000337 (LOAD16_U_I64 texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000338def : Pat<(i64 (extloadi32 (add I32:$addr,
339 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000340 (LOAD32_U_I64 texternalsym:$off, $addr)>;
341
342// Select "don't care" extending loads with just a constant offset.
343def : Pat<(i32 (extloadi8 imm:$off)), (LOAD8_U_I32 imm:$off, (CONST_I32 0))>;
344def : Pat<(i32 (extloadi16 imm:$off)), (LOAD16_U_I32 imm:$off, (CONST_I32 0))>;
345def : Pat<(i64 (extloadi8 imm:$off)), (LOAD8_U_I64 imm:$off, (CONST_I32 0))>;
346def : Pat<(i64 (extloadi16 imm:$off)), (LOAD16_U_I64 imm:$off, (CONST_I32 0))>;
347def : Pat<(i64 (extloadi32 imm:$off)), (LOAD32_U_I64 imm:$off, (CONST_I32 0))>;
348def : Pat<(i32 (extloadi8 (WebAssemblywrapper tglobaladdr:$off))),
349 (LOAD8_U_I32 tglobaladdr:$off, (CONST_I32 0))>;
350def : Pat<(i32 (extloadi16 (WebAssemblywrapper tglobaladdr:$off))),
351 (LOAD16_U_I32 tglobaladdr:$off, (CONST_I32 0))>;
352def : Pat<(i64 (extloadi8 (WebAssemblywrapper tglobaladdr:$off))),
353 (LOAD8_U_I64 tglobaladdr:$off, (CONST_I32 0))>;
354def : Pat<(i64 (extloadi16 (WebAssemblywrapper tglobaladdr:$off))),
355 (LOAD16_U_I64 tglobaladdr:$off, (CONST_I32 0))>;
356def : Pat<(i64 (extloadi32 (WebAssemblywrapper tglobaladdr:$off))),
357 (LOAD32_U_I64 tglobaladdr:$off, (CONST_I32 0))>;
358def : Pat<(i32 (extloadi8 (WebAssemblywrapper texternalsym:$off))),
359 (LOAD8_U_I32 texternalsym:$off, (CONST_I32 0))>;
360def : Pat<(i32 (extloadi16 (WebAssemblywrapper texternalsym:$off))),
361 (LOAD16_U_I32 texternalsym:$off, (CONST_I32 0))>;
362def : Pat<(i64 (extloadi8 (WebAssemblywrapper texternalsym:$off))),
363 (LOAD8_U_I64 texternalsym:$off, (CONST_I32 0))>;
364def : Pat<(i64 (extloadi16 (WebAssemblywrapper texternalsym:$off))),
365 (LOAD16_U_I64 texternalsym:$off, (CONST_I32 0))>;
366def : Pat<(i64 (extloadi32 (WebAssemblywrapper texternalsym:$off))),
367 (LOAD32_U_I64 tglobaladdr:$off, (CONST_I32 0))>;
368
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000369let Defs = [ARGUMENTS] in {
370
JF Bastien73ff6af2015-08-31 22:24:11 +0000371// Basic store.
Dan Gohman7054ac12015-11-23 21:16:35 +0000372// Note that we split the patterns out of the instruction definitions because
373// WebAssembly's stores return their operand value, and tablegen doesn't like
374// instruction definition patterns that don't reference all of the output
375// operands.
JF Bastien73ff6af2015-08-31 22:24:11 +0000376// Note: WebAssembly inverts SelectionDAG's usual operand order.
Dan Gohmane3d7b582015-12-15 03:21:48 +0000377def STORE_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr, I32:$val), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000378 "i32.store\t$dst, ${off}(${addr}), $val">;
Dan Gohmane3d7b582015-12-15 03:21:48 +0000379def STORE_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr, I64:$val), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000380 "i64.store\t$dst, ${off}(${addr}), $val">;
Dan Gohmane3d7b582015-12-15 03:21:48 +0000381def STORE_F32 : I<(outs F32:$dst), (ins i32imm:$off, I32:$addr, F32:$val), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000382 "f32.store\t$dst, ${off}(${addr}), $val">;
Dan Gohmane3d7b582015-12-15 03:21:48 +0000383def STORE_F64 : I<(outs F64:$dst), (ins i32imm:$off, I32:$addr, F64:$val), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000384 "f64.store\t$dst, ${off}(${addr}), $val">;
Dan Gohman7054ac12015-11-23 21:16:35 +0000385
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000386} // Defs = [ARGUMENTS]
387
Dan Gohman4b9d7912015-12-15 22:01:29 +0000388// Select stores with no constant offset.
Derek Schuff9d779522015-12-05 00:26:39 +0000389def : Pat<(store I32:$val, I32:$addr), (STORE_I32 0, I32:$addr, I32:$val)>;
390def : Pat<(store I64:$val, I32:$addr), (STORE_I64 0, I32:$addr, I64:$val)>;
391def : Pat<(store F32:$val, I32:$addr), (STORE_F32 0, I32:$addr, F32:$val)>;
392def : Pat<(store F64:$val, I32:$addr), (STORE_F64 0, I32:$addr, F64:$val)>;
393
Dan Gohman4b9d7912015-12-15 22:01:29 +0000394// Select stores with a constant offset.
Dan Gohmanf225a632016-01-11 22:05:44 +0000395def : Pat<(store I32:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000396 (STORE_I32 imm:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000397def : Pat<(store I64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000398 (STORE_I64 imm:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000399def : Pat<(store F32:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000400 (STORE_F32 imm:$off, I32:$addr, F32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000401def : Pat<(store F64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000402 (STORE_F64 imm:$off, I32:$addr, F64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000403def : Pat<(store I32:$val, (regPlusGA I32:$addr,
404 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000405 (STORE_I32 tglobaladdr:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000406def : Pat<(store I64:$val, (regPlusGA I32:$addr,
407 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000408 (STORE_I64 tglobaladdr:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000409def : Pat<(store F32:$val, (regPlusGA I32:$addr,
410 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000411 (STORE_F32 tglobaladdr:$off, I32:$addr, F32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000412def : Pat<(store F64:$val, (regPlusGA I32:$addr,
413 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000414 (STORE_F64 tglobaladdr:$off, I32:$addr, F64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000415def : Pat<(store I32:$val, (add I32:$addr,
416 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000417 (STORE_I32 texternalsym:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000418def : Pat<(store I64:$val, (add I32:$addr,
419 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000420 (STORE_I64 texternalsym:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000421def : Pat<(store F32:$val, (add I32:$addr,
422 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000423 (STORE_F32 texternalsym:$off, I32:$addr, F32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000424def : Pat<(store F64:$val, (add I32:$addr,
425 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000426 (STORE_F64 texternalsym:$off, I32:$addr, F64:$val)>;
427
428// Select stores with just a constant offset.
429def : Pat<(store I32:$val, imm:$off),
430 (STORE_I32 imm:$off, (CONST_I32 0), I32:$val)>;
431def : Pat<(store I64:$val, imm:$off),
432 (STORE_I64 imm:$off, (CONST_I32 0), I64:$val)>;
433def : Pat<(store F32:$val, imm:$off),
434 (STORE_F32 imm:$off, (CONST_I32 0), F32:$val)>;
435def : Pat<(store F64:$val, imm:$off),
436 (STORE_F64 imm:$off, (CONST_I32 0), F64:$val)>;
437def : Pat<(store I32:$val, (WebAssemblywrapper tglobaladdr:$off)),
438 (STORE_I32 tglobaladdr:$off, (CONST_I32 0), I32:$val)>;
439def : Pat<(store I64:$val, (WebAssemblywrapper tglobaladdr:$off)),
440 (STORE_I64 tglobaladdr:$off, (CONST_I32 0), I64:$val)>;
441def : Pat<(store F32:$val, (WebAssemblywrapper tglobaladdr:$off)),
442 (STORE_F32 tglobaladdr:$off, (CONST_I32 0), F32:$val)>;
443def : Pat<(store F64:$val, (WebAssemblywrapper tglobaladdr:$off)),
444 (STORE_F64 tglobaladdr:$off, (CONST_I32 0), F64:$val)>;
445def : Pat<(store I32:$val, (WebAssemblywrapper texternalsym:$off)),
446 (STORE_I32 texternalsym:$off, (CONST_I32 0), I32:$val)>;
447def : Pat<(store I64:$val, (WebAssemblywrapper texternalsym:$off)),
448 (STORE_I64 texternalsym:$off, (CONST_I32 0), I64:$val)>;
449def : Pat<(store F32:$val, (WebAssemblywrapper texternalsym:$off)),
450 (STORE_F32 texternalsym:$off, (CONST_I32 0), F32:$val)>;
451def : Pat<(store F64:$val, (WebAssemblywrapper texternalsym:$off)),
452 (STORE_F64 texternalsym:$off, (CONST_I32 0), F64:$val)>;
JF Bastien73ff6af2015-08-31 22:24:11 +0000453
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000454let Defs = [ARGUMENTS] in {
455
JF Bastien73ff6af2015-08-31 22:24:11 +0000456// Truncating store.
Dan Gohmane3d7b582015-12-15 03:21:48 +0000457def STORE8_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr, I32:$val), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000458 "i32.store8\t$dst, ${off}(${addr}), $val">;
Dan Gohmane3d7b582015-12-15 03:21:48 +0000459def STORE16_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr, I32:$val), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000460 "i32.store16\t$dst, ${off}(${addr}), $val">;
Dan Gohmane3d7b582015-12-15 03:21:48 +0000461def STORE8_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr, I64:$val), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000462 "i64.store8\t$dst, ${off}(${addr}), $val">;
Dan Gohmane3d7b582015-12-15 03:21:48 +0000463def STORE16_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr, I64:$val), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000464 "i64.store16\t$dst, ${off}(${addr}), $val">;
Dan Gohmane3d7b582015-12-15 03:21:48 +0000465def STORE32_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr, I64:$val), [],
Dan Gohmand587aa52015-12-21 16:58:49 +0000466 "i64.store32\t$dst, ${off}(${addr}), $val">;
Dan Gohman7054ac12015-11-23 21:16:35 +0000467
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000468} // Defs = [ARGUMENTS]
469
Dan Gohman4b9d7912015-12-15 22:01:29 +0000470// Select truncating stores with no constant offset.
Dan Gohman7054ac12015-11-23 21:16:35 +0000471def : Pat<(truncstorei8 I32:$val, I32:$addr),
Derek Schuff9d779522015-12-05 00:26:39 +0000472 (STORE8_I32 0, I32:$addr, I32:$val)>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000473def : Pat<(truncstorei16 I32:$val, I32:$addr),
Derek Schuff9d779522015-12-05 00:26:39 +0000474 (STORE16_I32 0, I32:$addr, I32:$val)>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000475def : Pat<(truncstorei8 I64:$val, I32:$addr),
Derek Schuff9d779522015-12-05 00:26:39 +0000476 (STORE8_I64 0, I32:$addr, I64:$val)>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000477def : Pat<(truncstorei16 I64:$val, I32:$addr),
Derek Schuff9d779522015-12-05 00:26:39 +0000478 (STORE16_I64 0, I32:$addr, I64:$val)>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000479def : Pat<(truncstorei32 I64:$val, I32:$addr),
Derek Schuff9d779522015-12-05 00:26:39 +0000480 (STORE32_I64 0, I32:$addr, I64:$val)>;
JF Bastien73ff6af2015-08-31 22:24:11 +0000481
Dan Gohman4b9d7912015-12-15 22:01:29 +0000482// Select truncating stores with a constant offset.
Dan Gohmanf225a632016-01-11 22:05:44 +0000483def : Pat<(truncstorei8 I32:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000484 (STORE8_I32 imm:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000485def : Pat<(truncstorei16 I32:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000486 (STORE16_I32 imm:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000487def : Pat<(truncstorei8 I64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000488 (STORE8_I64 imm:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000489def : Pat<(truncstorei16 I64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000490 (STORE16_I64 imm:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000491def : Pat<(truncstorei32 I64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000492 (STORE32_I64 imm:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000493def : Pat<(truncstorei8 I32:$val,
494 (regPlusGA I32:$addr,
495 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000496 (STORE8_I32 tglobaladdr:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000497def : Pat<(truncstorei16 I32:$val,
498 (regPlusGA I32:$addr,
499 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000500 (STORE16_I32 tglobaladdr:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000501def : Pat<(truncstorei8 I64:$val,
502 (regPlusGA I32:$addr,
503 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000504 (STORE8_I64 tglobaladdr:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000505def : Pat<(truncstorei16 I64:$val,
506 (regPlusGA I32:$addr,
507 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000508 (STORE16_I64 tglobaladdr:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000509def : Pat<(truncstorei32 I64:$val,
510 (regPlusGA I32:$addr,
511 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000512 (STORE32_I64 tglobaladdr:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000513def : Pat<(truncstorei8 I32:$val, (add I32:$addr,
514 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000515 (STORE8_I32 texternalsym:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000516def : Pat<(truncstorei16 I32:$val,
517 (add I32:$addr,
518 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000519 (STORE16_I32 texternalsym:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000520def : Pat<(truncstorei8 I64:$val,
521 (add I32:$addr,
522 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000523 (STORE8_I64 texternalsym:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000524def : Pat<(truncstorei16 I64:$val,
525 (add I32:$addr,
526 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000527 (STORE16_I64 texternalsym:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000528def : Pat<(truncstorei32 I64:$val,
529 (add I32:$addr,
530 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman4b9d7912015-12-15 22:01:29 +0000531 (STORE32_I64 texternalsym:$off, I32:$addr, I64:$val)>;
532
533// Select truncating stores with just a constant offset.
534def : Pat<(truncstorei8 I32:$val, imm:$off),
535 (STORE8_I32 imm:$off, (CONST_I32 0), I32:$val)>;
536def : Pat<(truncstorei16 I32:$val, imm:$off),
537 (STORE16_I32 imm:$off, (CONST_I32 0), I32:$val)>;
538def : Pat<(truncstorei8 I64:$val, imm:$off),
539 (STORE8_I64 imm:$off, (CONST_I32 0), I64:$val)>;
540def : Pat<(truncstorei16 I64:$val, imm:$off),
541 (STORE16_I64 imm:$off, (CONST_I32 0), I64:$val)>;
542def : Pat<(truncstorei32 I64:$val, imm:$off),
543 (STORE32_I64 imm:$off, (CONST_I32 0), I64:$val)>;
544def : Pat<(truncstorei8 I32:$val, (WebAssemblywrapper tglobaladdr:$off)),
545 (STORE8_I32 tglobaladdr:$off, (CONST_I32 0), I32:$val)>;
546def : Pat<(truncstorei16 I32:$val, (WebAssemblywrapper tglobaladdr:$off)),
547 (STORE16_I32 tglobaladdr:$off, (CONST_I32 0), I32:$val)>;
548def : Pat<(truncstorei8 I64:$val, (WebAssemblywrapper tglobaladdr:$off)),
549 (STORE8_I64 tglobaladdr:$off, (CONST_I32 0), I64:$val)>;
550def : Pat<(truncstorei16 I64:$val, (WebAssemblywrapper tglobaladdr:$off)),
551 (STORE16_I64 tglobaladdr:$off, (CONST_I32 0), I64:$val)>;
552def : Pat<(truncstorei32 I64:$val, (WebAssemblywrapper tglobaladdr:$off)),
553 (STORE32_I64 tglobaladdr:$off, (CONST_I32 0), I64:$val)>;
554def : Pat<(truncstorei8 I32:$val, (WebAssemblywrapper texternalsym:$off)),
555 (STORE8_I32 texternalsym:$off, (CONST_I32 0), I32:$val)>;
556def : Pat<(truncstorei16 I32:$val, (WebAssemblywrapper texternalsym:$off)),
557 (STORE16_I32 texternalsym:$off, (CONST_I32 0), I32:$val)>;
558def : Pat<(truncstorei8 I64:$val, (WebAssemblywrapper texternalsym:$off)),
559 (STORE8_I64 texternalsym:$off, (CONST_I32 0), I64:$val)>;
560def : Pat<(truncstorei16 I64:$val, (WebAssemblywrapper texternalsym:$off)),
561 (STORE16_I64 texternalsym:$off, (CONST_I32 0), I64:$val)>;
562def : Pat<(truncstorei32 I64:$val, (WebAssemblywrapper texternalsym:$off)),
563 (STORE32_I64 texternalsym:$off, (CONST_I32 0), I64:$val)>;
564
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000565let Defs = [ARGUMENTS] in {
566
Dan Gohman72f16922015-10-02 19:21:15 +0000567// Memory size.
Dan Gohmanf4333242015-11-13 20:19:11 +0000568def MEMORY_SIZE_I32 : I<(outs I32:$dst), (ins),
Dan Gohmanaf29bd42015-11-05 20:42:30 +0000569 [(set I32:$dst, (int_wasm_memory_size))],
Dan Gohman192dddc2015-11-23 22:37:29 +0000570 "memory_size\t$dst">,
Dan Gohman72f16922015-10-02 19:21:15 +0000571 Requires<[HasAddr32]>;
Dan Gohmanf4333242015-11-13 20:19:11 +0000572def MEMORY_SIZE_I64 : I<(outs I64:$dst), (ins),
Dan Gohmanaf29bd42015-11-05 20:42:30 +0000573 [(set I64:$dst, (int_wasm_memory_size))],
Dan Gohman192dddc2015-11-23 22:37:29 +0000574 "memory_size\t$dst">,
Dan Gohman72f16922015-10-02 19:21:15 +0000575 Requires<[HasAddr64]>;
Dan Gohmanbaba8c62015-10-02 20:10:26 +0000576
Dan Gohmand7ffb912015-11-05 20:16:59 +0000577// Grow memory.
Dan Gohmanf4333242015-11-13 20:19:11 +0000578def GROW_MEMORY_I32 : I<(outs), (ins I32:$delta),
Dan Gohmanaf29bd42015-11-05 20:42:30 +0000579 [(int_wasm_grow_memory I32:$delta)],
Dan Gohman192dddc2015-11-23 22:37:29 +0000580 "grow_memory\t$delta">,
Dan Gohmand7ffb912015-11-05 20:16:59 +0000581 Requires<[HasAddr32]>;
Dan Gohmanf4333242015-11-13 20:19:11 +0000582def GROW_MEMORY_I64 : I<(outs), (ins I64:$delta),
Dan Gohmanaf29bd42015-11-05 20:42:30 +0000583 [(int_wasm_grow_memory I64:$delta)],
Dan Gohman192dddc2015-11-23 22:37:29 +0000584 "grow_memory\t$delta">,
Dan Gohmand7ffb912015-11-05 20:16:59 +0000585 Requires<[HasAddr64]>;
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000586
587} // Defs = [ARGUMENTS]