X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FWebAssembly%2FWebAssemblyInstrFloat.td;h=d966380e6b0cfe54c475af338b31ebddad8ce0a2;hb=51b079cd28aacf110bf1b53c89bca4a2b23c4d22;hp=b9906d7a3f065cb4924ce31a10bdea403597de7c;hpb=7bfd515593043008422d401f2a5b5ac06d7f9bbc;p=oota-llvm.git diff --git a/lib/Target/WebAssembly/WebAssemblyInstrFloat.td b/lib/Target/WebAssembly/WebAssemblyInstrFloat.td index b9906d7a3f0..d966380e6b0 100644 --- a/lib/Target/WebAssembly/WebAssemblyInstrFloat.td +++ b/lib/Target/WebAssembly/WebAssemblyInstrFloat.td @@ -12,26 +12,84 @@ /// //===----------------------------------------------------------------------===// -/* - * TODO(jfb): Add the following for 32-bit and 64-bit. - * - * float32.add: addition - * float32.sub: subtraction - * float32.mul: multiplication - * float32.div: division - * float32.abs: absolute value - * float32.neg: negation - * float32.copysign: copysign - * float32.ceil: ceiling operation - * float32.floor: floor operation - * float32.trunc: round to nearest integer towards zero - * float32.nearestint: round to nearest integer, ties to even - * float32.eq: compare equal - * float32.lt: less than - * float32.le: less than or equal - * float32.gt: greater than - * float32.ge: greater than or equal - * float32.sqrt: square root - * float32.min: minimum (binary operator); if either operand is NaN, returns NaN - * float32.max: maximum (binary operator); if either operand is NaN, returns NaN - */ +let Defs = [ARGUMENTS] in { + +let isCommutable = 1 in +defm ADD : BinaryFP; +defm SUB : BinaryFP; +let isCommutable = 1 in +defm MUL : BinaryFP; +defm DIV : BinaryFP; +defm SQRT : UnaryFP; + +defm ABS : UnaryFP; +defm NEG : UnaryFP; +defm COPYSIGN : BinaryFP; + +let isCommutable = 1 in { +defm MIN : BinaryFP; +defm MAX : BinaryFP; +} // isCommutable = 1 + +defm CEIL : UnaryFP; +defm FLOOR : UnaryFP; +defm TRUNC : UnaryFP; +defm NEAREST : UnaryFP; + +} // Defs = [ARGUMENTS] + +// WebAssembly doesn't expose inexact exceptions, so map frint to fnearbyint. +def : Pat<(frint f32:$src), (NEAREST_F32 f32:$src)>; +def : Pat<(frint f64:$src), (NEAREST_F64 f64:$src)>; + +let Defs = [ARGUMENTS] in { + +let isCommutable = 1 in { +defm EQ : ComparisonFP; +defm NE : ComparisonFP; +} // isCommutable = 1 +defm LT : ComparisonFP; +defm LE : ComparisonFP; +defm GT : ComparisonFP; +defm GE : ComparisonFP; + +} // Defs = [ARGUMENTS] + +// Don't care floating-point comparisons, supported via other comparisons. +def : Pat<(seteq f32:$lhs, f32:$rhs), (EQ_F32 f32:$lhs, f32:$rhs)>; +def : Pat<(setne f32:$lhs, f32:$rhs), (NE_F32 f32:$lhs, f32:$rhs)>; +def : Pat<(setlt f32:$lhs, f32:$rhs), (LT_F32 f32:$lhs, f32:$rhs)>; +def : Pat<(setle f32:$lhs, f32:$rhs), (LE_F32 f32:$lhs, f32:$rhs)>; +def : Pat<(setgt f32:$lhs, f32:$rhs), (GT_F32 f32:$lhs, f32:$rhs)>; +def : Pat<(setge f32:$lhs, f32:$rhs), (GE_F32 f32:$lhs, f32:$rhs)>; +def : Pat<(seteq f64:$lhs, f64:$rhs), (EQ_F64 f64:$lhs, f64:$rhs)>; +def : Pat<(setne f64:$lhs, f64:$rhs), (NE_F64 f64:$lhs, f64:$rhs)>; +def : Pat<(setlt f64:$lhs, f64:$rhs), (LT_F64 f64:$lhs, f64:$rhs)>; +def : Pat<(setle f64:$lhs, f64:$rhs), (LE_F64 f64:$lhs, f64:$rhs)>; +def : Pat<(setgt f64:$lhs, f64:$rhs), (GT_F64 f64:$lhs, f64:$rhs)>; +def : Pat<(setge f64:$lhs, f64:$rhs), (GE_F64 f64:$lhs, f64:$rhs)>; + +let Defs = [ARGUMENTS] in { + +def SELECT_F32 : I<(outs F32:$dst), (ins I32:$cond, F32:$lhs, F32:$rhs), + [(set F32:$dst, (select I32:$cond, F32:$lhs, F32:$rhs))], + "f32.select\t$dst, $cond, $lhs, $rhs">; +def SELECT_F64 : I<(outs F64:$dst), (ins I32:$cond, F64:$lhs, F64:$rhs), + [(set F64:$dst, (select I32:$cond, F64:$lhs, F64:$rhs))], + "f64.select\t$dst, $cond, $lhs, $rhs">; + +} // Defs = [ARGUMENTS] + +// ISD::SELECT requires its operand to conform to getBooleanContents, but +// WebAssembly's select interprets any non-zero value as true, so we can fold +// a setne with 0 into a select. +def : Pat<(select (i32 (setne I32:$cond, 0)), F32:$lhs, F32:$rhs), + (SELECT_F32 I32:$cond, F32:$lhs, F32:$rhs)>; +def : Pat<(select (i32 (setne I32:$cond, 0)), F64:$lhs, F64:$rhs), + (SELECT_F64 I32:$cond, F64:$lhs, F64:$rhs)>; + +// And again, this time with seteq instead of setne and the arms reversed. +def : Pat<(select (i32 (seteq I32:$cond, 0)), F32:$lhs, F32:$rhs), + (SELECT_F32 I32:$cond, F32:$rhs, F32:$lhs)>; +def : Pat<(select (i32 (seteq I32:$cond, 0)), F64:$lhs, F64:$rhs), + (SELECT_F64 I32:$cond, F64:$rhs, F64:$lhs)>;