1// 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 15/* 16 * TODO(jfb): Add the following. 17 * 18 * load_global: load the value of a given global variable 19 * store_global: store a given value to a given global variable 20 */ 21 22// FIXME: 23// - HasAddr64 24// - WebAssemblyTargetLowering::isLegalAddressingMode 25// - WebAssemblyTargetLowering having to do with atomics 26// - Each has optional alignment and immediate byte offset. 27 28// WebAssembly has i8/i16/i32/i64/f32/f64 memory types, but doesn't have i8/i16 29// local types. These memory-only types instead zero- or sign-extend into local 30// types when loading, and truncate when storing. 31 32// Basic load. 33def LOAD_I32_ : I<(outs I32:$dst), (ins I32:$addr), 34 [(set I32:$dst, (load I32:$addr))]>; 35def LOAD_I64_ : I<(outs I64:$dst), (ins I32:$addr), 36 [(set I64:$dst, (load I32:$addr))]>; 37def LOAD_F32_ : I<(outs F32:$dst), (ins I32:$addr), 38 [(set F32:$dst, (load I32:$addr))]>; 39def LOAD_F64_ : I<(outs F64:$dst), (ins I32:$addr), 40 [(set F64:$dst, (load I32:$addr))]>; 41 42// Extending load. 43def LOAD_S_i8_I32_ : I<(outs I32:$dst), (ins I32:$addr), 44 [(set I32:$dst, (sextloadi8 I32:$addr))]>; 45def LOAD_U_i8_I32_ : I<(outs I32:$dst), (ins I32:$addr), 46 [(set I32:$dst, (zextloadi8 I32:$addr))]>; 47def LOAD_S_i16_I32_ : I<(outs I32:$dst), (ins I32:$addr), 48 [(set I32:$dst, (sextloadi16 I32:$addr))]>; 49def LOAD_U_i16_I32_ : I<(outs I32:$dst), (ins I32:$addr), 50 [(set I32:$dst, (zextloadi16 I32:$addr))]>; 51def LOAD_S_i8_I64_ : I<(outs I64:$dst), (ins I32:$addr), 52 [(set I64:$dst, (sextloadi8 I32:$addr))]>; 53def LOAD_U_i8_I64_ : I<(outs I64:$dst), (ins I32:$addr), 54 [(set I64:$dst, (zextloadi8 I32:$addr))]>; 55def LOAD_S_i16_I64_ : I<(outs I64:$dst), (ins I32:$addr), 56 [(set I64:$dst, (sextloadi16 I32:$addr))]>; 57def LOAD_U_i16_I64_ : I<(outs I64:$dst), (ins I32:$addr), 58 [(set I64:$dst, (zextloadi16 I32:$addr))]>; 59def LOAD_S_I32_I64_ : I<(outs I64:$dst), (ins I32:$addr), 60 [(set I64:$dst, (sextloadi32 I32:$addr))]>; 61def LOAD_U_I32_I64_ : I<(outs I64:$dst), (ins I32:$addr), 62 [(set I64:$dst, (zextloadi32 I32:$addr))]>; 63 64// "Don't care" extending load become zero-extending load. 65def : Pat<(i32 (extloadi8 I32:$addr)), (LOAD_U_i8_I32_ $addr)>; 66def : Pat<(i32 (extloadi16 I32:$addr)), (LOAD_U_i16_I32_ $addr)>; 67def : Pat<(i64 (extloadi8 I32:$addr)), (LOAD_U_i8_I64_ $addr)>; 68def : Pat<(i64 (extloadi16 I32:$addr)), (LOAD_U_i16_I64_ $addr)>; 69def : Pat<(i64 (extloadi32 I32:$addr)), (LOAD_U_I32_I64_ $addr)>; 70 71// Basic store. 72// Note: WebAssembly inverts SelectionDAG's usual operand order. 73def STORE_I32_ : I<(outs), (ins I32:$addr, I32:$val), 74 [(store i32:$val, I32:$addr)]>; 75def STORE_I64_ : I<(outs), (ins I32:$addr, I64:$val), 76 [(store i64:$val, I32:$addr)]>; 77def STORE_F32_ : I<(outs), (ins I32:$addr, F32:$val), 78 [(store f32:$val, I32:$addr)]>; 79def STORE_F64_ : I<(outs), (ins I32:$addr, F64:$val), 80 [(store f64:$val, I32:$addr)]>; 81 82// Truncating store. 83def STORE_i8_I32 : I<(outs), (ins I32:$addr, I32:$val), 84 [(truncstorei8 I32:$val, I32:$addr)]>; 85def STORE_i16_I32 : I<(outs), (ins I32:$addr, I32:$val), 86 [(truncstorei16 I32:$val, I32:$addr)]>; 87def STORE_i8_I64 : I<(outs), (ins I32:$addr, I64:$val), 88 [(truncstorei8 I64:$val, I32:$addr)]>; 89def STORE_i16_I64 : I<(outs), (ins I32:$addr, I64:$val), 90 [(truncstorei16 I64:$val, I32:$addr)]>; 91def STORE_I32_I64 : I<(outs), (ins I32:$addr, I64:$val), 92 [(truncstorei32 I64:$val, I32:$addr)]>; 93 94// Page size. 95def page_size_I32 : I<(outs I32:$dst), (ins), 96 [(set I32:$dst, (int_wasm_page_size))]>, 97 Requires<[HasAddr32]>; 98def page_size_I64 : I<(outs I64:$dst), (ins), 99 [(set I64:$dst, (int_wasm_page_size))]>, 100 Requires<[HasAddr64]>; 101 102// Memory size. 103def memory_size_I32 : I<(outs I32:$dst), (ins), 104 [(set I32:$dst, (int_wasm_memory_size))]>, 105 Requires<[HasAddr32]>; 106def memory_size_I64 : I<(outs I64:$dst), (ins), 107 [(set I64:$dst, (int_wasm_memory_size))]>, 108 Requires<[HasAddr64]>; 109 110// Resize memory. 111def resize_memory_I32 : I<(outs), (ins I32:$delta), 112 [(int_wasm_resize_memory I32:$delta)]>, 113 Requires<[HasAddr32]>; 114def resize_memory_I64 : I<(outs), (ins I64:$delta), 115 [(int_wasm_resize_memory I64:$delta)]>, 116 Requires<[HasAddr64]>; 117