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 _INSTRUCTION_COMPILER_H 23 #define _INSTRUCTION_COMPILER_H 24 25 #include <list> 26 #include <map> 27 #include <set> 28 #include <string> 29 #include <vector> 30 31 #include "Text.hh" 32 #include "code_container.hh" 33 #include "garbageable.hh" 34 #include "global.hh" 35 #include "instructions.hh" 36 #include "dcond.hh" 37 #include "old_occurences.hh" 38 #include "property.hh" 39 40 #define _DNF_ 1 41 42 using namespace std; 43 44 typedef ValueInst* InstType; 45 46 class InstructionsCompiler : public virtual Garbageable { 47 protected: 48 CodeContainer* fContainer; 49 50 property<ValueInst*> fCompileProperty; 51 property<string> fVectorProperty; 52 property<pair<string, string>> fStaticInitProperty; 53 property<pair<string, string>> fInstanceInitProperty; 54 property<string> fTableProperty; 55 56 map<Tree, Tree> fConditionProperty; // used with the new X,Y:enable --> sigControl(X*Y,Y>0) primitive 57 58 Tree fSharingKey; 59 old_OccMarkup* fOccMarkup; 60 61 // Ensure IOTA base fixed delays are computed once 62 std::map<int, std::string> fIOTATable; 63 64 Tree fUIRoot; 65 Description* fDescription; 66 67 /* 68 -dlt <N> : threshold between 'mask' and 'select' based ring-buffer delay line model. 69 'mask' delay-lines use the next power-of-two value size and a mask (faster but use more memory) 70 'select' delay-line use N+1 and use select to wrap the read/write indexes (use less memory but slower) 71 */ 72 73 bool fHasIota; 74 75 void getTypedNames(::Type t, const string& prefix, Typed::VarType& ctype, string& vname); 76 77 bool getCompiledExpression(Tree sig, InstType& cexp); 78 InstType setCompiledExpression(Tree sig, const InstType& cexp); 79 80 void setVectorNameProperty(Tree sig, const string& vecname); 81 bool getVectorNameProperty(Tree sig, string& vecname); 82 83 void setTableNameProperty(Tree sig, const string& vecname); 84 bool getTableNameProperty(Tree sig, string& vecname); 85 86 // Redefined by RustInstructionsCompiler 87 virtual StatementInst* generateInitArray(const string& vname, Typed::VarType ctype, int delay); 88 virtual StatementInst* generateCopyArray(const string& vname, int index_from, int index_to); 89 virtual StatementInst* generateCopyArray(const string& vname_to, const string& vname_from, int size); 90 91 // Redefined in InterpreterInstructionsCompiler 92 virtual StatementInst* generateShiftArray(const string& vname, int delay); 93 94 ValueInst* generateButtonAux(Tree sig, Tree path, const string& name); 95 ValueInst* generateSliderAux(Tree sig, Tree path, Tree cur, Tree min, Tree max, Tree step, const string& name); 96 ValueInst* generateBargraphAux(Tree sig, Tree path, Tree min, Tree max, ValueInst* exp, const string& name); 97 98 // wrapper functions to access code container pushInitMethod(StatementInst * inst)99 StatementInst* pushInitMethod(StatementInst* inst) { return fContainer->pushInitMethod(inst); } pushResetUIInstructions(StatementInst * inst)100 StatementInst* pushResetUIInstructions(StatementInst* inst) { return fContainer->pushResetUIInstructions(inst); } pushClearMethod(StatementInst * inst)101 StatementInst* pushClearMethod(StatementInst* inst) { return fContainer->pushClearMethod(inst); } pushPostInitMethod(StatementInst * inst)102 StatementInst* pushPostInitMethod(StatementInst* inst) { return fContainer->pushPostInitMethod(inst); } pushPreInitMethod(StatementInst * inst)103 StatementInst* pushPreInitMethod(StatementInst* inst) { return fContainer->pushPreInitMethod(inst); } pushDestroyMethod(StatementInst * inst)104 StatementInst* pushDestroyMethod(StatementInst* inst) { return fContainer->pushDestroyMethod(inst); } pushStaticInitMethod(StatementInst * inst)105 StatementInst* pushStaticInitMethod(StatementInst* inst) { return fContainer->pushStaticInitMethod(inst); } pushPostStaticInitMethod(StatementInst * inst)106 StatementInst* pushPostStaticInitMethod(StatementInst* inst) { return fContainer->pushPostStaticInitMethod(inst); } pushStaticDestroyMethod(StatementInst * inst)107 StatementInst* pushStaticDestroyMethod(StatementInst* inst) { return fContainer->pushStaticDestroyMethod(inst); } pushComputeBlockMethod(StatementInst * inst)108 StatementInst* pushComputeBlockMethod(StatementInst* inst) { return fContainer->pushComputeBlockMethod(inst); } pushPostComputeBlockMethod(StatementInst * inst)109 StatementInst* pushPostComputeBlockMethod(StatementInst* inst) 110 { 111 return fContainer->pushPostComputeBlockMethod(inst); 112 } pushUserInterfaceMethod(StatementInst * inst)113 StatementInst* pushUserInterfaceMethod(StatementInst* inst) { return fContainer->pushUserInterfaceMethod(inst); } 114 pushDeclare(StatementInst * inst)115 StatementInst* pushDeclare(StatementInst* inst) { return fContainer->pushDeclare(inst); } pushGlobalDeclare(StatementInst * inst)116 StatementInst* pushGlobalDeclare(StatementInst* inst) { return fContainer->pushGlobalDeclare(inst); } pushExtGlobalDeclare(StatementInst * inst)117 StatementInst* pushExtGlobalDeclare(StatementInst* inst) { return fContainer->pushExtGlobalDeclare(inst); } 118 pushPreComputeDSPMethod(StatementInst * inst)119 StatementInst* pushPreComputeDSPMethod(StatementInst* inst) { return fContainer->pushPreComputeDSPMethod(inst); } pushComputeDSPMethod(StatementInst * inst)120 StatementInst* pushComputeDSPMethod(StatementInst* inst) { return fContainer->pushComputeDSPMethod(inst); } pushPostComputeDSPMethod(StatementInst * inst)121 StatementInst* pushPostComputeDSPMethod(StatementInst* inst) { return fContainer->pushPostComputeDSPMethod(inst); } 122 123 void ensureIotaCode(); 124 pow2limit(int x)125 int pow2limit(int x) 126 { 127 int n = 2; 128 while (n < x) { 129 n = 2 * n; 130 } 131 return n; 132 } 133 ispowerof2(int x)134 bool ispowerof2(int x) 135 { 136 /* First x in the below expression is for the case when x is 0 */ 137 return x && (!(x&(x-1))); 138 } 139 140 CodeContainer* signal2Container(const string& name, Tree sig); 141 142 int getSharingCount(Tree sig); 143 void setSharingCount(Tree sig, int count); 144 void sharingAnalysis(Tree t); 145 void sharingAnnotation(int vctxt, Tree sig); 146 getCurrentLoopIndex()147 FIRIndex getCurrentLoopIndex() { return FIRIndex(fContainer->getCurLoop()->getLoopIndex()); } 148 149 void declareWaveform(Tree sig, string& vname, int& size); 150 151 // Enable/control 152 void conditionAnnotation(Tree l); 153 void conditionAnnotation(Tree t, Tree nc); 154 void conditionStatistics(Tree l); 155 156 ValueInst* cnf2code(Tree cc); 157 ValueInst* or2code(Tree oc); 158 159 ValueInst* dnf2code(Tree cc); 160 ValueInst* and2code(Tree oc); 161 162 ValueInst* getConditionCode(Tree sig); 163 164 public: 165 InstructionsCompiler(CodeContainer* container); 166 ~InstructionsCompiler()167 virtual ~InstructionsCompiler() {} 168 169 virtual ValueInst* CS(Tree sig); 170 171 virtual void compileMultiSignal(Tree sig); 172 virtual void compileSingleSignal(Tree sig); 173 174 virtual ValueInst* generateVariableStore(Tree sig, ValueInst* inst); 175 virtual ValueInst* generateCacheCode(Tree sig, ValueInst* inst); 176 virtual ValueInst* forceCacheCode(Tree sig, ValueInst* inst); 177 178 // Code generation 179 virtual ValueInst* generateCode(Tree sig); 180 181 virtual ValueInst* generateXtended(Tree sig); 182 virtual ValueInst* generateDelay(Tree sig, Tree arg, Tree size); 183 virtual ValueInst* generatePrefix(Tree sig, Tree x, Tree e); 184 virtual ValueInst* generateIota(Tree sig, Tree arg); 185 virtual ValueInst* generateBinOp(Tree sig, int opcode, Tree arg1, Tree arg2); 186 187 virtual ValueInst* generateFFun(Tree sig, Tree ff, Tree largs); 188 virtual ValueInst* generateWaveform(Tree sig); 189 190 virtual ValueInst* generateInput(Tree sig, int idx); 191 192 virtual ValueInst* generateTable(Tree sig, Tree tsize, Tree content); 193 virtual ValueInst* generateStaticTable(Tree sig, Tree tsize, Tree content); 194 virtual ValueInst* generateWRTbl(Tree sig, Tree tbl, Tree idx, Tree data); 195 virtual ValueInst* generateRDTbl(Tree sig, Tree tbl, Tree idx); 196 virtual ValueInst* generateSigGen(Tree sig, Tree content); 197 virtual ValueInst* generateStaticSigGen(Tree sig, Tree content); 198 199 virtual ValueInst* generateSelect2(Tree sig, Tree sel, Tree s1, Tree s2); 200 201 virtual ValueInst* generateRecProj(Tree sig, Tree exp, int i); 202 virtual ValueInst* generateRec(Tree sig, Tree var, Tree le, int index = -1); 203 204 virtual ValueInst* generateIntCast(Tree sig, Tree x); 205 virtual ValueInst* generateFloatCast(Tree sig, Tree x); 206 207 virtual ValueInst* generateButton(Tree sig, Tree label); 208 virtual ValueInst* generateCheckbox(Tree sig, Tree label); 209 virtual ValueInst* generateVSlider(Tree sig, Tree label, Tree cur, Tree min, Tree max, Tree step); 210 virtual ValueInst* generateHSlider(Tree sig, Tree label, Tree cur, Tree min, Tree max, Tree step); 211 virtual ValueInst* generateNumEntry(Tree sig, Tree label, Tree cur, Tree min, Tree max, Tree step); 212 213 virtual ValueInst* generateVBargraph(Tree sig, Tree label, Tree min, Tree max, ValueInst* exp); 214 virtual ValueInst* generateHBargraph(Tree sig, Tree label, Tree min, Tree max, ValueInst* exp); 215 216 virtual ValueInst* generateSoundfile(Tree sig, Tree label); 217 virtual ValueInst* generateSoundfileLength(Tree sig, ValueInst* sf, ValueInst* part); 218 virtual ValueInst* generateSoundfileRate(Tree sig, ValueInst* sf, ValueInst* part); 219 virtual ValueInst* generateSoundfileBuffer(Tree sig, ValueInst* sf, ValueInst* x, ValueInst* y, ValueInst* z); 220 221 virtual ValueInst* generateIntNumber(Tree sig, int num); 222 virtual ValueInst* generateRealNumber(Tree sig, double num); 223 virtual ValueInst* generateFConst(Tree sig, Tree type, const string& file, const string& name); 224 virtual ValueInst* generateFVar(Tree sig, Tree type, const string& file, const string& name); 225 226 virtual ValueInst* generateDelayVec(Tree sig, ValueInst* exp, Typed::VarType ctype, const string& vname, int mxd); 227 virtual ValueInst* generateDelayLine(ValueInst* exp, Typed::VarType ctype, const string& vname, int mxd, 228 Address::AccessType& var_access, ValueInst* ccs); 229 230 virtual ValueInst* generateControl(Tree sig, Tree x, Tree y); 231 232 // UI hierachy description 233 void addUIWidget(Tree path, Tree widget); 234 Tree prepareUserInterfaceTree(Tree t); 235 void generateUserInterfaceTree(Tree t, bool root = false); 236 void generateUserInterfaceElements(Tree elements); 237 void generateWidgetCode(Tree fulllabel, Tree varname, Tree sig); 238 239 void generateMacroInterfaceTree(const string& pathname, Tree t); 240 void generateMacroInterfaceElements(const string& pathname, Tree elements); 241 void generateWidgetMacro(const string& pathname, Tree fulllabel, Tree varname, Tree sig); 242 setDescription(Description * descr)243 void setDescription(Description* descr) { fDescription = descr; } getDescription()244 Description* getDescription() { return fDescription; } 245 246 Tree prepare(Tree LS); 247 Tree prepare2(Tree L0); 248 249 }; 250 251 #endif 252