blob: 25d77bb1f234315291e70b449a2b4e5ff08d8caa [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 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
36 APInt KnownZero0, KnownOne0;
37 CurDAG->computeKnownBits(N->getOperand(0), KnownZero0, KnownOne0, 0);
38 APInt KnownZero1, KnownOne1;
39 CurDAG->computeKnownBits(N->getOperand(1), KnownZero1, KnownOne1, 0);
40 return (~KnownZero0 & ~KnownZero1) == 0;
41}]>;
42
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 Schuff1b258d32016-08-31 20:27:20 +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
JF Bastien73ff6af2015-08-31 22:24:11 +000058// Basic load.
Dan Gohman48abaa92016-10-25 00:17:11 +000059// FIXME: When we can break syntax compatibility, reorder the fields in the
60// asmstrings to match the binary encoding.
61def LOAD_I32 : I<(outs I32:$dst),
Dan Gohman00d734d2016-12-23 03:23:52 +000062 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +000063 [], "i32.load\t$dst, ${off}(${addr})${p2align}", 0x28>;
64def LOAD_I64 : I<(outs I64:$dst),
Dan Gohman00d734d2016-12-23 03:23:52 +000065 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +000066 [], "i64.load\t$dst, ${off}(${addr})${p2align}", 0x29>;
67def LOAD_F32 : I<(outs F32:$dst),
Dan Gohman00d734d2016-12-23 03:23:52 +000068 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +000069 [], "f32.load\t$dst, ${off}(${addr})${p2align}", 0x2a>;
70def LOAD_F64 : I<(outs F64:$dst),
Dan Gohman00d734d2016-12-23 03:23:52 +000071 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +000072 [], "f64.load\t$dst, ${off}(${addr})${p2align}", 0x2b>;
JF Bastien73ff6af2015-08-31 22:24:11 +000073
Dan Gohman4b9d7912015-12-15 22:01:29 +000074} // Defs = [ARGUMENTS]
75
76// Select loads with no constant offset.
Dan Gohman48abaa92016-10-25 00:17:11 +000077def : Pat<(i32 (load I32:$addr)), (LOAD_I32 0, 0, $addr)>;
78def : Pat<(i64 (load I32:$addr)), (LOAD_I64 0, 0, $addr)>;
79def : Pat<(f32 (load I32:$addr)), (LOAD_F32 0, 0, $addr)>;
80def : Pat<(f64 (load I32:$addr)), (LOAD_F64 0, 0, $addr)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +000081
82// Select loads with a constant offset.
Dan Gohmanf225a632016-01-11 22:05:44 +000083def : Pat<(i32 (load (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +000084 (LOAD_I32 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000085def : Pat<(i64 (load (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +000086 (LOAD_I64 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000087def : Pat<(f32 (load (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +000088 (LOAD_F32 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000089def : Pat<(f64 (load (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +000090 (LOAD_F64 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +000091def : Pat<(i32 (load (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +000092 (LOAD_I32 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +000093def : Pat<(i64 (load (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +000094 (LOAD_I64 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +000095def : Pat<(f32 (load (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +000096 (LOAD_F32 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +000097def : Pat<(f64 (load (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +000098 (LOAD_F64 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +000099def : Pat<(i32 (load (regPlusGA I32:$addr,
100 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000101 (LOAD_I32 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000102def : Pat<(i64 (load (regPlusGA I32:$addr,
103 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000104 (LOAD_I64 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000105def : Pat<(f32 (load (regPlusGA I32:$addr,
106 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000107 (LOAD_F32 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000108def : Pat<(f64 (load (regPlusGA I32:$addr,
109 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000110 (LOAD_F64 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000111def : Pat<(i32 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000112 (LOAD_I32 0, texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000113def : Pat<(i64 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000114 (LOAD_I64 0, texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000115def : Pat<(f32 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000116 (LOAD_F32 0, texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000117def : Pat<(f64 (load (add I32:$addr, (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000118 (LOAD_F64 0, texternalsym:$off, $addr)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000119
120// Select loads with just a constant offset.
Dan Gohman48abaa92016-10-25 00:17:11 +0000121def : Pat<(i32 (load imm:$off)), (LOAD_I32 0, imm:$off, (CONST_I32 0))>;
122def : Pat<(i64 (load imm:$off)), (LOAD_I64 0, imm:$off, (CONST_I32 0))>;
123def : Pat<(f32 (load imm:$off)), (LOAD_F32 0, imm:$off, (CONST_I32 0))>;
124def : Pat<(f64 (load imm:$off)), (LOAD_F64 0, imm:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000125def : Pat<(i32 (load (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000126 (LOAD_I32 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000127def : Pat<(i64 (load (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000128 (LOAD_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000129def : Pat<(f32 (load (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000130 (LOAD_F32 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000131def : Pat<(f64 (load (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000132 (LOAD_F64 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000133def : Pat<(i32 (load (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000134 (LOAD_I32 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000135def : Pat<(i64 (load (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000136 (LOAD_I64 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000137def : Pat<(f32 (load (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000138 (LOAD_F32 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000139def : Pat<(f64 (load (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000140 (LOAD_F64 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000141
142let Defs = [ARGUMENTS] in {
143
JF Bastien73ff6af2015-08-31 22:24:11 +0000144// Extending load.
Dan Gohman48abaa92016-10-25 00:17:11 +0000145def LOAD8_S_I32 : I<(outs I32:$dst),
Dan Gohman00d734d2016-12-23 03:23:52 +0000146 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000147 [], "i32.load8_s\t$dst, ${off}(${addr})${p2align}", 0x2c>;
148def LOAD8_U_I32 : I<(outs I32:$dst),
Dan Gohman00d734d2016-12-23 03:23:52 +0000149 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000150 [], "i32.load8_u\t$dst, ${off}(${addr})${p2align}", 0x2d>;
151def LOAD16_S_I32 : I<(outs I32:$dst),
Dan Gohman00d734d2016-12-23 03:23:52 +0000152 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000153 [], "i32.load16_s\t$dst, ${off}(${addr})${p2align}", 0x2e>;
154def LOAD16_U_I32 : I<(outs I32:$dst),
Dan Gohman00d734d2016-12-23 03:23:52 +0000155 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000156 [], "i32.load16_u\t$dst, ${off}(${addr})${p2align}", 0x2f>;
157def LOAD8_S_I64 : I<(outs I64:$dst),
Dan Gohman00d734d2016-12-23 03:23:52 +0000158 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000159 [], "i64.load8_s\t$dst, ${off}(${addr})${p2align}", 0x30>;
160def LOAD8_U_I64 : I<(outs I64:$dst),
Dan Gohman00d734d2016-12-23 03:23:52 +0000161 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000162 [], "i64.load8_u\t$dst, ${off}(${addr})${p2align}", 0x31>;
163def LOAD16_S_I64 : I<(outs I64:$dst),
Dan Gohman00d734d2016-12-23 03:23:52 +0000164 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000165 [], "i64.load16_s\t$dst, ${off}(${addr})${p2align}", 0x32>;
166def LOAD16_U_I64 : I<(outs I64:$dst),
Dan Gohman00d734d2016-12-23 03:23:52 +0000167 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000168 [], "i64.load16_u\t$dst, ${off}(${addr})${p2align}", 0x33>;
169def LOAD32_S_I64 : I<(outs I64:$dst),
Dan Gohman00d734d2016-12-23 03:23:52 +0000170 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000171 [], "i64.load32_s\t$dst, ${off}(${addr})${p2align}", 0x34>;
172def LOAD32_U_I64 : I<(outs I64:$dst),
Dan Gohman00d734d2016-12-23 03:23:52 +0000173 (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000174 [], "i64.load32_u\t$dst, ${off}(${addr})${p2align}", 0x35>;
JF Bastien73ff6af2015-08-31 22:24:11 +0000175
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000176} // Defs = [ARGUMENTS]
177
Derek Schuff9d779522015-12-05 00:26:39 +0000178// Select extending loads with no constant offset.
Dan Gohman48abaa92016-10-25 00:17:11 +0000179def : Pat<(i32 (sextloadi8 I32:$addr)), (LOAD8_S_I32 0, 0, $addr)>;
180def : Pat<(i32 (zextloadi8 I32:$addr)), (LOAD8_U_I32 0, 0, $addr)>;
181def : Pat<(i32 (sextloadi16 I32:$addr)), (LOAD16_S_I32 0, 0, $addr)>;
182def : Pat<(i32 (zextloadi16 I32:$addr)), (LOAD16_U_I32 0, 0, $addr)>;
183def : Pat<(i64 (sextloadi8 I32:$addr)), (LOAD8_S_I64 0, 0, $addr)>;
184def : Pat<(i64 (zextloadi8 I32:$addr)), (LOAD8_U_I64 0, 0, $addr)>;
185def : Pat<(i64 (sextloadi16 I32:$addr)), (LOAD16_S_I64 0, 0, $addr)>;
186def : Pat<(i64 (zextloadi16 I32:$addr)), (LOAD16_U_I64 0, 0, $addr)>;
187def : Pat<(i64 (sextloadi32 I32:$addr)), (LOAD32_S_I64 0, 0, $addr)>;
188def : Pat<(i64 (zextloadi32 I32:$addr)), (LOAD32_U_I64 0, 0, $addr)>;
Derek Schuff9d779522015-12-05 00:26:39 +0000189
Dan Gohman4b9d7912015-12-15 22:01:29 +0000190// Select extending loads with a constant offset.
Dan Gohmanf225a632016-01-11 22:05:44 +0000191def : Pat<(i32 (sextloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000192 (LOAD8_S_I32 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000193def : Pat<(i32 (zextloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000194 (LOAD8_U_I32 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000195def : Pat<(i32 (sextloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000196 (LOAD16_S_I32 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000197def : Pat<(i32 (zextloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000198 (LOAD16_U_I32 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000199def : Pat<(i64 (sextloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000200 (LOAD8_S_I64 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000201def : Pat<(i64 (zextloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000202 (LOAD8_U_I64 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000203def : Pat<(i64 (sextloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000204 (LOAD16_S_I64 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000205def : Pat<(i64 (zextloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000206 (LOAD16_U_I64 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000207def : Pat<(i64 (sextloadi32 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000208 (LOAD32_S_I64 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000209def : Pat<(i64 (zextloadi32 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000210 (LOAD32_U_I64 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000211def : Pat<(i32 (sextloadi8 (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000212 (LOAD8_S_I32 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000213def : Pat<(i32 (zextloadi8 (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000214 (LOAD8_U_I32 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000215def : Pat<(i32 (sextloadi16 (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000216 (LOAD16_S_I32 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000217def : Pat<(i32 (zextloadi16 (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000218 (LOAD16_U_I32 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000219def : Pat<(i64 (sextloadi8 (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000220 (LOAD8_S_I64 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000221def : Pat<(i64 (zextloadi8 (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000222 (LOAD8_U_I64 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000223def : Pat<(i64 (sextloadi16 (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000224 (LOAD16_S_I64 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000225def : Pat<(i64 (zextloadi16 (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000226 (LOAD16_U_I64 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000227def : Pat<(i64 (sextloadi32 (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000228 (LOAD32_S_I64 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000229def : Pat<(i64 (zextloadi32 (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000230 (LOAD32_U_I64 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000231def : Pat<(i32 (sextloadi8 (regPlusGA I32:$addr,
232 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000233 (LOAD8_S_I32 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000234def : Pat<(i32 (zextloadi8 (regPlusGA I32:$addr,
235 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000236 (LOAD8_U_I32 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000237def : Pat<(i32 (sextloadi16 (regPlusGA I32:$addr,
238 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000239 (LOAD16_S_I32 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000240def : Pat<(i32 (zextloadi16 (regPlusGA I32:$addr,
241 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000242 (LOAD16_U_I32 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000243def : Pat<(i64 (sextloadi8 (regPlusGA I32:$addr,
244 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000245 (LOAD8_S_I64 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000246def : Pat<(i64 (zextloadi8 (regPlusGA I32:$addr,
247 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000248 (LOAD8_U_I64 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000249def : Pat<(i64 (sextloadi16 (regPlusGA I32:$addr,
250 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000251 (LOAD16_S_I64 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000252def : Pat<(i64 (zextloadi16 (regPlusGA I32:$addr,
253 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000254 (LOAD16_U_I64 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000255def : Pat<(i64 (sextloadi32 (regPlusGA I32:$addr,
256 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000257 (LOAD32_S_I64 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000258def : Pat<(i64 (zextloadi32 (regPlusGA I32:$addr,
259 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000260 (LOAD32_U_I64 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000261def : Pat<(i32 (sextloadi8 (add I32:$addr,
262 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000263 (LOAD8_S_I32 0, texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000264def : Pat<(i32 (zextloadi8 (add I32:$addr,
265 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000266 (LOAD8_U_I32 0, texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000267def : Pat<(i32 (sextloadi16 (add I32:$addr,
268 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000269 (LOAD16_S_I32 0, texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000270def : Pat<(i32 (zextloadi16 (add I32:$addr,
271 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000272 (LOAD16_U_I32 0, texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000273def : Pat<(i64 (sextloadi8 (add I32:$addr,
274 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000275 (LOAD8_S_I64 0, texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000276def : Pat<(i64 (zextloadi8 (add I32:$addr,
277 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000278 (LOAD8_U_I64 0, texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000279def : Pat<(i64 (sextloadi16 (add I32:$addr,
280 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000281 (LOAD16_S_I64 0, texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000282def : Pat<(i64 (zextloadi16 (add I32:$addr,
283 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000284 (LOAD16_U_I64 0, texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000285def : Pat<(i64 (sextloadi32 (add I32:$addr,
286 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000287 (LOAD32_S_I64 0, texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000288def : Pat<(i64 (zextloadi32 (add I32:$addr,
289 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000290 (LOAD32_U_I64 0, texternalsym:$off, $addr)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000291
292// Select extending loads with just a constant offset.
Dan Gohmanbb372242016-01-26 03:39:31 +0000293def : Pat<(i32 (sextloadi8 imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000294 (LOAD8_S_I32 0, imm:$off, (CONST_I32 0))>;
Dan Gohmanbb372242016-01-26 03:39:31 +0000295def : Pat<(i32 (zextloadi8 imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000296 (LOAD8_U_I32 0, imm:$off, (CONST_I32 0))>;
Dan Gohmanbb372242016-01-26 03:39:31 +0000297def : Pat<(i32 (sextloadi16 imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000298 (LOAD16_S_I32 0, imm:$off, (CONST_I32 0))>;
Dan Gohmanbb372242016-01-26 03:39:31 +0000299def : Pat<(i32 (zextloadi16 imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000300 (LOAD16_U_I32 0, imm:$off, (CONST_I32 0))>;
Dan Gohmanbb372242016-01-26 03:39:31 +0000301def : Pat<(i64 (sextloadi8 imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000302 (LOAD8_S_I64 0, imm:$off, (CONST_I32 0))>;
Dan Gohmanbb372242016-01-26 03:39:31 +0000303def : Pat<(i64 (zextloadi8 imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000304 (LOAD8_U_I64 0, imm:$off, (CONST_I32 0))>;
Dan Gohmanbb372242016-01-26 03:39:31 +0000305def : Pat<(i64 (sextloadi16 imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000306 (LOAD16_S_I64 0, imm:$off, (CONST_I32 0))>;
Dan Gohmanbb372242016-01-26 03:39:31 +0000307def : Pat<(i64 (zextloadi16 imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000308 (LOAD16_U_I64 0, imm:$off, (CONST_I32 0))>;
Dan Gohmanbb372242016-01-26 03:39:31 +0000309def : Pat<(i64 (sextloadi32 imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000310 (LOAD32_S_I64 0, imm:$off, (CONST_I32 0))>;
Dan Gohmanbb372242016-01-26 03:39:31 +0000311def : Pat<(i64 (zextloadi32 imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000312 (LOAD32_U_I64 0, imm:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000313def : Pat<(i32 (sextloadi8 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000314 (LOAD8_S_I32 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000315def : Pat<(i32 (zextloadi8 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000316 (LOAD8_U_I32 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000317def : Pat<(i32 (sextloadi16 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000318 (LOAD16_S_I32 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000319def : Pat<(i32 (zextloadi16 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000320 (LOAD16_U_I32 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000321def : Pat<(i64 (sextloadi8 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000322 (LOAD8_S_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000323def : Pat<(i64 (zextloadi8 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000324 (LOAD8_U_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000325def : Pat<(i64 (sextloadi16 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000326 (LOAD16_S_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000327def : Pat<(i64 (zextloadi16 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000328 (LOAD16_U_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000329def : Pat<(i64 (sextloadi32 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000330 (LOAD32_S_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000331def : Pat<(i64 (zextloadi32 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000332 (LOAD32_U_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000333def : Pat<(i32 (sextloadi8 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000334 (LOAD8_S_I32 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000335def : Pat<(i32 (zextloadi8 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000336 (LOAD8_U_I32 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000337def : Pat<(i32 (sextloadi16 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000338 (LOAD16_S_I32 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000339def : Pat<(i32 (zextloadi16 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000340 (LOAD16_U_I32 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000341def : Pat<(i64 (sextloadi8 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000342 (LOAD8_S_I64 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000343def : Pat<(i64 (zextloadi8 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000344 (LOAD8_U_I64 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000345def : Pat<(i64 (sextloadi16 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000346 (LOAD16_S_I64 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000347def : Pat<(i64 (zextloadi16 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000348 (LOAD16_U_I64 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000349def : Pat<(i64 (sextloadi32 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000350 (LOAD32_S_I64 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000351def : Pat<(i64 (zextloadi32 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000352 (LOAD32_U_I64 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000353
354// Resolve "don't care" extending loads to zero-extending loads. This is
355// somewhat arbitrary, but zero-extending is conceptually simpler.
356
357// Select "don't care" extending loads with no constant offset.
Dan Gohman48abaa92016-10-25 00:17:11 +0000358def : Pat<(i32 (extloadi8 I32:$addr)), (LOAD8_U_I32 0, 0, $addr)>;
359def : Pat<(i32 (extloadi16 I32:$addr)), (LOAD16_U_I32 0, 0, $addr)>;
360def : Pat<(i64 (extloadi8 I32:$addr)), (LOAD8_U_I64 0, 0, $addr)>;
361def : Pat<(i64 (extloadi16 I32:$addr)), (LOAD16_U_I64 0, 0, $addr)>;
362def : Pat<(i64 (extloadi32 I32:$addr)), (LOAD32_U_I64 0, 0, $addr)>;
JF Bastien73ff6af2015-08-31 22:24:11 +0000363
Dan Gohman4b9d7912015-12-15 22:01:29 +0000364// Select "don't care" extending loads with a constant offset.
Dan Gohmanf225a632016-01-11 22:05:44 +0000365def : Pat<(i32 (extloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000366 (LOAD8_U_I32 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000367def : Pat<(i32 (extloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000368 (LOAD16_U_I32 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000369def : Pat<(i64 (extloadi8 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000370 (LOAD8_U_I64 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000371def : Pat<(i64 (extloadi16 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000372 (LOAD16_U_I64 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000373def : Pat<(i64 (extloadi32 (regPlusImm I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000374 (LOAD32_U_I64 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000375def : Pat<(i32 (extloadi8 (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000376 (LOAD8_U_I32 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000377def : Pat<(i32 (extloadi16 (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000378 (LOAD16_U_I32 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000379def : Pat<(i64 (extloadi8 (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000380 (LOAD8_U_I64 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000381def : Pat<(i64 (extloadi16 (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000382 (LOAD16_U_I64 0, imm:$off, $addr)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000383def : Pat<(i64 (extloadi32 (or_is_add I32:$addr, imm:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000384 (LOAD32_U_I64 0, imm:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000385def : Pat<(i32 (extloadi8 (regPlusGA I32:$addr,
386 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000387 (LOAD8_U_I32 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000388def : Pat<(i32 (extloadi16 (regPlusGA I32:$addr,
389 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000390 (LOAD16_U_I32 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000391def : Pat<(i64 (extloadi8 (regPlusGA I32:$addr,
392 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000393 (LOAD8_U_I64 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000394def : Pat<(i64 (extloadi16 (regPlusGA I32:$addr,
395 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000396 (LOAD16_U_I64 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000397def : Pat<(i64 (extloadi32 (regPlusGA I32:$addr,
398 (WebAssemblywrapper tglobaladdr:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000399 (LOAD32_U_I64 0, tglobaladdr:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000400def : Pat<(i32 (extloadi8 (add I32:$addr,
401 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000402 (LOAD8_U_I32 0, texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000403def : Pat<(i32 (extloadi16 (add I32:$addr,
404 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000405 (LOAD16_U_I32 0, texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000406def : Pat<(i64 (extloadi8 (add I32:$addr,
407 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000408 (LOAD8_U_I64 0, texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000409def : Pat<(i64 (extloadi16 (add I32:$addr,
410 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000411 (LOAD16_U_I64 0, texternalsym:$off, $addr)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000412def : Pat<(i64 (extloadi32 (add I32:$addr,
413 (WebAssemblywrapper texternalsym:$off)))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000414 (LOAD32_U_I64 0, texternalsym:$off, $addr)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000415
416// Select "don't care" extending loads with just a constant offset.
Dan Gohmanbb372242016-01-26 03:39:31 +0000417def : Pat<(i32 (extloadi8 imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000418 (LOAD8_U_I32 0, imm:$off, (CONST_I32 0))>;
Dan Gohmanbb372242016-01-26 03:39:31 +0000419def : Pat<(i32 (extloadi16 imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000420 (LOAD16_U_I32 0, imm:$off, (CONST_I32 0))>;
Dan Gohmanbb372242016-01-26 03:39:31 +0000421def : Pat<(i64 (extloadi8 imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000422 (LOAD8_U_I64 0, imm:$off, (CONST_I32 0))>;
Dan Gohmanbb372242016-01-26 03:39:31 +0000423def : Pat<(i64 (extloadi16 imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000424 (LOAD16_U_I64 0, imm:$off, (CONST_I32 0))>;
Dan Gohmanbb372242016-01-26 03:39:31 +0000425def : Pat<(i64 (extloadi32 imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000426 (LOAD32_U_I64 0, imm:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000427def : Pat<(i32 (extloadi8 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000428 (LOAD8_U_I32 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000429def : Pat<(i32 (extloadi16 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000430 (LOAD16_U_I32 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000431def : Pat<(i64 (extloadi8 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000432 (LOAD8_U_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000433def : Pat<(i64 (extloadi16 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000434 (LOAD16_U_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000435def : Pat<(i64 (extloadi32 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000436 (LOAD32_U_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000437def : Pat<(i32 (extloadi8 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000438 (LOAD8_U_I32 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000439def : Pat<(i32 (extloadi16 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000440 (LOAD16_U_I32 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000441def : Pat<(i64 (extloadi8 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000442 (LOAD8_U_I64 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000443def : Pat<(i64 (extloadi16 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000444 (LOAD16_U_I64 0, texternalsym:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000445def : Pat<(i64 (extloadi32 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000446 (LOAD32_U_I64 0, tglobaladdr:$off, (CONST_I32 0))>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000447
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000448let Defs = [ARGUMENTS] in {
449
JF Bastien73ff6af2015-08-31 22:24:11 +0000450// Basic store.
451// Note: WebAssembly inverts SelectionDAG's usual operand order.
Dan Gohman00d734d2016-12-23 03:23:52 +0000452def STORE_I32 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000453 I32:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000454 "i32.store\t${off}(${addr})${p2align}, $val", 0x36>;
Dan Gohman00d734d2016-12-23 03:23:52 +0000455def STORE_I64 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000456 I64:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000457 "i64.store\t${off}(${addr})${p2align}, $val", 0x37>;
Dan Gohman00d734d2016-12-23 03:23:52 +0000458def STORE_F32 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000459 F32:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000460 "f32.store\t${off}(${addr})${p2align}, $val", 0x38>;
Dan Gohman00d734d2016-12-23 03:23:52 +0000461def STORE_F64 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000462 F64:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000463 "f64.store\t${off}(${addr})${p2align}, $val", 0x39>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000464
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000465} // Defs = [ARGUMENTS]
466
Dan Gohman4b9d7912015-12-15 22:01:29 +0000467// Select stores with no constant offset.
Dan Gohman48abaa92016-10-25 00:17:11 +0000468def : Pat<(store I32:$val, I32:$addr), (STORE_I32 0, 0, I32:$addr, I32:$val)>;
469def : Pat<(store I64:$val, I32:$addr), (STORE_I64 0, 0, I32:$addr, I64:$val)>;
470def : Pat<(store F32:$val, I32:$addr), (STORE_F32 0, 0, I32:$addr, F32:$val)>;
471def : Pat<(store F64:$val, I32:$addr), (STORE_F64 0, 0, I32:$addr, F64:$val)>;
Derek Schuff9d779522015-12-05 00:26:39 +0000472
Dan Gohman4b9d7912015-12-15 22:01:29 +0000473// Select stores with a constant offset.
Dan Gohmanf225a632016-01-11 22:05:44 +0000474def : Pat<(store I32:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000475 (STORE_I32 0, imm:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000476def : Pat<(store I64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000477 (STORE_I64 0, imm:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000478def : Pat<(store F32:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000479 (STORE_F32 0, imm:$off, I32:$addr, F32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000480def : Pat<(store F64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000481 (STORE_F64 0, imm:$off, I32:$addr, F64:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000482def : Pat<(store I32:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000483 (STORE_I32 0, imm:$off, I32:$addr, I32:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000484def : Pat<(store I64:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000485 (STORE_I64 0, imm:$off, I32:$addr, I64:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000486def : Pat<(store F32:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000487 (STORE_F32 0, imm:$off, I32:$addr, F32:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000488def : Pat<(store F64:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000489 (STORE_F64 0, imm:$off, I32:$addr, F64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000490def : Pat<(store I32:$val, (regPlusGA I32:$addr,
491 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000492 (STORE_I32 0, tglobaladdr:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000493def : Pat<(store I64:$val, (regPlusGA I32:$addr,
494 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000495 (STORE_I64 0, tglobaladdr:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000496def : Pat<(store F32:$val, (regPlusGA I32:$addr,
497 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000498 (STORE_F32 0, tglobaladdr:$off, I32:$addr, F32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000499def : Pat<(store F64:$val, (regPlusGA I32:$addr,
500 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000501 (STORE_F64 0, tglobaladdr:$off, I32:$addr, F64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000502def : Pat<(store I32:$val, (add I32:$addr,
503 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000504 (STORE_I32 0, texternalsym:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000505def : Pat<(store I64:$val, (add I32:$addr,
506 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000507 (STORE_I64 0, texternalsym:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000508def : Pat<(store F32:$val, (add I32:$addr,
509 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000510 (STORE_F32 0, texternalsym:$off, I32:$addr, F32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000511def : Pat<(store F64:$val, (add I32:$addr,
512 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000513 (STORE_F64 0, texternalsym:$off, I32:$addr, F64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000514
515// Select stores with just a constant offset.
516def : Pat<(store I32:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000517 (STORE_I32 0, imm:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000518def : Pat<(store I64:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000519 (STORE_I64 0, imm:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000520def : Pat<(store F32:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000521 (STORE_F32 0, imm:$off, (CONST_I32 0), F32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000522def : Pat<(store F64:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000523 (STORE_F64 0, imm:$off, (CONST_I32 0), F64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000524def : Pat<(store I32:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000525 (STORE_I32 0, tglobaladdr:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000526def : Pat<(store I64:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000527 (STORE_I64 0, tglobaladdr:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000528def : Pat<(store F32:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000529 (STORE_F32 0, tglobaladdr:$off, (CONST_I32 0), F32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000530def : Pat<(store F64:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000531 (STORE_F64 0, tglobaladdr:$off, (CONST_I32 0), F64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000532def : Pat<(store I32:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000533 (STORE_I32 0, texternalsym:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000534def : Pat<(store I64:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000535 (STORE_I64 0, texternalsym:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000536def : Pat<(store F32:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000537 (STORE_F32 0, texternalsym:$off, (CONST_I32 0), F32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000538def : Pat<(store F64:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000539 (STORE_F64 0, texternalsym:$off, (CONST_I32 0), F64:$val)>;
JF Bastien73ff6af2015-08-31 22:24:11 +0000540
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000541let Defs = [ARGUMENTS] in {
542
JF Bastien73ff6af2015-08-31 22:24:11 +0000543// Truncating store.
Dan Gohman00d734d2016-12-23 03:23:52 +0000544def STORE8_I32 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000545 I32:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000546 "i32.store8\t${off}(${addr})${p2align}, $val", 0x3a>;
Dan Gohman00d734d2016-12-23 03:23:52 +0000547def STORE16_I32 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000548 I32:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000549 "i32.store16\t${off}(${addr})${p2align}, $val", 0x3b>;
Dan Gohman00d734d2016-12-23 03:23:52 +0000550def STORE8_I64 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000551 I64:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000552 "i64.store8\t${off}(${addr})${p2align}, $val", 0x3c>;
Dan Gohman00d734d2016-12-23 03:23:52 +0000553def STORE16_I64 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000554 I64:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000555 "i64.store16\t${off}(${addr})${p2align}, $val", 0x3d>;
Dan Gohman00d734d2016-12-23 03:23:52 +0000556def STORE32_I64 : I<(outs), (ins P2Align:$p2align, offset32_op:$off, I32:$addr,
Dan Gohman48abaa92016-10-25 00:17:11 +0000557 I64:$val), [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000558 "i64.store32\t${off}(${addr})${p2align}, $val", 0x3e>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000559
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000560} // Defs = [ARGUMENTS]
561
Dan Gohman4b9d7912015-12-15 22:01:29 +0000562// Select truncating stores with no constant offset.
Dan Gohman7054ac12015-11-23 21:16:35 +0000563def : Pat<(truncstorei8 I32:$val, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000564 (STORE8_I32 0, 0, I32:$addr, I32:$val)>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000565def : Pat<(truncstorei16 I32:$val, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000566 (STORE16_I32 0, 0, I32:$addr, I32:$val)>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000567def : Pat<(truncstorei8 I64:$val, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000568 (STORE8_I64 0, 0, I32:$addr, I64:$val)>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000569def : Pat<(truncstorei16 I64:$val, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000570 (STORE16_I64 0, 0, I32:$addr, I64:$val)>;
Dan Gohman7054ac12015-11-23 21:16:35 +0000571def : Pat<(truncstorei32 I64:$val, I32:$addr),
Dan Gohman48abaa92016-10-25 00:17:11 +0000572 (STORE32_I64 0, 0, I32:$addr, I64:$val)>;
JF Bastien73ff6af2015-08-31 22:24:11 +0000573
Dan Gohman4b9d7912015-12-15 22:01:29 +0000574// Select truncating stores with a constant offset.
Dan Gohmanf225a632016-01-11 22:05:44 +0000575def : Pat<(truncstorei8 I32:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000576 (STORE8_I32 0, imm:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000577def : Pat<(truncstorei16 I32:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000578 (STORE16_I32 0, imm:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000579def : Pat<(truncstorei8 I64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000580 (STORE8_I64 0, imm:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000581def : Pat<(truncstorei16 I64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000582 (STORE16_I64 0, imm:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000583def : Pat<(truncstorei32 I64:$val, (regPlusImm I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000584 (STORE32_I64 0, imm:$off, I32:$addr, I64:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000585def : Pat<(truncstorei8 I32:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000586 (STORE8_I32 0, imm:$off, I32:$addr, I32:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000587def : Pat<(truncstorei16 I32:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000588 (STORE16_I32 0, imm:$off, I32:$addr, I32:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000589def : Pat<(truncstorei8 I64:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000590 (STORE8_I64 0, imm:$off, I32:$addr, I64:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000591def : Pat<(truncstorei16 I64:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000592 (STORE16_I64 0, imm:$off, I32:$addr, I64:$val)>;
Dan Gohman3b09d272016-02-22 20:04:02 +0000593def : Pat<(truncstorei32 I64:$val, (or_is_add I32:$addr, imm:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000594 (STORE32_I64 0, imm:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000595def : Pat<(truncstorei8 I32:$val,
596 (regPlusGA I32:$addr,
597 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000598 (STORE8_I32 0, tglobaladdr:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000599def : Pat<(truncstorei16 I32:$val,
600 (regPlusGA I32:$addr,
601 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000602 (STORE16_I32 0, tglobaladdr:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000603def : Pat<(truncstorei8 I64:$val,
604 (regPlusGA I32:$addr,
605 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000606 (STORE8_I64 0, tglobaladdr:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000607def : Pat<(truncstorei16 I64:$val,
608 (regPlusGA I32:$addr,
609 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000610 (STORE16_I64 0, tglobaladdr:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000611def : Pat<(truncstorei32 I64:$val,
612 (regPlusGA I32:$addr,
613 (WebAssemblywrapper tglobaladdr:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000614 (STORE32_I64 0, tglobaladdr:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000615def : Pat<(truncstorei8 I32:$val, (add I32:$addr,
616 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000617 (STORE8_I32 0, texternalsym:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000618def : Pat<(truncstorei16 I32:$val,
619 (add I32:$addr,
620 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000621 (STORE16_I32 0, texternalsym:$off, I32:$addr, I32:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000622def : Pat<(truncstorei8 I64:$val,
623 (add I32:$addr,
624 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000625 (STORE8_I64 0, texternalsym:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000626def : Pat<(truncstorei16 I64:$val,
627 (add I32:$addr,
628 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000629 (STORE16_I64 0, texternalsym:$off, I32:$addr, I64:$val)>;
Dan Gohmanf225a632016-01-11 22:05:44 +0000630def : Pat<(truncstorei32 I64:$val,
631 (add I32:$addr,
632 (WebAssemblywrapper texternalsym:$off))),
Dan Gohman48abaa92016-10-25 00:17:11 +0000633 (STORE32_I64 0, texternalsym:$off, I32:$addr, I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000634
635// Select truncating stores with just a constant offset.
636def : Pat<(truncstorei8 I32:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000637 (STORE8_I32 0, imm:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000638def : Pat<(truncstorei16 I32:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000639 (STORE16_I32 0, imm:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000640def : Pat<(truncstorei8 I64:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000641 (STORE8_I64 0, imm:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000642def : Pat<(truncstorei16 I64:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000643 (STORE16_I64 0, imm:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000644def : Pat<(truncstorei32 I64:$val, imm:$off),
Dan Gohman48abaa92016-10-25 00:17:11 +0000645 (STORE32_I64 0, imm:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000646def : Pat<(truncstorei8 I32:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000647 (STORE8_I32 0, tglobaladdr:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000648def : Pat<(truncstorei16 I32:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000649 (STORE16_I32 0, tglobaladdr:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000650def : Pat<(truncstorei8 I64:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000651 (STORE8_I64 0, tglobaladdr:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000652def : Pat<(truncstorei16 I64:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000653 (STORE16_I64 0, tglobaladdr:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000654def : Pat<(truncstorei32 I64:$val, (WebAssemblywrapper tglobaladdr:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000655 (STORE32_I64 0, tglobaladdr:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000656def : Pat<(truncstorei8 I32:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000657 (STORE8_I32 0, texternalsym:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000658def : Pat<(truncstorei16 I32:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000659 (STORE16_I32 0, texternalsym:$off, (CONST_I32 0), I32:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000660def : Pat<(truncstorei8 I64:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000661 (STORE8_I64 0, texternalsym:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000662def : Pat<(truncstorei16 I64:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000663 (STORE16_I64 0, texternalsym:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000664def : Pat<(truncstorei32 I64:$val, (WebAssemblywrapper texternalsym:$off)),
Dan Gohman48abaa92016-10-25 00:17:11 +0000665 (STORE32_I64 0, texternalsym:$off, (CONST_I32 0), I64:$val)>;
Dan Gohman4b9d7912015-12-15 22:01:29 +0000666
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000667let Defs = [ARGUMENTS] in {
668
Derek Schuff31680dd2016-05-02 17:25:22 +0000669// Current memory size.
Dan Gohmanf50d9642016-10-25 16:55:52 +0000670def CURRENT_MEMORY_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
671 [],
Dan Gohmanc9682972016-10-24 20:21:49 +0000672 "current_memory\t$dst", 0x3f>,
Derek Schuff31680dd2016-05-02 17:25:22 +0000673 Requires<[HasAddr32]>;
Dan Gohmanbaba8c62015-10-02 20:10:26 +0000674
Dan Gohmand7ffb912015-11-05 20:16:59 +0000675// Grow memory.
Dan Gohman73e3aaa2017-01-18 01:02:45 +0000676def GROW_MEMORY_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
Dan Gohmanf50d9642016-10-25 16:55:52 +0000677 [],
Dan Gohman73e3aaa2017-01-18 01:02:45 +0000678 "grow_memory\t$dst, $delta", 0x40>,
Dan Gohmand7ffb912015-11-05 20:16:59 +0000679 Requires<[HasAddr32]>;
Dan Gohmanfb3e0592015-11-25 19:36:19 +0000680
681} // Defs = [ARGUMENTS]
Dan Gohmanf50d9642016-10-25 16:55:52 +0000682
683def : Pat<(int_wasm_current_memory),
684 (CURRENT_MEMORY_I32 0)>;
685def : Pat<(int_wasm_grow_memory I32:$delta),
686 (GROW_MEMORY_I32 0, $delta)>;