1//===-- WebAssemblyInstrConv.td-WebAssembly Conversion 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/// WebAssembly datatype conversions, truncations, reinterpretations, 12/// promotions, and demotions operand code-gen constructs. 13/// 14//===----------------------------------------------------------------------===// 15 16let Defs = [ARGUMENTS] in { 17 18defm I32_WRAP_I64 : I<(outs I32:$dst), (ins I64:$src), (outs), (ins), 19 [(set I32:$dst, (trunc I64:$src))], 20 "i32.wrap/i64\t$dst, $src", "i32.wrap/i64", 0xa7>; 21 22defm I64_EXTEND_S_I32 : I<(outs I64:$dst), (ins I32:$src), (outs), (ins), 23 [(set I64:$dst, (sext I32:$src))], 24 "i64.extend_s/i32\t$dst, $src", "i64.extend_s/i32", 25 0xac>; 26defm I64_EXTEND_U_I32 : I<(outs I64:$dst), (ins I32:$src), (outs), (ins), 27 [(set I64:$dst, (zext I32:$src))], 28 "i64.extend_u/i32\t$dst, $src", "i64.extend_u/i32", 29 0xad>; 30 31let Predicates = [HasSignExt] in { 32defm I32_EXTEND8_S_I32 : I<(outs I32:$dst), (ins I32:$src), (outs), (ins), 33 [(set I32:$dst, (sext_inreg I32:$src, i8))], 34 "i32.extend8_s\t$dst, $src", "i32.extend8_s", 35 0xc0>; 36defm I32_EXTEND16_S_I32 : I<(outs I32:$dst), (ins I32:$src), (outs), (ins), 37 [(set I32:$dst, (sext_inreg I32:$src, i16))], 38 "i32.extend16_s\t$dst, $src", "i32.extend16_s", 39 0xc1>; 40defm I64_EXTEND8_S_I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins), 41 [(set I64:$dst, (sext_inreg I64:$src, i8))], 42 "i64.extend8_s\t$dst, $src", "i64.extend8_s", 43 0xc2>; 44defm I64_EXTEND16_S_I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins), 45 [(set I64:$dst, (sext_inreg I64:$src, i16))], 46 "i64.extend16_s\t$dst, $src", "i64.extend16_s", 47 0xc3>; 48defm I64_EXTEND32_S_I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins), 49 [(set I64:$dst, (sext_inreg I64:$src, i32))], 50 "i64.extend32_s\t$dst, $src", "i64.extend32_s", 51 0xc4>; 52} // Predicates = [HasSignExt] 53 54} // defs = [ARGUMENTS] 55 56// Expand a "don't care" extend into zero-extend (chosen over sign-extend 57// somewhat arbitrarily, although it favors popular hardware architectures 58// and is conceptually a simpler operation). 59def : Pat<(i64 (anyext I32:$src)), (I64_EXTEND_U_I32 I32:$src)>; 60 61let Defs = [ARGUMENTS] in { 62 63// Conversion from floating point to integer instructions which don't trap on 64// overflow or invalid. 65defm I32_TRUNC_S_SAT_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 66 [(set I32:$dst, (fp_to_sint F32:$src))], 67 "i32.trunc_s:sat/f32\t$dst, $src", 68 "i32.trunc_s:sat/f32", 0xfc00>, 69 Requires<[HasNontrappingFPToInt]>; 70defm I32_TRUNC_U_SAT_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 71 [(set I32:$dst, (fp_to_uint F32:$src))], 72 "i32.trunc_u:sat/f32\t$dst, $src", 73 "i32.trunc_u:sat/f32", 0xfc01>, 74 Requires<[HasNontrappingFPToInt]>; 75defm I64_TRUNC_S_SAT_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 76 [(set I64:$dst, (fp_to_sint F32:$src))], 77 "i64.trunc_s:sat/f32\t$dst, $src", 78 "i64.trunc_s:sat/f32", 0xfc04>, 79 Requires<[HasNontrappingFPToInt]>; 80defm I64_TRUNC_U_SAT_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 81 [(set I64:$dst, (fp_to_uint F32:$src))], 82 "i64.trunc_u:sat/f32\t$dst, $src", 83 "i64.trunc_u:sat/f32", 0xfc05>, 84 Requires<[HasNontrappingFPToInt]>; 85defm I32_TRUNC_S_SAT_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 86 [(set I32:$dst, (fp_to_sint F64:$src))], 87 "i32.trunc_s:sat/f64\t$dst, $src", 88 "i32.trunc_s:sat/f64", 0xfc02>, 89 Requires<[HasNontrappingFPToInt]>; 90defm I32_TRUNC_U_SAT_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 91 [(set I32:$dst, (fp_to_uint F64:$src))], 92 "i32.trunc_u:sat/f64\t$dst, $src", 93 "i32.trunc_u:sat/f64", 0xfc03>, 94 Requires<[HasNontrappingFPToInt]>; 95defm I64_TRUNC_S_SAT_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 96 [(set I64:$dst, (fp_to_sint F64:$src))], 97 "i64.trunc_s:sat/f64\t$dst, $src", 98 "i64.trunc_s:sat/f64", 0xfc06>, 99 Requires<[HasNontrappingFPToInt]>; 100defm I64_TRUNC_U_SAT_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 101 [(set I64:$dst, (fp_to_uint F64:$src))], 102 "i64.trunc_u:sat/f64\t$dst, $src", 103 "i64.trunc_u:sat/f64", 0xfc07>, 104 Requires<[HasNontrappingFPToInt]>; 105 106// Conversion from floating point to integer pseudo-instructions which don't 107// trap on overflow or invalid. 108let usesCustomInserter = 1, isCodeGenOnly = 1 in { 109defm FP_TO_SINT_I32_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 110 [(set I32:$dst, (fp_to_sint F32:$src))], "", "", 0>, 111 Requires<[NotHasNontrappingFPToInt]>; 112defm FP_TO_UINT_I32_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 113 [(set I32:$dst, (fp_to_uint F32:$src))], "", "", 0>, 114 Requires<[NotHasNontrappingFPToInt]>; 115defm FP_TO_SINT_I64_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 116 [(set I64:$dst, (fp_to_sint F32:$src))], "", "", 0>, 117 Requires<[NotHasNontrappingFPToInt]>; 118defm FP_TO_UINT_I64_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 119 [(set I64:$dst, (fp_to_uint F32:$src))], "", "", 0>, 120 Requires<[NotHasNontrappingFPToInt]>; 121defm FP_TO_SINT_I32_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 122 [(set I32:$dst, (fp_to_sint F64:$src))], "", "", 0>, 123 Requires<[NotHasNontrappingFPToInt]>; 124defm FP_TO_UINT_I32_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 125 [(set I32:$dst, (fp_to_uint F64:$src))], "", "", 0>, 126 Requires<[NotHasNontrappingFPToInt]>; 127defm FP_TO_SINT_I64_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 128 [(set I64:$dst, (fp_to_sint F64:$src))], "", "", 0>, 129 Requires<[NotHasNontrappingFPToInt]>; 130defm FP_TO_UINT_I64_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 131 [(set I64:$dst, (fp_to_uint F64:$src))], "", "", 0>, 132 Requires<[NotHasNontrappingFPToInt]>; 133} // usesCustomInserter, isCodeGenOnly = 1 134 135// Conversion from floating point to integer traps on overflow and invalid. 136let hasSideEffects = 1 in { 137defm I32_TRUNC_S_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 138 [], "i32.trunc_s/f32\t$dst, $src", "i32.trunc_s/f32", 139 0xa8>; 140defm I32_TRUNC_U_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 141 [], "i32.trunc_u/f32\t$dst, $src", "i32.trunc_u/f32", 142 0xa9>; 143defm I64_TRUNC_S_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 144 [], "i64.trunc_s/f32\t$dst, $src", "i64.trunc_s/f32", 145 0xae>; 146defm I64_TRUNC_U_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 147 [], "i64.trunc_u/f32\t$dst, $src", "i64.trunc_u/f32", 148 0xaf>; 149defm I32_TRUNC_S_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 150 [], "i32.trunc_s/f64\t$dst, $src", "i32.trunc_s/f64", 151 0xaa>; 152defm I32_TRUNC_U_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 153 [], "i32.trunc_u/f64\t$dst, $src", "i32.trunc_u/f64", 154 0xab>; 155defm I64_TRUNC_S_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 156 [], "i64.trunc_s/f64\t$dst, $src", "i64.trunc_s/f64", 157 0xb0>; 158defm I64_TRUNC_U_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 159 [], "i64.trunc_u/f64\t$dst, $src", "i64.trunc_u/f64", 160 0xb1>; 161} // hasSideEffects = 1 162 163defm F32_CONVERT_S_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins), 164 [(set F32:$dst, (sint_to_fp I32:$src))], 165 "f32.convert_s/i32\t$dst, $src", "f32.convert_s/i32", 166 0xb2>; 167defm F32_CONVERT_U_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins), 168 [(set F32:$dst, (uint_to_fp I32:$src))], 169 "f32.convert_u/i32\t$dst, $src", "f32.convert_u/i32", 170 0xb3>; 171defm F64_CONVERT_S_I32 : I<(outs F64:$dst), (ins I32:$src), (outs), (ins), 172 [(set F64:$dst, (sint_to_fp I32:$src))], 173 "f64.convert_s/i32\t$dst, $src", "f64.convert_s/i32", 174 0xb7>; 175defm F64_CONVERT_U_I32 : I<(outs F64:$dst), (ins I32:$src), (outs), (ins), 176 [(set F64:$dst, (uint_to_fp I32:$src))], 177 "f64.convert_u/i32\t$dst, $src", "f64.convert_u/i32", 178 0xb8>; 179defm F32_CONVERT_S_I64 : I<(outs F32:$dst), (ins I64:$src), (outs), (ins), 180 [(set F32:$dst, (sint_to_fp I64:$src))], 181 "f32.convert_s/i64\t$dst, $src", "f32.convert_s/i64", 182 0xb4>; 183defm F32_CONVERT_U_I64 : I<(outs F32:$dst), (ins I64:$src), (outs), (ins), 184 [(set F32:$dst, (uint_to_fp I64:$src))], 185 "f32.convert_u/i64\t$dst, $src", "f32.convert_u/i64", 186 0xb5>; 187defm F64_CONVERT_S_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins), 188 [(set F64:$dst, (sint_to_fp I64:$src))], 189 "f64.convert_s/i64\t$dst, $src", "f64.convert_s/i64", 190 0xb9>; 191defm F64_CONVERT_U_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins), 192 [(set F64:$dst, (uint_to_fp I64:$src))], 193 "f64.convert_u/i64\t$dst, $src", "f64.convert_u/i64", 194 0xba>; 195 196defm F64_PROMOTE_F32 : I<(outs F64:$dst), (ins F32:$src), (outs), (ins), 197 [(set F64:$dst, (fpextend F32:$src))], 198 "f64.promote/f32\t$dst, $src", "f64.promote/f32", 199 0xbb>; 200defm F32_DEMOTE_F64 : I<(outs F32:$dst), (ins F64:$src), (outs), (ins), 201 [(set F32:$dst, (fpround F64:$src))], 202 "f32.demote/f64\t$dst, $src", "f32.demote/f64", 203 0xb6>; 204 205defm I32_REINTERPRET_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 206 [(set I32:$dst, (bitconvert F32:$src))], 207 "i32.reinterpret/f32\t$dst, $src", 208 "i32.reinterpret/f32", 0xbc>; 209defm F32_REINTERPRET_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins), 210 [(set F32:$dst, (bitconvert I32:$src))], 211 "f32.reinterpret/i32\t$dst, $src", 212 "f32.reinterpret/i32", 0xbe>; 213defm I64_REINTERPRET_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 214 [(set I64:$dst, (bitconvert F64:$src))], 215 "i64.reinterpret/f64\t$dst, $src", 216 "i64.reinterpret/f64", 0xbd>; 217defm F64_REINTERPRET_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins), 218 [(set F64:$dst, (bitconvert I64:$src))], 219 "f64.reinterpret/i64\t$dst, $src", 220 "f64.reinterpret/i64", 0xbf>; 221 222} // Defs = [ARGUMENTS] 223