xref: /aosp_15_r20/external/llvm/lib/Target/WebAssembly/WebAssemblyInstrFloat.td (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker// WebAssemblyInstrFloat.td-WebAssembly Float codegen support ---*- tablegen -*-
2*9880d681SAndroid Build Coastguard Worker//
3*9880d681SAndroid Build Coastguard Worker//                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker//
5*9880d681SAndroid Build Coastguard Worker// This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker// License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker//
8*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker///
10*9880d681SAndroid Build Coastguard Worker/// \file
11*9880d681SAndroid Build Coastguard Worker/// \brief WebAssembly Floating-point operand code-gen constructs.
12*9880d681SAndroid Build Coastguard Worker///
13*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Workerlet Defs = [ARGUMENTS] in {
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Workerlet isCommutable = 1 in
18*9880d681SAndroid Build Coastguard Workerdefm ADD : BinaryFP<fadd, "add ">;
19*9880d681SAndroid Build Coastguard Workerdefm SUB : BinaryFP<fsub, "sub ">;
20*9880d681SAndroid Build Coastguard Workerlet isCommutable = 1 in
21*9880d681SAndroid Build Coastguard Workerdefm MUL : BinaryFP<fmul, "mul ">;
22*9880d681SAndroid Build Coastguard Workerdefm DIV : BinaryFP<fdiv, "div ">;
23*9880d681SAndroid Build Coastguard Workerdefm SQRT : UnaryFP<fsqrt, "sqrt">;
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Workerdefm ABS : UnaryFP<fabs, "abs ">;
26*9880d681SAndroid Build Coastguard Workerdefm NEG : UnaryFP<fneg, "neg ">;
27*9880d681SAndroid Build Coastguard Workerdefm COPYSIGN : BinaryFP<fcopysign, "copysign">;
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Workerlet isCommutable = 1 in {
30*9880d681SAndroid Build Coastguard Workerdefm MIN : BinaryFP<fminnan, "min ">;
31*9880d681SAndroid Build Coastguard Workerdefm MAX : BinaryFP<fmaxnan, "max ">;
32*9880d681SAndroid Build Coastguard Worker} // isCommutable = 1
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Workerdefm CEIL : UnaryFP<fceil, "ceil">;
35*9880d681SAndroid Build Coastguard Workerdefm FLOOR : UnaryFP<ffloor, "floor">;
36*9880d681SAndroid Build Coastguard Workerdefm TRUNC : UnaryFP<ftrunc, "trunc">;
37*9880d681SAndroid Build Coastguard Workerdefm NEAREST : UnaryFP<fnearbyint, "nearest">;
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Worker} // Defs = [ARGUMENTS]
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Worker// DAGCombine oddly folds casts into the rhs of copysign. Unfold them.
42*9880d681SAndroid Build Coastguard Workerdef : Pat<(fcopysign F64:$lhs, F32:$rhs),
43*9880d681SAndroid Build Coastguard Worker          (COPYSIGN_F64 F64:$lhs, (F64_PROMOTE_F32 F32:$rhs))>;
44*9880d681SAndroid Build Coastguard Workerdef : Pat<(fcopysign F32:$lhs, F64:$rhs),
45*9880d681SAndroid Build Coastguard Worker          (COPYSIGN_F32 F32:$lhs, (F32_DEMOTE_F64 F64:$rhs))>;
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker// WebAssembly doesn't expose inexact exceptions, so map frint to fnearbyint.
48*9880d681SAndroid Build Coastguard Workerdef : Pat<(frint f32:$src), (NEAREST_F32 f32:$src)>;
49*9880d681SAndroid Build Coastguard Workerdef : Pat<(frint f64:$src), (NEAREST_F64 f64:$src)>;
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Workerlet Defs = [ARGUMENTS] in {
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Workerlet isCommutable = 1 in {
54*9880d681SAndroid Build Coastguard Workerdefm EQ : ComparisonFP<SETOEQ, "eq  ">;
55*9880d681SAndroid Build Coastguard Workerdefm NE : ComparisonFP<SETUNE, "ne  ">;
56*9880d681SAndroid Build Coastguard Worker} // isCommutable = 1
57*9880d681SAndroid Build Coastguard Workerdefm LT : ComparisonFP<SETOLT, "lt  ">;
58*9880d681SAndroid Build Coastguard Workerdefm LE : ComparisonFP<SETOLE, "le  ">;
59*9880d681SAndroid Build Coastguard Workerdefm GT : ComparisonFP<SETOGT, "gt  ">;
60*9880d681SAndroid Build Coastguard Workerdefm GE : ComparisonFP<SETOGE, "ge  ">;
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker} // Defs = [ARGUMENTS]
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker// Don't care floating-point comparisons, supported via other comparisons.
65*9880d681SAndroid Build Coastguard Workerdef : Pat<(seteq f32:$lhs, f32:$rhs), (EQ_F32 f32:$lhs, f32:$rhs)>;
66*9880d681SAndroid Build Coastguard Workerdef : Pat<(setne f32:$lhs, f32:$rhs), (NE_F32 f32:$lhs, f32:$rhs)>;
67*9880d681SAndroid Build Coastguard Workerdef : Pat<(setlt f32:$lhs, f32:$rhs), (LT_F32 f32:$lhs, f32:$rhs)>;
68*9880d681SAndroid Build Coastguard Workerdef : Pat<(setle f32:$lhs, f32:$rhs), (LE_F32 f32:$lhs, f32:$rhs)>;
69*9880d681SAndroid Build Coastguard Workerdef : Pat<(setgt f32:$lhs, f32:$rhs), (GT_F32 f32:$lhs, f32:$rhs)>;
70*9880d681SAndroid Build Coastguard Workerdef : Pat<(setge f32:$lhs, f32:$rhs), (GE_F32 f32:$lhs, f32:$rhs)>;
71*9880d681SAndroid Build Coastguard Workerdef : Pat<(seteq f64:$lhs, f64:$rhs), (EQ_F64 f64:$lhs, f64:$rhs)>;
72*9880d681SAndroid Build Coastguard Workerdef : Pat<(setne f64:$lhs, f64:$rhs), (NE_F64 f64:$lhs, f64:$rhs)>;
73*9880d681SAndroid Build Coastguard Workerdef : Pat<(setlt f64:$lhs, f64:$rhs), (LT_F64 f64:$lhs, f64:$rhs)>;
74*9880d681SAndroid Build Coastguard Workerdef : Pat<(setle f64:$lhs, f64:$rhs), (LE_F64 f64:$lhs, f64:$rhs)>;
75*9880d681SAndroid Build Coastguard Workerdef : Pat<(setgt f64:$lhs, f64:$rhs), (GT_F64 f64:$lhs, f64:$rhs)>;
76*9880d681SAndroid Build Coastguard Workerdef : Pat<(setge f64:$lhs, f64:$rhs), (GE_F64 f64:$lhs, f64:$rhs)>;
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Workerlet Defs = [ARGUMENTS] in {
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Workerdef SELECT_F32 : I<(outs F32:$dst), (ins F32:$lhs, F32:$rhs, I32:$cond),
81*9880d681SAndroid Build Coastguard Worker                   [(set F32:$dst, (select I32:$cond, F32:$lhs, F32:$rhs))],
82*9880d681SAndroid Build Coastguard Worker                   "f32.select\t$dst, $lhs, $rhs, $cond">;
83*9880d681SAndroid Build Coastguard Workerdef SELECT_F64 : I<(outs F64:$dst), (ins F64:$lhs, F64:$rhs, I32:$cond),
84*9880d681SAndroid Build Coastguard Worker                   [(set F64:$dst, (select I32:$cond, F64:$lhs, F64:$rhs))],
85*9880d681SAndroid Build Coastguard Worker                   "f64.select\t$dst, $lhs, $rhs, $cond">;
86*9880d681SAndroid Build Coastguard Worker
87*9880d681SAndroid Build Coastguard Worker} // Defs = [ARGUMENTS]
88*9880d681SAndroid Build Coastguard Worker
89*9880d681SAndroid Build Coastguard Worker// ISD::SELECT requires its operand to conform to getBooleanContents, but
90*9880d681SAndroid Build Coastguard Worker// WebAssembly's select interprets any non-zero value as true, so we can fold
91*9880d681SAndroid Build Coastguard Worker// a setne with 0 into a select.
92*9880d681SAndroid Build Coastguard Workerdef : Pat<(select (i32 (setne I32:$cond, 0)), F32:$lhs, F32:$rhs),
93*9880d681SAndroid Build Coastguard Worker          (SELECT_F32 F32:$lhs, F32:$rhs, I32:$cond)>;
94*9880d681SAndroid Build Coastguard Workerdef : Pat<(select (i32 (setne I32:$cond, 0)), F64:$lhs, F64:$rhs),
95*9880d681SAndroid Build Coastguard Worker          (SELECT_F64 F64:$lhs, F64:$rhs, I32:$cond)>;
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker// And again, this time with seteq instead of setne and the arms reversed.
98*9880d681SAndroid Build Coastguard Workerdef : Pat<(select (i32 (seteq I32:$cond, 0)), F32:$lhs, F32:$rhs),
99*9880d681SAndroid Build Coastguard Worker          (SELECT_F32 F32:$rhs, F32:$lhs, I32:$cond)>;
100*9880d681SAndroid Build Coastguard Workerdef : Pat<(select (i32 (seteq I32:$cond, 0)), F64:$lhs, F64:$rhs),
101*9880d681SAndroid Build Coastguard Worker          (SELECT_F64 F64:$rhs, F64:$lhs, I32:$cond)>;
102