1 /************************************************************************
2  ************************************************************************
3     FAUST compiler
4     Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
5     ---------------------------------------------------------------------
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  ************************************************************************
20  ************************************************************************/
21 
22 #ifndef _BINOP_
23 #define _BINOP_
24 
25 #include "fbc_opcode.hh"
26 #include "node.hh"
27 
28 typedef const Node (*comp)(const Node& a, const Node& b);
29 typedef bool (*pred)(const Node& a);
30 
31 bool falsePredicate(Node const& a);
32 
33 enum WasmOp {
34 
35     I32EqZ = 0x45,
36     I32Eq  = 0x46,
37     I32Ne  = 0x47,
38     I32LtS = 0x48,
39     I32LtU = 0x49,
40     I32GtS = 0x4a,
41     I32GtU = 0x4b,
42     I32LeS = 0x4c,
43     I32LeU = 0x4d,
44     I32GeS = 0x4e,
45     I32GeU = 0x4f,
46     I64EqZ = 0x50,
47     I64Eq  = 0x51,
48     I64Ne  = 0x52,
49     I64LtS = 0x53,
50     I64LtU = 0x54,
51     I64GtS = 0x55,
52     I64GtU = 0x56,
53     I64LeS = 0x57,
54     I64LeU = 0x58,
55     I64GeS = 0x59,
56     I64GeU = 0x5a,
57     F32Eq  = 0x5b,
58     F32Ne  = 0x5c,
59     F32Lt  = 0x5d,
60     F32Gt  = 0x5e,
61     F32Le  = 0x5f,
62     F32Ge  = 0x60,
63     F64Eq  = 0x61,
64     F64Ne  = 0x62,
65     F64Lt  = 0x63,
66     F64Gt  = 0x64,
67     F64Le  = 0x65,
68     F64Ge  = 0x66,
69 
70     I32Clz    = 0x67,
71     I32Ctz    = 0x68,
72     I32Popcnt = 0x69,
73     I32Add    = 0x6a,
74     I32Sub    = 0x6b,
75     I32Mul    = 0x6c,
76     I32DivS   = 0x6d,
77     I32DivU   = 0x6e,
78     I32RemS   = 0x6f,
79     I32RemU   = 0x70,
80     I32And    = 0x71,
81     I32Or     = 0x72,
82     I32Xor    = 0x73,
83     I32Shl    = 0x74,
84     I32ShrS   = 0x75,
85     I32ShrU   = 0x76,
86     I32RotL   = 0x77,
87     I32RotR   = 0x78,
88 
89     I64Clz    = 0x79,
90     I64Ctz    = 0x7a,
91     I64Popcnt = 0x7b,
92     I64Add    = 0x7c,
93     I64Sub    = 0x7d,
94     I64Mul    = 0x7e,
95     I64DivS   = 0x7f,
96     I64DivU   = 0x80,
97     I64RemS   = 0x81,
98     I64RemU   = 0x82,
99     I64And    = 0x83,
100     I64Or     = 0x84,
101     I64Xor    = 0x85,
102     I64Shl    = 0x86,
103     I64ShrS   = 0x87,
104     I64ShrU   = 0x88,
105     I64RotL   = 0x89,
106     I64RotR   = 0x8a,
107 
108     F32Abs        = 0x8b,
109     F32Neg        = 0x8c,
110     F32Ceil       = 0x8d,
111     F32Floor      = 0x8e,
112     F32Trunc      = 0x8f,
113     F32NearestInt = 0x90,
114     F32Sqrt       = 0x91,
115     F32Add        = 0x92,
116     F32Sub        = 0x93,
117     F32Mul        = 0x94,
118     F32Div        = 0x95,
119     F32Min        = 0x96,
120     F32Max        = 0x97,
121     F32CopySign   = 0x98,
122 
123     F64Abs        = 0x99,
124     F64Neg        = 0x9a,
125     F64Ceil       = 0x9b,
126     F64Floor      = 0x9c,
127     F64Trunc      = 0x9d,
128     F64NearestInt = 0x9e,
129     F64Sqrt       = 0x9f,
130     F64Add        = 0xa0,
131     F64Sub        = 0xa1,
132     F64Mul        = 0xa2,
133     F64Div        = 0xa3,
134     F64Min        = 0xa4,
135     F64Max        = 0xa5,
136     F64CopySign   = 0xa6,
137 
138     Dummy = 0x00
139 
140 };
141 
142 // No Garbageable since used in static table
143 struct BinOp {
144     const char* fName;
145     const char* fNameVec;
146     const char* fNameScal;
147     const char* fNameLLVMInt;
148     const char* fNameLLVMFloat;
149 
150     unsigned int fLLVMIntInst;
151     unsigned int fLLVMFloatInst;
152 
153     const char* fNameWastInt32;
154     const char* fNameWastInt64;
155     const char* fNameWastFloat;
156     const char* fNameWastDouble;
157 
158     WasmOp fWasmInt32;
159     WasmOp fWasmInt64;
160     WasmOp fWasmFloat;
161     WasmOp fWasmDouble;
162 
163     FBCInstruction::Opcode fInterpIntInst32;
164     FBCInstruction::Opcode fInterpFloatInst;
165 
166     comp fCompute;
167     pred fLeftNeutral;
168     pred fRightNeutral;
169     pred fLeftAbsorbing;
170     pred fRightAbsorbing;
171     int  fPriority;
172 
BinOpBinOp173     BinOp(const char* name, const char* name_vec, const char* name_scal, const char* name_llvm_int,
174           const char* name_llvm_float, unsigned int llvm_int, unsigned int llvm_float, const char* name_wasm_int32,
175           const char* name_wasm_int64, const char* name_wasm_float, const char* name_wasm_double, WasmOp wasm_int32,
176           WasmOp wasm_int64, WasmOp wasm_float, WasmOp wasm_double, FBCInstruction::Opcode interp_int32,
177           FBCInstruction::Opcode interp_float, comp fun, pred ln, pred rn, int priority, pred la = falsePredicate,
178           pred ra = falsePredicate)
179         : fName(name),
180           fNameVec(name_vec),
181           fNameScal(name_scal),
182           fNameLLVMInt(name_llvm_int),
183           fNameLLVMFloat(name_llvm_float),
184           fLLVMIntInst(llvm_int),
185           fLLVMFloatInst(llvm_float),
186           fNameWastInt32(name_wasm_int32),
187           fNameWastInt64(name_wasm_int64),
188           fNameWastFloat(name_wasm_float),
189           fNameWastDouble(name_wasm_double),
190           fWasmInt32(wasm_int32),
191           fWasmInt64(wasm_int64),
192           fWasmFloat(wasm_float),
193           fWasmDouble(wasm_double),
194           fInterpIntInst32(interp_int32),
195           fInterpFloatInst(interp_float),
196           fCompute(fun),
197           fLeftNeutral(ln),
198           fRightNeutral(rn),
199           fLeftAbsorbing(la),
200           fRightAbsorbing(ra),
201           fPriority(priority)
202     {
203     }
204 
computeBinOp205     Node compute(const Node& a, const Node& b) { return fCompute(a, b); }
206 
isRightNeutralBinOp207     bool isRightNeutral(const Node& a) { return fRightNeutral(a); }
isLeftNeutralBinOp208     bool isLeftNeutral(const Node& a) { return fLeftNeutral(a); }
isLeftAbsorbingBinOp209     bool isLeftAbsorbing(const Node& a) { return fLeftAbsorbing(a); }
isRightAbsorbingBinOp210     bool isRightAbsorbing(const Node& a) { return fRightAbsorbing(a); }
211 };
212 
213 extern BinOp* gBinOpTable[];
214 extern BinOp* gBinOpLateqTable[];
215 
216 enum SOperator { kAdd, kSub, kMul, kDiv, kRem, kLsh, kARsh, kLRsh, kGT, kLT, kGE, kLE, kEQ, kNE, kAND, kOR, kXOR };
217 
218 bool isBoolOpcode(int o);
219 bool isLogicalOpcode(int o);
220 bool isShiftOpcode(int o);
221 bool isCommutativeOpcode(int o);
222 
223 #endif
224