WebAssemblyInstrFloat.td revision 314564
1286425Sdim// WebAssemblyInstrFloat.td-WebAssembly Float codegen support ---*- tablegen -*- 2286425Sdim// 3286425Sdim// The LLVM Compiler Infrastructure 4286425Sdim// 5286425Sdim// This file is distributed under the University of Illinois Open Source 6286425Sdim// License. See LICENSE.TXT for details. 7286425Sdim// 8286425Sdim//===----------------------------------------------------------------------===// 9286425Sdim/// 10286425Sdim/// \file 11286425Sdim/// \brief WebAssembly Floating-point operand code-gen constructs. 12286425Sdim/// 13286425Sdim//===----------------------------------------------------------------------===// 14286425Sdim 15296417Sdimlet Defs = [ARGUMENTS] in { 16286425Sdim 17296417Sdimlet isCommutable = 1 in 18314564Sdimdefm ADD : BinaryFP<fadd, "add ", 0x92, 0xa0>; 19314564Sdimdefm SUB : BinaryFP<fsub, "sub ", 0x93, 0xa1>; 20296417Sdimlet isCommutable = 1 in 21314564Sdimdefm MUL : BinaryFP<fmul, "mul ", 0x94, 0xa2>; 22314564Sdimdefm DIV : BinaryFP<fdiv, "div ", 0x95, 0xa3>; 23314564Sdimdefm SQRT : UnaryFP<fsqrt, "sqrt", 0x91, 0x9f>; 24286425Sdim 25314564Sdimdefm ABS : UnaryFP<fabs, "abs ", 0x8b, 0x99>; 26314564Sdimdefm NEG : UnaryFP<fneg, "neg ", 0x8c, 0x9a>; 27314564Sdimdefm COPYSIGN : BinaryFP<fcopysign, "copysign", 0x98, 0xa6>; 28286425Sdim 29296417Sdimlet isCommutable = 1 in { 30314564Sdimdefm MIN : BinaryFP<fminnan, "min ", 0x96, 0xa4>; 31314564Sdimdefm MAX : BinaryFP<fmaxnan, "max ", 0x97, 0xa5>; 32296417Sdim} // isCommutable = 1 33296417Sdim 34314564Sdimdefm CEIL : UnaryFP<fceil, "ceil", 0x8d, 0x9b>; 35314564Sdimdefm FLOOR : UnaryFP<ffloor, "floor", 0x8e, 0x9c>; 36314564Sdimdefm TRUNC : UnaryFP<ftrunc, "trunc", 0x8f, 0x9d>; 37314564Sdimdefm NEAREST : UnaryFP<fnearbyint, "nearest", 0x90, 0x9e>; 38296417Sdim 39296417Sdim} // Defs = [ARGUMENTS] 40296417Sdim 41296417Sdim// DAGCombine oddly folds casts into the rhs of copysign. Unfold them. 42296417Sdimdef : Pat<(fcopysign F64:$lhs, F32:$rhs), 43296417Sdim (COPYSIGN_F64 F64:$lhs, (F64_PROMOTE_F32 F32:$rhs))>; 44296417Sdimdef : Pat<(fcopysign F32:$lhs, F64:$rhs), 45296417Sdim (COPYSIGN_F32 F32:$lhs, (F32_DEMOTE_F64 F64:$rhs))>; 46296417Sdim 47296417Sdim// WebAssembly doesn't expose inexact exceptions, so map frint to fnearbyint. 48296417Sdimdef : Pat<(frint f32:$src), (NEAREST_F32 f32:$src)>; 49296417Sdimdef : Pat<(frint f64:$src), (NEAREST_F64 f64:$src)>; 50296417Sdim 51296417Sdimlet Defs = [ARGUMENTS] in { 52296417Sdim 53296417Sdimlet isCommutable = 1 in { 54314564Sdimdefm EQ : ComparisonFP<SETOEQ, "eq ", 0x5b, 0x61>; 55314564Sdimdefm NE : ComparisonFP<SETUNE, "ne ", 0x5c, 0x62>; 56296417Sdim} // isCommutable = 1 57314564Sdimdefm LT : ComparisonFP<SETOLT, "lt ", 0x5d, 0x63>; 58314564Sdimdefm LE : ComparisonFP<SETOLE, "le ", 0x5e, 0x64>; 59314564Sdimdefm GT : ComparisonFP<SETOGT, "gt ", 0x5f, 0x65>; 60314564Sdimdefm GE : ComparisonFP<SETOGE, "ge ", 0x60, 0x66>; 61296417Sdim 62296417Sdim} // Defs = [ARGUMENTS] 63296417Sdim 64296417Sdim// Don't care floating-point comparisons, supported via other comparisons. 65296417Sdimdef : Pat<(seteq f32:$lhs, f32:$rhs), (EQ_F32 f32:$lhs, f32:$rhs)>; 66296417Sdimdef : Pat<(setne f32:$lhs, f32:$rhs), (NE_F32 f32:$lhs, f32:$rhs)>; 67296417Sdimdef : Pat<(setlt f32:$lhs, f32:$rhs), (LT_F32 f32:$lhs, f32:$rhs)>; 68296417Sdimdef : Pat<(setle f32:$lhs, f32:$rhs), (LE_F32 f32:$lhs, f32:$rhs)>; 69296417Sdimdef : Pat<(setgt f32:$lhs, f32:$rhs), (GT_F32 f32:$lhs, f32:$rhs)>; 70296417Sdimdef : Pat<(setge f32:$lhs, f32:$rhs), (GE_F32 f32:$lhs, f32:$rhs)>; 71296417Sdimdef : Pat<(seteq f64:$lhs, f64:$rhs), (EQ_F64 f64:$lhs, f64:$rhs)>; 72296417Sdimdef : Pat<(setne f64:$lhs, f64:$rhs), (NE_F64 f64:$lhs, f64:$rhs)>; 73296417Sdimdef : Pat<(setlt f64:$lhs, f64:$rhs), (LT_F64 f64:$lhs, f64:$rhs)>; 74296417Sdimdef : Pat<(setle f64:$lhs, f64:$rhs), (LE_F64 f64:$lhs, f64:$rhs)>; 75296417Sdimdef : Pat<(setgt f64:$lhs, f64:$rhs), (GT_F64 f64:$lhs, f64:$rhs)>; 76296417Sdimdef : Pat<(setge f64:$lhs, f64:$rhs), (GE_F64 f64:$lhs, f64:$rhs)>; 77296417Sdim 78296417Sdimlet Defs = [ARGUMENTS] in { 79296417Sdim 80309124Sdimdef SELECT_F32 : I<(outs F32:$dst), (ins F32:$lhs, F32:$rhs, I32:$cond), 81296417Sdim [(set F32:$dst, (select I32:$cond, F32:$lhs, F32:$rhs))], 82314564Sdim "f32.select\t$dst, $lhs, $rhs, $cond", 0x1b>; 83309124Sdimdef SELECT_F64 : I<(outs F64:$dst), (ins F64:$lhs, F64:$rhs, I32:$cond), 84296417Sdim [(set F64:$dst, (select I32:$cond, F64:$lhs, F64:$rhs))], 85314564Sdim "f64.select\t$dst, $lhs, $rhs, $cond", 0x1b>; 86296417Sdim 87296417Sdim} // Defs = [ARGUMENTS] 88296417Sdim 89296417Sdim// ISD::SELECT requires its operand to conform to getBooleanContents, but 90296417Sdim// WebAssembly's select interprets any non-zero value as true, so we can fold 91296417Sdim// a setne with 0 into a select. 92296417Sdimdef : Pat<(select (i32 (setne I32:$cond, 0)), F32:$lhs, F32:$rhs), 93309124Sdim (SELECT_F32 F32:$lhs, F32:$rhs, I32:$cond)>; 94296417Sdimdef : Pat<(select (i32 (setne I32:$cond, 0)), F64:$lhs, F64:$rhs), 95309124Sdim (SELECT_F64 F64:$lhs, F64:$rhs, I32:$cond)>; 96296417Sdim 97296417Sdim// And again, this time with seteq instead of setne and the arms reversed. 98296417Sdimdef : Pat<(select (i32 (seteq I32:$cond, 0)), F32:$lhs, F32:$rhs), 99309124Sdim (SELECT_F32 F32:$rhs, F32:$lhs, I32:$cond)>; 100296417Sdimdef : Pat<(select (i32 (seteq I32:$cond, 0)), F64:$lhs, F64:$rhs), 101309124Sdim (SELECT_F64 F64:$rhs, F64:$lhs, I32:$cond)>; 102