// local types. These memory-only types instead zero- or sign-extend into local
// types when loading, and truncate when storing.
+let Defs = [ARGUMENTS] in {
+
// Basic load.
def LOAD_I32 : I<(outs I32:$dst), (ins I32:$addr),
[(set I32:$dst, (load I32:$addr))],
[(set I64:$dst, (zextloadi32 I32:$addr))],
"i64.load32_u\t$dst, $addr">;
+} // Defs = [ARGUMENTS]
+
// "Don't care" extending load become zero-extending load.
def : Pat<(i32 (extloadi8 I32:$addr)), (LOAD8_U_I32 $addr)>;
def : Pat<(i32 (extloadi16 I32:$addr)), (LOAD16_U_I32 $addr)>;
def : Pat<(i64 (extloadi16 I32:$addr)), (LOAD16_U_I64 $addr)>;
def : Pat<(i64 (extloadi32 I32:$addr)), (LOAD32_U_I64 $addr)>;
+let Defs = [ARGUMENTS] in {
+
// Basic store.
// Note that we split the patterns out of the instruction definitions because
// WebAssembly's stores return their operand value, and tablegen doesn't like
def STORE_F64 : I<(outs F64:$dst), (ins I32:$addr, F64:$val), [],
"f64.store\t$dst, $addr, $val">;
+} // Defs = [ARGUMENTS]
+
def : Pat<(store I32:$val, I32:$addr), (STORE_I32 I32:$addr, I32:$val)>;
def : Pat<(store I64:$val, I32:$addr), (STORE_I64 I32:$addr, I64:$val)>;
def : Pat<(store F32:$val, I32:$addr), (STORE_F32 I32:$addr, F32:$val)>;
def : Pat<(store F64:$val, I32:$addr), (STORE_F64 I32:$addr, F64:$val)>;
+let Defs = [ARGUMENTS] in {
+
// Truncating store.
def STORE8_I32 : I<(outs I32:$dst), (ins I32:$addr, I32:$val), [],
"i32.store8\t$dst, $addr, $val">;
def STORE32_I64 : I<(outs I64:$dst), (ins I32:$addr, I64:$val), [],
"i64.store32\t$dst, $addr, $val">;
+} // Defs = [ARGUMENTS]
+
def : Pat<(truncstorei8 I32:$val, I32:$addr),
(STORE8_I32 I32:$addr, I32:$val)>;
def : Pat<(truncstorei16 I32:$val, I32:$addr),
def : Pat<(truncstorei32 I64:$val, I32:$addr),
(STORE32_I64 I32:$addr, I64:$val)>;
+let Defs = [ARGUMENTS] in {
+
// Memory size.
def MEMORY_SIZE_I32 : I<(outs I32:$dst), (ins),
[(set I32:$dst, (int_wasm_memory_size))],
[(int_wasm_grow_memory I64:$delta)],
"grow_memory\t$delta">,
Requires<[HasAddr64]>;
+
+} // Defs = [ARGUMENTS]