10b57cec5SDimitry Andric//===-- WebAssemblyInstrConv.td-WebAssembly Conversion support -*- tablegen -*-= 20b57cec5SDimitry Andric// 30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric// 70b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric/// 90b57cec5SDimitry Andric/// \file 100b57cec5SDimitry Andric/// WebAssembly datatype conversions, truncations, reinterpretations, 110b57cec5SDimitry Andric/// promotions, and demotions operand code-gen constructs. 120b57cec5SDimitry Andric/// 130b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andricdefm I32_WRAP_I64 : I<(outs I32:$dst), (ins I64:$src), (outs), (ins), 160b57cec5SDimitry Andric [(set I32:$dst, (trunc I64:$src))], 170b57cec5SDimitry Andric "i32.wrap_i64\t$dst, $src", "i32.wrap_i64", 0xa7>; 180b57cec5SDimitry Andric 190b57cec5SDimitry Andricdefm I64_EXTEND_S_I32 : I<(outs I64:$dst), (ins I32:$src), (outs), (ins), 200b57cec5SDimitry Andric [(set I64:$dst, (sext I32:$src))], 210b57cec5SDimitry Andric "i64.extend_i32_s\t$dst, $src", "i64.extend_i32_s", 220b57cec5SDimitry Andric 0xac>; 230b57cec5SDimitry Andricdefm I64_EXTEND_U_I32 : I<(outs I64:$dst), (ins I32:$src), (outs), (ins), 240b57cec5SDimitry Andric [(set I64:$dst, (zext I32:$src))], 250b57cec5SDimitry Andric "i64.extend_i32_u\t$dst, $src", "i64.extend_i32_u", 260b57cec5SDimitry Andric 0xad>; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andriclet Predicates = [HasSignExt] in { 290b57cec5SDimitry Andricdefm I32_EXTEND8_S_I32 : I<(outs I32:$dst), (ins I32:$src), (outs), (ins), 300b57cec5SDimitry Andric [(set I32:$dst, (sext_inreg I32:$src, i8))], 310b57cec5SDimitry Andric "i32.extend8_s\t$dst, $src", "i32.extend8_s", 320b57cec5SDimitry Andric 0xc0>; 330b57cec5SDimitry Andricdefm I32_EXTEND16_S_I32 : I<(outs I32:$dst), (ins I32:$src), (outs), (ins), 340b57cec5SDimitry Andric [(set I32:$dst, (sext_inreg I32:$src, i16))], 350b57cec5SDimitry Andric "i32.extend16_s\t$dst, $src", "i32.extend16_s", 360b57cec5SDimitry Andric 0xc1>; 370b57cec5SDimitry Andricdefm I64_EXTEND8_S_I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins), 380b57cec5SDimitry Andric [(set I64:$dst, (sext_inreg I64:$src, i8))], 390b57cec5SDimitry Andric "i64.extend8_s\t$dst, $src", "i64.extend8_s", 400b57cec5SDimitry Andric 0xc2>; 410b57cec5SDimitry Andricdefm I64_EXTEND16_S_I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins), 420b57cec5SDimitry Andric [(set I64:$dst, (sext_inreg I64:$src, i16))], 430b57cec5SDimitry Andric "i64.extend16_s\t$dst, $src", "i64.extend16_s", 440b57cec5SDimitry Andric 0xc3>; 450b57cec5SDimitry Andricdefm I64_EXTEND32_S_I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins), 460b57cec5SDimitry Andric [(set I64:$dst, (sext_inreg I64:$src, i32))], 470b57cec5SDimitry Andric "i64.extend32_s\t$dst, $src", "i64.extend32_s", 480b57cec5SDimitry Andric 0xc4>; 490b57cec5SDimitry Andric} // Predicates = [HasSignExt] 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric// Expand a "don't care" extend into zero-extend (chosen over sign-extend 520b57cec5SDimitry Andric// somewhat arbitrarily, although it favors popular hardware architectures 530b57cec5SDimitry Andric// and is conceptually a simpler operation). 540b57cec5SDimitry Andricdef : Pat<(i64 (anyext I32:$src)), (I64_EXTEND_U_I32 I32:$src)>; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric// Conversion from floating point to integer instructions which don't trap on 570b57cec5SDimitry Andric// overflow or invalid. 580b57cec5SDimitry Andricdefm I32_TRUNC_S_SAT_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 590b57cec5SDimitry Andric [(set I32:$dst, (fp_to_sint F32:$src))], 600b57cec5SDimitry Andric "i32.trunc_sat_f32_s\t$dst, $src", 610b57cec5SDimitry Andric "i32.trunc_sat_f32_s", 0xfc00>, 620b57cec5SDimitry Andric Requires<[HasNontrappingFPToInt]>; 630b57cec5SDimitry Andricdefm I32_TRUNC_U_SAT_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 640b57cec5SDimitry Andric [(set I32:$dst, (fp_to_uint F32:$src))], 650b57cec5SDimitry Andric "i32.trunc_sat_f32_u\t$dst, $src", 660b57cec5SDimitry Andric "i32.trunc_sat_f32_u", 0xfc01>, 670b57cec5SDimitry Andric Requires<[HasNontrappingFPToInt]>; 680b57cec5SDimitry Andricdefm I64_TRUNC_S_SAT_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 690b57cec5SDimitry Andric [(set I64:$dst, (fp_to_sint F32:$src))], 700b57cec5SDimitry Andric "i64.trunc_sat_f32_s\t$dst, $src", 710b57cec5SDimitry Andric "i64.trunc_sat_f32_s", 0xfc04>, 720b57cec5SDimitry Andric Requires<[HasNontrappingFPToInt]>; 730b57cec5SDimitry Andricdefm I64_TRUNC_U_SAT_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 740b57cec5SDimitry Andric [(set I64:$dst, (fp_to_uint F32:$src))], 750b57cec5SDimitry Andric "i64.trunc_sat_f32_u\t$dst, $src", 760b57cec5SDimitry Andric "i64.trunc_sat_f32_u", 0xfc05>, 770b57cec5SDimitry Andric Requires<[HasNontrappingFPToInt]>; 780b57cec5SDimitry Andricdefm I32_TRUNC_S_SAT_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 790b57cec5SDimitry Andric [(set I32:$dst, (fp_to_sint F64:$src))], 800b57cec5SDimitry Andric "i32.trunc_sat_f64_s\t$dst, $src", 810b57cec5SDimitry Andric "i32.trunc_sat_f64_s", 0xfc02>, 820b57cec5SDimitry Andric Requires<[HasNontrappingFPToInt]>; 830b57cec5SDimitry Andricdefm I32_TRUNC_U_SAT_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 840b57cec5SDimitry Andric [(set I32:$dst, (fp_to_uint F64:$src))], 850b57cec5SDimitry Andric "i32.trunc_sat_f64_u\t$dst, $src", 860b57cec5SDimitry Andric "i32.trunc_sat_f64_u", 0xfc03>, 870b57cec5SDimitry Andric Requires<[HasNontrappingFPToInt]>; 880b57cec5SDimitry Andricdefm I64_TRUNC_S_SAT_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 890b57cec5SDimitry Andric [(set I64:$dst, (fp_to_sint F64:$src))], 900b57cec5SDimitry Andric "i64.trunc_sat_f64_s\t$dst, $src", 910b57cec5SDimitry Andric "i64.trunc_sat_f64_s", 0xfc06>, 920b57cec5SDimitry Andric Requires<[HasNontrappingFPToInt]>; 930b57cec5SDimitry Andricdefm I64_TRUNC_U_SAT_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 940b57cec5SDimitry Andric [(set I64:$dst, (fp_to_uint F64:$src))], 950b57cec5SDimitry Andric "i64.trunc_sat_f64_u\t$dst, $src", 960b57cec5SDimitry Andric "i64.trunc_sat_f64_u", 0xfc07>, 970b57cec5SDimitry Andric Requires<[HasNontrappingFPToInt]>; 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric// Support the explicitly saturating operations as well. 1000b57cec5SDimitry Andricdef : Pat<(fp_to_sint_sat F32:$src, i32), (I32_TRUNC_S_SAT_F32 F32:$src)>; 1010b57cec5SDimitry Andricdef : Pat<(fp_to_uint_sat F32:$src, i32), (I32_TRUNC_U_SAT_F32 F32:$src)>; 1020b57cec5SDimitry Andricdef : Pat<(fp_to_sint_sat F64:$src, i32), (I32_TRUNC_S_SAT_F64 F64:$src)>; 1030b57cec5SDimitry Andricdef : Pat<(fp_to_uint_sat F64:$src, i32), (I32_TRUNC_U_SAT_F64 F64:$src)>; 1040b57cec5SDimitry Andricdef : Pat<(fp_to_sint_sat F32:$src, i64), (I64_TRUNC_S_SAT_F32 F32:$src)>; 1050b57cec5SDimitry Andricdef : Pat<(fp_to_uint_sat F32:$src, i64), (I64_TRUNC_U_SAT_F32 F32:$src)>; 1060b57cec5SDimitry Andricdef : Pat<(fp_to_sint_sat F64:$src, i64), (I64_TRUNC_S_SAT_F64 F64:$src)>; 1070b57cec5SDimitry Andricdef : Pat<(fp_to_uint_sat F64:$src, i64), (I64_TRUNC_U_SAT_F64 F64:$src)>; 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric// Conversion from floating point to integer pseudo-instructions which don't 1100b57cec5SDimitry Andric// trap on overflow or invalid. 1110b57cec5SDimitry Andriclet usesCustomInserter = 1, isCodeGenOnly = 1 in { 1120b57cec5SDimitry Andricdefm FP_TO_SINT_I32_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 1130b57cec5SDimitry Andric [(set I32:$dst, (fp_to_sint F32:$src))], "", "", 0>, 1140b57cec5SDimitry Andric Requires<[NotHasNontrappingFPToInt]>; 1150b57cec5SDimitry Andricdefm FP_TO_UINT_I32_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 1160b57cec5SDimitry Andric [(set I32:$dst, (fp_to_uint F32:$src))], "", "", 0>, 1170b57cec5SDimitry Andric Requires<[NotHasNontrappingFPToInt]>; 1180b57cec5SDimitry Andricdefm FP_TO_SINT_I64_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 1190b57cec5SDimitry Andric [(set I64:$dst, (fp_to_sint F32:$src))], "", "", 0>, 1200b57cec5SDimitry Andric Requires<[NotHasNontrappingFPToInt]>; 1210b57cec5SDimitry Andricdefm FP_TO_UINT_I64_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 1220b57cec5SDimitry Andric [(set I64:$dst, (fp_to_uint F32:$src))], "", "", 0>, 1230b57cec5SDimitry Andric Requires<[NotHasNontrappingFPToInt]>; 1240b57cec5SDimitry Andricdefm FP_TO_SINT_I32_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 1250b57cec5SDimitry Andric [(set I32:$dst, (fp_to_sint F64:$src))], "", "", 0>, 1260b57cec5SDimitry Andric Requires<[NotHasNontrappingFPToInt]>; 1270b57cec5SDimitry Andricdefm FP_TO_UINT_I32_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 1280b57cec5SDimitry Andric [(set I32:$dst, (fp_to_uint F64:$src))], "", "", 0>, 1290b57cec5SDimitry Andric Requires<[NotHasNontrappingFPToInt]>; 1300b57cec5SDimitry Andricdefm FP_TO_SINT_I64_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 1310b57cec5SDimitry Andric [(set I64:$dst, (fp_to_sint F64:$src))], "", "", 0>, 1320b57cec5SDimitry Andric Requires<[NotHasNontrappingFPToInt]>; 1330b57cec5SDimitry Andricdefm FP_TO_UINT_I64_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 1340b57cec5SDimitry Andric [(set I64:$dst, (fp_to_uint F64:$src))], "", "", 0>, 1350b57cec5SDimitry Andric Requires<[NotHasNontrappingFPToInt]>; 1360b57cec5SDimitry Andric} // usesCustomInserter, isCodeGenOnly = 1 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric// Conversion from floating point to integer traps on overflow and invalid. 1390b57cec5SDimitry Andriclet hasSideEffects = 1 in { 1400b57cec5SDimitry Andricdefm I32_TRUNC_S_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 1410b57cec5SDimitry Andric [], "i32.trunc_f32_s\t$dst, $src", "i32.trunc_f32_s", 1420b57cec5SDimitry Andric 0xa8>; 1430b57cec5SDimitry Andricdefm I32_TRUNC_U_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 1440b57cec5SDimitry Andric [], "i32.trunc_f32_u\t$dst, $src", "i32.trunc_f32_u", 1450b57cec5SDimitry Andric 0xa9>; 1460b57cec5SDimitry Andricdefm I64_TRUNC_S_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 1470b57cec5SDimitry Andric [], "i64.trunc_f32_s\t$dst, $src", "i64.trunc_f32_s", 1480b57cec5SDimitry Andric 0xae>; 1490b57cec5SDimitry Andricdefm I64_TRUNC_U_F32 : I<(outs I64:$dst), (ins F32:$src), (outs), (ins), 1500b57cec5SDimitry Andric [], "i64.trunc_f32_u\t$dst, $src", "i64.trunc_f32_u", 1510b57cec5SDimitry Andric 0xaf>; 1520b57cec5SDimitry Andricdefm I32_TRUNC_S_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 1530b57cec5SDimitry Andric [], "i32.trunc_f64_s\t$dst, $src", "i32.trunc_f64_s", 1540b57cec5SDimitry Andric 0xaa>; 1550b57cec5SDimitry Andricdefm I32_TRUNC_U_F64 : I<(outs I32:$dst), (ins F64:$src), (outs), (ins), 1560b57cec5SDimitry Andric [], "i32.trunc_f64_u\t$dst, $src", "i32.trunc_f64_u", 1570b57cec5SDimitry Andric 0xab>; 1580b57cec5SDimitry Andricdefm I64_TRUNC_S_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 1590b57cec5SDimitry Andric [], "i64.trunc_f64_s\t$dst, $src", "i64.trunc_f64_s", 1600b57cec5SDimitry Andric 0xb0>; 1610b57cec5SDimitry Andricdefm I64_TRUNC_U_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 1620b57cec5SDimitry Andric [], "i64.trunc_f64_u\t$dst, $src", "i64.trunc_f64_u", 1630b57cec5SDimitry Andric 0xb1>; 1640b57cec5SDimitry Andric} // hasSideEffects = 1 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andricdef : Pat<(int_wasm_trunc_signed F32:$src), 1670b57cec5SDimitry Andric (I32_TRUNC_S_F32 F32:$src)>; 1680b57cec5SDimitry Andricdef : Pat<(int_wasm_trunc_unsigned F32:$src), 1690b57cec5SDimitry Andric (I32_TRUNC_U_F32 F32:$src)>; 1700b57cec5SDimitry Andricdef : Pat<(int_wasm_trunc_signed F64:$src), 1710b57cec5SDimitry Andric (I32_TRUNC_S_F64 F64:$src)>; 1720b57cec5SDimitry Andricdef : Pat<(int_wasm_trunc_unsigned F64:$src), 1730b57cec5SDimitry Andric (I32_TRUNC_U_F64 F64:$src)>; 1740b57cec5SDimitry Andricdef : Pat<(int_wasm_trunc_signed F32:$src), 1750b57cec5SDimitry Andric (I64_TRUNC_S_F32 F32:$src)>; 1760b57cec5SDimitry Andricdef : Pat<(int_wasm_trunc_unsigned F32:$src), 1770b57cec5SDimitry Andric (I64_TRUNC_U_F32 F32:$src)>; 1780b57cec5SDimitry Andricdef : Pat<(int_wasm_trunc_signed F64:$src), 1790b57cec5SDimitry Andric (I64_TRUNC_S_F64 F64:$src)>; 1800b57cec5SDimitry Andricdef : Pat<(int_wasm_trunc_unsigned F64:$src), 1810b57cec5SDimitry Andric (I64_TRUNC_U_F64 F64:$src)>; 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andricdefm F32_CONVERT_S_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins), 1840b57cec5SDimitry Andric [(set F32:$dst, (sint_to_fp I32:$src))], 1850b57cec5SDimitry Andric "f32.convert_i32_s\t$dst, $src", "f32.convert_i32_s", 1860b57cec5SDimitry Andric 0xb2>; 1870b57cec5SDimitry Andricdefm F32_CONVERT_U_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins), 1880b57cec5SDimitry Andric [(set F32:$dst, (uint_to_fp I32:$src))], 1890b57cec5SDimitry Andric "f32.convert_i32_u\t$dst, $src", "f32.convert_i32_u", 1900b57cec5SDimitry Andric 0xb3>; 1910b57cec5SDimitry Andricdefm F64_CONVERT_S_I32 : I<(outs F64:$dst), (ins I32:$src), (outs), (ins), 1920b57cec5SDimitry Andric [(set F64:$dst, (sint_to_fp I32:$src))], 1930b57cec5SDimitry Andric "f64.convert_i32_s\t$dst, $src", "f64.convert_i32_s", 1940b57cec5SDimitry Andric 0xb7>; 1950b57cec5SDimitry Andricdefm F64_CONVERT_U_I32 : I<(outs F64:$dst), (ins I32:$src), (outs), (ins), 1960b57cec5SDimitry Andric [(set F64:$dst, (uint_to_fp I32:$src))], 1970b57cec5SDimitry Andric "f64.convert_i32_u\t$dst, $src", "f64.convert_i32_u", 1980b57cec5SDimitry Andric 0xb8>; 1990b57cec5SDimitry Andricdefm F32_CONVERT_S_I64 : I<(outs F32:$dst), (ins I64:$src), (outs), (ins), 2000b57cec5SDimitry Andric [(set F32:$dst, (sint_to_fp I64:$src))], 2010b57cec5SDimitry Andric "f32.convert_i64_s\t$dst, $src", "f32.convert_i64_s", 2020b57cec5SDimitry Andric 0xb4>; 2030b57cec5SDimitry Andricdefm F32_CONVERT_U_I64 : I<(outs F32:$dst), (ins I64:$src), (outs), (ins), 2040b57cec5SDimitry Andric [(set F32:$dst, (uint_to_fp I64:$src))], 2050b57cec5SDimitry Andric "f32.convert_i64_u\t$dst, $src", "f32.convert_i64_u", 2060b57cec5SDimitry Andric 0xb5>; 2070b57cec5SDimitry Andricdefm F64_CONVERT_S_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins), 2080b57cec5SDimitry Andric [(set F64:$dst, (sint_to_fp I64:$src))], 2090b57cec5SDimitry Andric "f64.convert_i64_s\t$dst, $src", "f64.convert_i64_s", 2100b57cec5SDimitry Andric 0xb9>; 2110b57cec5SDimitry Andricdefm F64_CONVERT_U_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins), 2120b57cec5SDimitry Andric [(set F64:$dst, (uint_to_fp I64:$src))], 2130b57cec5SDimitry Andric "f64.convert_i64_u\t$dst, $src", "f64.convert_i64_u", 2140b57cec5SDimitry Andric 0xba>; 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andricdefm F64_PROMOTE_F32 : I<(outs F64:$dst), (ins F32:$src), (outs), (ins), 2170b57cec5SDimitry Andric [(set F64:$dst, (fpextend F32:$src))], 2180b57cec5SDimitry Andric "f64.promote_f32\t$dst, $src", "f64.promote_f32", 2190b57cec5SDimitry Andric 0xbb>; 2200b57cec5SDimitry Andricdefm F32_DEMOTE_F64 : I<(outs F32:$dst), (ins F64:$src), (outs), (ins), 2210b57cec5SDimitry Andric [(set F32:$dst, (fpround F64:$src))], 2220b57cec5SDimitry Andric "f32.demote_f64\t$dst, $src", "f32.demote_f64", 2230b57cec5SDimitry Andric 0xb6>; 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andricdefm I32_REINTERPRET_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), 2260b57cec5SDimitry Andric [(set I32:$dst, (bitconvert F32:$src))], 2270b57cec5SDimitry Andric "i32.reinterpret_f32\t$dst, $src", 2280b57cec5SDimitry Andric "i32.reinterpret_f32", 0xbc>; 2290b57cec5SDimitry Andricdefm F32_REINTERPRET_I32 : I<(outs F32:$dst), (ins I32:$src), (outs), (ins), 2300b57cec5SDimitry Andric [(set F32:$dst, (bitconvert I32:$src))], 2310b57cec5SDimitry Andric "f32.reinterpret_i32\t$dst, $src", 232 "f32.reinterpret_i32", 0xbe>; 233defm I64_REINTERPRET_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), 234 [(set I64:$dst, (bitconvert F64:$src))], 235 "i64.reinterpret_f64\t$dst, $src", 236 "i64.reinterpret_f64", 0xbd>; 237defm F64_REINTERPRET_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins), 238 [(set F64:$dst, (bitconvert I64:$src))], 239 "f64.reinterpret_i64\t$dst, $src", 240 "f64.reinterpret_i64", 0xbf>; 241