1286425Sdim//===-- WebAssemblyInstrConv.td-WebAssembly Conversion support -*- tablegen -*-= 2286425Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6286425Sdim// 7286425Sdim//===----------------------------------------------------------------------===// 8286425Sdim/// 9286425Sdim/// \file 10341825Sdim/// WebAssembly datatype conversions, truncations, reinterpretations, 11286425Sdim/// promotions, and demotions operand code-gen constructs. 12286425Sdim/// 13286425Sdim//===----------------------------------------------------------------------===// 14286425Sdim 15341825Sdimdefm I32_WRAP_I64 : I<(outs I32:$dst), (ins I64:$src), (outs), (ins), 16296417Sdim [(set I32:$dst, (trunc I64:$src))], 17344779Sdim "i32.wrap_i64\t$dst, $src", "i32.wrap_i64", 0xa7>; 18296417Sdim 19341825Sdimdefm I64_EXTEND_S_I32 : I<(outs I64:$dst), (ins I32:$src), (outs), (ins), 20296417Sdim [(set I64:$dst, (sext I32:$src))], 21344779Sdim "i64.extend_i32_s\t$dst, $src", "i64.extend_i32_s", 22341825Sdim 0xac>; 23341825Sdimdefm I64_EXTEND_U_I32 : I<(outs I64:$dst), (ins I32:$src), (outs), (ins), 24341825Sdim [(set I64:$dst, (zext I32:$src))], 25344779Sdim "i64.extend_i32_u\t$dst, $src", "i64.extend_i32_u", 26341825Sdim 0xad>; 27296417Sdim 28341825Sdimlet Predicates = [HasSignExt] in { 29341825Sdimdefm I32_EXTEND8_S_I32 : I<(outs I32:$dst), (ins I32:$src), (outs), (ins), 30341825Sdim [(set I32:$dst, (sext_inreg I32:$src, i8))], 31341825Sdim "i32.extend8_s\t$dst, $src", "i32.extend8_s", 32341825Sdim 0xc0>; 33341825Sdimdefm I32_EXTEND16_S_I32 : I<(outs I32:$dst), (ins I32:$src), (outs), (ins), 34341825Sdim [(set I32:$dst, (sext_inreg I32:$src, i16))], 35341825Sdim "i32.extend16_s\t$dst, $src", "i32.extend16_s", 36341825Sdim 0xc1>; 37341825Sdimdefm I64_EXTEND8_S_I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins), 38341825Sdim [(set I64:$dst, (sext_inreg I64:$src, i8))], 39341825Sdim "i64.extend8_s\t$dst, $src", "i64.extend8_s", 40341825Sdim 0xc2>; 41341825Sdimdefm I64_EXTEND16_S_I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins), 42341825Sdim [(set I64:$dst, (sext_inreg I64:$src, i16))], 43341825Sdim "i64.extend16_s\t$dst, $src", "i64.extend16_s", 44341825Sdim 0xc3>; 45341825Sdimdefm I64_EXTEND32_S_I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins), 46341825Sdim [(set I64:$dst, (sext_inreg I64:$src, i32))], 47341825Sdim "i64.extend32_s\t$dst, $src", "i64.extend32_s", 48341825Sdim 0xc4>; 49341825Sdim} // Predicates = [HasSignExt] 50327952Sdim 51296417Sdim// Expand a "don't care" extend into zero-extend (chosen over sign-extend 52296417Sdim// somewhat arbitrarily, although it favors popular hardware architectures 53296417Sdim// and is conceptually a simpler operation). 54296417Sdimdef : Pat<(i64 (anyext I32:$src)), (I64_EXTEND_U_I32 I32:$src)>; 55296417Sdim 56327952Sdim// Conversion from floating point to integer instructions which don't trap on 57327952Sdim// overflow or invalid. 58341825Sdimdefm I32_TRUNC_S_SAT_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 59341825Sdim [(set I32:$dst, (fp_to_sint F32:$src))], 60344779Sdim "i32.trunc_sat_f32_s\t$dst, $src", 61344779Sdim "i32.trunc_sat_f32_s", 0xfc00>, 62341825Sdim Requires<[HasNontrappingFPToInt]>; 63341825Sdimdefm I32_TRUNC_U_SAT_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 64341825Sdim [(set I32:$dst, (fp_to_uint F32:$src))], 65344779Sdim "i32.trunc_sat_f32_u\t$dst, $src", 66344779Sdim "i32.trunc_sat_f32_u", 0xfc01>, 67341825Sdim Requires<[HasNontrappingFPToInt]>; 68341825Sdimdefm I64_TRUNC_S_SAT_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 69341825Sdim [(set I64:$dst, (fp_to_sint F32:$src))], 70344779Sdim "i64.trunc_sat_f32_s\t$dst, $src", 71344779Sdim "i64.trunc_sat_f32_s", 0xfc04>, 72341825Sdim Requires<[HasNontrappingFPToInt]>; 73341825Sdimdefm I64_TRUNC_U_SAT_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 74341825Sdim [(set I64:$dst, (fp_to_uint F32:$src))], 75344779Sdim "i64.trunc_sat_f32_u\t$dst, $src", 76344779Sdim "i64.trunc_sat_f32_u", 0xfc05>, 77341825Sdim Requires<[HasNontrappingFPToInt]>; 78341825Sdimdefm I32_TRUNC_S_SAT_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 79341825Sdim [(set I32:$dst, (fp_to_sint F64:$src))], 80344779Sdim "i32.trunc_sat_f64_s\t$dst, $src", 81344779Sdim "i32.trunc_sat_f64_s", 0xfc02>, 82341825Sdim Requires<[HasNontrappingFPToInt]>; 83341825Sdimdefm I32_TRUNC_U_SAT_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 84341825Sdim [(set I32:$dst, (fp_to_uint F64:$src))], 85344779Sdim "i32.trunc_sat_f64_u\t$dst, $src", 86344779Sdim "i32.trunc_sat_f64_u", 0xfc03>, 87341825Sdim Requires<[HasNontrappingFPToInt]>; 88341825Sdimdefm I64_TRUNC_S_SAT_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 89341825Sdim [(set I64:$dst, (fp_to_sint F64:$src))], 90344779Sdim "i64.trunc_sat_f64_s\t$dst, $src", 91344779Sdim "i64.trunc_sat_f64_s", 0xfc06>, 92341825Sdim Requires<[HasNontrappingFPToInt]>; 93341825Sdimdefm I64_TRUNC_U_SAT_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 94341825Sdim [(set I64:$dst, (fp_to_uint F64:$src))], 95344779Sdim "i64.trunc_sat_f64_u\t$dst, $src", 96344779Sdim "i64.trunc_sat_f64_u", 0xfc07>, 97341825Sdim Requires<[HasNontrappingFPToInt]>; 98327952Sdim 99344779Sdim// Lower llvm.wasm.trunc.saturate.* to saturating instructions 100344779Sdimdef : Pat<(int_wasm_trunc_saturate_signed F32:$src), 101344779Sdim (I32_TRUNC_S_SAT_F32 F32:$src)>; 102344779Sdimdef : Pat<(int_wasm_trunc_saturate_unsigned F32:$src), 103344779Sdim (I32_TRUNC_U_SAT_F32 F32:$src)>; 104344779Sdimdef : Pat<(int_wasm_trunc_saturate_signed F64:$src), 105344779Sdim (I32_TRUNC_S_SAT_F64 F64:$src)>; 106344779Sdimdef : Pat<(int_wasm_trunc_saturate_unsigned F64:$src), 107344779Sdim (I32_TRUNC_U_SAT_F64 F64:$src)>; 108344779Sdimdef : Pat<(int_wasm_trunc_saturate_signed F32:$src), 109344779Sdim (I64_TRUNC_S_SAT_F32 F32:$src)>; 110344779Sdimdef : Pat<(int_wasm_trunc_saturate_unsigned F32:$src), 111344779Sdim (I64_TRUNC_U_SAT_F32 F32:$src)>; 112344779Sdimdef : Pat<(int_wasm_trunc_saturate_signed F64:$src), 113344779Sdim (I64_TRUNC_S_SAT_F64 F64:$src)>; 114344779Sdimdef : Pat<(int_wasm_trunc_saturate_unsigned F64:$src), 115344779Sdim (I64_TRUNC_U_SAT_F64 F64:$src)>; 116344779Sdim 117327952Sdim// Conversion from floating point to integer pseudo-instructions which don't 118327952Sdim// trap on overflow or invalid. 119327952Sdimlet usesCustomInserter = 1, isCodeGenOnly = 1 in { 120341825Sdimdefm FP_TO_SINT_I32_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 121341825Sdim [(set I32:$dst, (fp_to_sint F32:$src))], "", "", 0>, 122341825Sdim Requires<[NotHasNontrappingFPToInt]>; 123341825Sdimdefm FP_TO_UINT_I32_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 124341825Sdim [(set I32:$dst, (fp_to_uint F32:$src))], "", "", 0>, 125341825Sdim Requires<[NotHasNontrappingFPToInt]>; 126341825Sdimdefm FP_TO_SINT_I64_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 127341825Sdim [(set I64:$dst, (fp_to_sint F32:$src))], "", "", 0>, 128341825Sdim Requires<[NotHasNontrappingFPToInt]>; 129341825Sdimdefm FP_TO_UINT_I64_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 130341825Sdim [(set I64:$dst, (fp_to_uint F32:$src))], "", "", 0>, 131341825Sdim Requires<[NotHasNontrappingFPToInt]>; 132341825Sdimdefm FP_TO_SINT_I32_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 133341825Sdim [(set I32:$dst, (fp_to_sint F64:$src))], "", "", 0>, 134341825Sdim Requires<[NotHasNontrappingFPToInt]>; 135341825Sdimdefm FP_TO_UINT_I32_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 136341825Sdim [(set I32:$dst, (fp_to_uint F64:$src))], "", "", 0>, 137341825Sdim Requires<[NotHasNontrappingFPToInt]>; 138341825Sdimdefm FP_TO_SINT_I64_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 139341825Sdim [(set I64:$dst, (fp_to_sint F64:$src))], "", "", 0>, 140341825Sdim Requires<[NotHasNontrappingFPToInt]>; 141341825Sdimdefm FP_TO_UINT_I64_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 142341825Sdim [(set I64:$dst, (fp_to_uint F64:$src))], "", "", 0>, 143341825Sdim Requires<[NotHasNontrappingFPToInt]>; 144327952Sdim} // usesCustomInserter, isCodeGenOnly = 1 145327952Sdim 146296417Sdim// Conversion from floating point to integer traps on overflow and invalid. 147296417Sdimlet hasSideEffects = 1 in { 148341825Sdimdefm I32_TRUNC_S_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 149344779Sdim [], "i32.trunc_f32_s\t$dst, $src", "i32.trunc_f32_s", 150341825Sdim 0xa8>; 151341825Sdimdefm I32_TRUNC_U_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 152344779Sdim [], "i32.trunc_f32_u\t$dst, $src", "i32.trunc_f32_u", 153341825Sdim 0xa9>; 154341825Sdimdefm I64_TRUNC_S_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 155344779Sdim [], "i64.trunc_f32_s\t$dst, $src", "i64.trunc_f32_s", 156341825Sdim 0xae>; 157341825Sdimdefm I64_TRUNC_U_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 158344779Sdim [], "i64.trunc_f32_u\t$dst, $src", "i64.trunc_f32_u", 159341825Sdim 0xaf>; 160341825Sdimdefm I32_TRUNC_S_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 161344779Sdim [], "i32.trunc_f64_s\t$dst, $src", "i32.trunc_f64_s", 162341825Sdim 0xaa>; 163341825Sdimdefm I32_TRUNC_U_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 164344779Sdim [], "i32.trunc_f64_u\t$dst, $src", "i32.trunc_f64_u", 165341825Sdim 0xab>; 166341825Sdimdefm I64_TRUNC_S_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 167344779Sdim [], "i64.trunc_f64_s\t$dst, $src", "i64.trunc_f64_s", 168341825Sdim 0xb0>; 169341825Sdimdefm I64_TRUNC_U_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 170344779Sdim [], "i64.trunc_f64_u\t$dst, $src", "i64.trunc_f64_u", 171341825Sdim 0xb1>; 172296417Sdim} // hasSideEffects = 1 173296417Sdim 174360784Sdimdef : Pat<(int_wasm_trunc_signed F32:$src), 175360784Sdim (I32_TRUNC_S_F32 F32:$src)>; 176360784Sdimdef : Pat<(int_wasm_trunc_unsigned F32:$src), 177360784Sdim (I32_TRUNC_U_F32 F32:$src)>; 178360784Sdimdef : Pat<(int_wasm_trunc_signed F64:$src), 179360784Sdim (I32_TRUNC_S_F64 F64:$src)>; 180360784Sdimdef : Pat<(int_wasm_trunc_unsigned F64:$src), 181360784Sdim (I32_TRUNC_U_F64 F64:$src)>; 182360784Sdimdef : Pat<(int_wasm_trunc_signed F32:$src), 183360784Sdim (I64_TRUNC_S_F32 F32:$src)>; 184360784Sdimdef : Pat<(int_wasm_trunc_unsigned F32:$src), 185360784Sdim (I64_TRUNC_U_F32 F32:$src)>; 186360784Sdimdef : Pat<(int_wasm_trunc_signed F64:$src), 187360784Sdim (I64_TRUNC_S_F64 F64:$src)>; 188360784Sdimdef : Pat<(int_wasm_trunc_unsigned F64:$src), 189360784Sdim (I64_TRUNC_U_F64 F64:$src)>; 190360784Sdim 191341825Sdimdefm F32_CONVERT_S_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins), 192341825Sdim [(set F32:$dst, (sint_to_fp I32:$src))], 193344779Sdim "f32.convert_i32_s\t$dst, $src", "f32.convert_i32_s", 194341825Sdim 0xb2>; 195341825Sdimdefm F32_CONVERT_U_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins), 196341825Sdim [(set F32:$dst, (uint_to_fp I32:$src))], 197344779Sdim "f32.convert_i32_u\t$dst, $src", "f32.convert_i32_u", 198341825Sdim 0xb3>; 199341825Sdimdefm F64_CONVERT_S_I32 : I<(outs F64:$dst), (ins I32:$src), (outs), (ins), 200341825Sdim [(set F64:$dst, (sint_to_fp I32:$src))], 201344779Sdim "f64.convert_i32_s\t$dst, $src", "f64.convert_i32_s", 202341825Sdim 0xb7>; 203341825Sdimdefm F64_CONVERT_U_I32 : I<(outs F64:$dst), (ins I32:$src), (outs), (ins), 204341825Sdim [(set F64:$dst, (uint_to_fp I32:$src))], 205344779Sdim "f64.convert_i32_u\t$dst, $src", "f64.convert_i32_u", 206341825Sdim 0xb8>; 207341825Sdimdefm F32_CONVERT_S_I64 : I<(outs F32:$dst), (ins I64:$src), (outs), (ins), 208341825Sdim [(set F32:$dst, (sint_to_fp I64:$src))], 209344779Sdim "f32.convert_i64_s\t$dst, $src", "f32.convert_i64_s", 210341825Sdim 0xb4>; 211341825Sdimdefm F32_CONVERT_U_I64 : I<(outs F32:$dst), (ins I64:$src), (outs), (ins), 212341825Sdim [(set F32:$dst, (uint_to_fp I64:$src))], 213344779Sdim "f32.convert_i64_u\t$dst, $src", "f32.convert_i64_u", 214341825Sdim 0xb5>; 215341825Sdimdefm F64_CONVERT_S_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins), 216341825Sdim [(set F64:$dst, (sint_to_fp I64:$src))], 217344779Sdim "f64.convert_i64_s\t$dst, $src", "f64.convert_i64_s", 218341825Sdim 0xb9>; 219341825Sdimdefm F64_CONVERT_U_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins), 220341825Sdim [(set F64:$dst, (uint_to_fp I64:$src))], 221344779Sdim "f64.convert_i64_u\t$dst, $src", "f64.convert_i64_u", 222341825Sdim 0xba>; 223296417Sdim 224341825Sdimdefm F64_PROMOTE_F32 : I<(outs F64:$dst), (ins F32:$src), (outs), (ins), 225341825Sdim [(set F64:$dst, (fpextend F32:$src))], 226344779Sdim "f64.promote_f32\t$dst, $src", "f64.promote_f32", 227341825Sdim 0xbb>; 228341825Sdimdefm F32_DEMOTE_F64 : I<(outs F32:$dst), (ins F64:$src), (outs), (ins), 229341825Sdim [(set F32:$dst, (fpround F64:$src))], 230344779Sdim "f32.demote_f64\t$dst, $src", "f32.demote_f64", 231341825Sdim 0xb6>; 232296417Sdim 233341825Sdimdefm I32_REINTERPRET_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 234341825Sdim [(set I32:$dst, (bitconvert F32:$src))], 235344779Sdim "i32.reinterpret_f32\t$dst, $src", 236344779Sdim "i32.reinterpret_f32", 0xbc>; 237341825Sdimdefm F32_REINTERPRET_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins), 238341825Sdim [(set F32:$dst, (bitconvert I32:$src))], 239344779Sdim "f32.reinterpret_i32\t$dst, $src", 240344779Sdim "f32.reinterpret_i32", 0xbe>; 241341825Sdimdefm I64_REINTERPRET_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 242341825Sdim [(set I64:$dst, (bitconvert F64:$src))], 243344779Sdim "i64.reinterpret_f64\t$dst, $src", 244344779Sdim "i64.reinterpret_f64", 0xbd>; 245341825Sdimdefm F64_REINTERPRET_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins), 246341825Sdim [(set F64:$dst, (bitconvert I64:$src))], 247344779Sdim "f64.reinterpret_i64\t$dst, $src", 248344779Sdim "f64.reinterpret_i64", 0xbf>; 249