00001 #include "xi-Module.h"
00002
00003 #include <fstream>
00004 #include <iostream>
00005
00006 using std::cout;
00007 using std::cerr;
00008 using std::endl;
00009
00010 namespace xi {
00011
00012 extern int fortranMode;
00013
00014 Module::Module(int l, const char* n, ConstructList* c) : name(n), clist(c) {
00015 line = l;
00016 _isMain = 0;
00017 if (clist) clist->recurse(this, &Construct::setModule);
00018 }
00019
00020 void Module::print(XStr& str) {
00021 if (external) str << "extern ";
00022 str << "module " << name;
00023 if (clist) {
00024 str << " {\n";
00025 clist->print(str);
00026 str << "}\n";
00027 } else {
00028 str << ";\n";
00029 }
00030 }
00031
00032 void Module::check() {
00033 if (clist) clist->check();
00034 }
00035
00036 void Module::generate() {
00037 using std::ofstream;
00038 XStr declstr, defstr;
00039 XStr pubDeclStr, pubDefStr, pubDefConstr;
00040
00041
00042 #if CMK_CELL != 0
00043 XStr accelstr_spe_c, accelstr_spe_h;
00044 #endif
00045
00046 declstr << "#ifndef _DECL_" << name
00047 << "_H_\n"
00048 "#define _DECL_"
00049 << name
00050 << "_H_\n"
00051 "#include \"charm++.h\"\n"
00052 "#include \"envelope.h\"\n"
00053 "#include <memory>\n"
00054 "#include \"sdag.h\"\n";
00055
00056 if (isTramTarget()) declstr << "#include \"NDMeshStreamer.h\"\n";
00057 if (fortranMode) declstr << "#include \"charm-api.h\"\n";
00058 if (clist) clist->genDecls(declstr);
00059 if (clist) clist->outputClosuresDecl(declstr);
00060 if (clist) clist->outputClosuresDef(defstr);
00061 declstr << "extern void _register" << name << "(void);\n";
00062 if (isMain()) {
00063 declstr << "extern \"C\" void CkRegisterMainModule(void);\n";
00064 }
00065
00066
00067
00068 genDefs(defstr);
00069 templateGuardBegin(false, defstr);
00070 defstr << "void _register" << name
00071 << "(void)\n"
00072 "{\n"
00073 " static int _done = 0; if(_done) return; _done = 1;\n";
00074 if (isTramTarget()) defstr << " _registerNDMeshStreamer();\n";
00075 if (clist) clist->genReg(defstr);
00076 defstr << "}\n";
00077 if (isMain()) {
00078 if (fortranMode) defstr << "extern void _registerf90main(void);\n";
00079 defstr << "extern \"C\" void CkRegisterMainModule(void) {\n";
00080 if (fortranMode) {
00081 defstr << " // FORTRAN\n";
00082 defstr << " _registerf90main();\n";
00083 }
00084 defstr << " _register" << name
00085 << "();\n"
00086 "}\n";
00087 }
00088 templateGuardEnd(defstr);
00089
00090
00091 if (clist) clist->genGlobalCode("", declstr, defstr);
00092 declstr << "#endif" << endx;
00093
00094
00095 #if CMK_CELL != 0
00096
00098 accelstr_spe_c << "#ifndef __ACCEL_" << name << "_C__\n"
00099 << "#define __ACCEL_" << name << "_C__\n\n\n";
00100 int numAccelEntries = genAccels_spe_c_funcBodies(accelstr_spe_c);
00101 accelstr_spe_c << "\n\n#endif //__ACCEL_" << name << "_C__\n";
00102
00104 accelstr_spe_h << "#ifndef __ACCEL_" << name << "_H__\n"
00105 << "#define __ACCEL_" << name << "_H__\n\n\n";
00106 genAccels_spe_h_includes(accelstr_spe_h);
00107 accelstr_spe_h << "\n\n";
00108 accelstr_spe_h << "#define MODULE_" << name << "_FUNC_INDEX_COUNT (" << numAccelEntries;
00109 genAccels_spe_h_fiCountDefs(accelstr_spe_h);
00110 accelstr_spe_h << ")\n\n\n";
00111 accelstr_spe_h << "#endif //__ACCEL_" << name << "_H__\n";
00112
00113 #endif
00114
00115 XStr topname, botname;
00116 topname << name << ".decl.h";
00117 botname << name << ".def.h";
00118 ofstream decl(topname.get_string()), def(botname.get_string());
00119 if (!decl || !def) {
00120 cerr << "Cannot open " << topname.get_string() << "or " << botname.get_string()
00121 << " for writing!!\n";
00122 die("cannot create output files (check directory permissions)\n");
00123 }
00124
00125 std::string defstr_with_line_numbers =
00126 addLineNumbers(defstr.get_string(), botname.get_string());
00127 std::string sanitizedDefs(defstr_with_line_numbers.c_str());
00128 desanitizeCode(sanitizedDefs);
00129 decl << declstr.get_string();
00130 def << sanitizedDefs.c_str();
00131
00132
00133 #if CMK_CELL != 0
00134
00136 XStr accelname_c, accelname_h;
00137 accelname_c << name << ".genSPECode.c";
00138 accelname_h << name << ".genSPECode.h";
00139 ofstream accel_c(accelname_c.get_string()), accel_h(accelname_h.get_string());
00140 if (!accel_c) {
00141 cerr << "Cannot open " << accelname_c.get_string() << " for writing!!\n";
00142 die("Cannot create output files (check directory permissions)\n");
00143 }
00144 if (!accel_h) {
00145 cerr << "Cannot open " << accelname_h.get_string() << " for writing!!\n";
00146 die("Cannot create output files (check directory permissions)\n");
00147 }
00148 accel_c << accelstr_spe_c.get_string();
00149 accel_h << accelstr_spe_h.get_string();
00150
00151
00152
00153 if (isMain()) {
00154 XStr mainAccelStr_c;
00155 mainAccelStr_c << "#include \"main__funcLookup__.genSPECode.h"
00156 << "\"\n"
00157 << "#include \"" << name << ".genSPECode.c"
00158 << "\"\n";
00159 ofstream mainAccel_c("main__funcLookup__.genSPECode.c");
00160 if (!mainAccel_c) {
00161 cerr << "Cannot open main__funcLookup__.genSPECode.c for writing!!\n";
00162 die("Cannot create output files (check directory permissions)");
00163 }
00164 mainAccel_c << mainAccelStr_c.get_string();
00165
00166 XStr mainAccelStr_h;
00167 mainAccelStr_h << "#ifndef __MAIN_FUNCLOOKUP_H__\n"
00168 << "#define __MAIN_FUNCLOOKUP_H__\n\n"
00169 << "#include <spu_intrinsics.h>\n"
00170 << "#include <stdlib.h>\n"
00171 << "#include <stdio.h>\n"
00172 << "#include \"spert.h\"\n\n"
00173 << "#include \"simd.h\"\n"
00174 << "#include \"" << name << ".genSPECode.h"
00175 << "\"\n\n"
00176 << "#endif //__MAIN_FUNCLOOKUP_H__\n";
00177 ofstream mainAccel_h("main__funcLookup__.genSPECode.h");
00178 if (!mainAccel_h) {
00179 cerr << "Cannot open main__funcLookup__.genSPECode.h for writing!!\n";
00180 die("Cannot create output files (check directory permissions)");
00181 }
00182 mainAccel_h << mainAccelStr_h.get_string();
00183 }
00184
00185 #endif
00186 }
00187
00188 void Module::preprocess() {
00189 if (clist != NULL) clist->preprocess();
00190 }
00191
00192 void Module::genDepend(const char* cifile) {
00193 cout << name << ".decl.h " << name << ".def.h: " << cifile << ".stamp" << endl;
00194 }
00195
00196 void Module::genDecls(XStr& str) {
00197 if (external) {
00198 str << "#include \"" << name << ".decl.h\"\n";
00199 } else {
00200 if (clist) clist->genDecls(str);
00201 }
00202
00203 #if CMK_CELL != 0
00204 str << "extern int register_accel_spe_funcs__module_" << name << "(int curIndex);\n";
00205 if (isMain()) {
00206 str << "extern \"C\" void register_accel_spe_funcs(void);\n";
00207 }
00208 #endif
00209 }
00210
00211 void Module::genDefs(XStr& str) {
00212 if (!external)
00213 if (clist) clist->genDefs(str);
00214
00215
00216 #if CMK_CELL != 0
00217
00218 if (!external) {
00219 templateGuardBegin(false, str);
00220
00221
00222
00223
00224
00225
00226 str << "int register_accel_spe_funcs__module_" << name << "(int curIndex) {\n"
00227 << " static int hasAlreadyRegisteredFlag = 0;\n"
00228 << " if (hasAlreadyRegisteredFlag) { return curIndex; };\n"
00229 << " hasAlreadyRegisteredFlag = 1;\n";
00230 genAccels_ppe_c_regFuncs(str);
00231 str << " return curIndex;\n"
00232 << "}\n";
00233
00234
00235 if (isMain()) {
00236 str << "#include\"spert.h\"\n"
00237 << "extern \"C\" void register_accel_spe_funcs(void) {\n"
00238 << " register_accel_spe_funcs__module_" << name << "(SPE_FUNC_INDEX_USER);\n"
00239 << "}\n";
00240 }
00241
00242 templateGuardEnd(str);
00243 }
00244
00245 #endif
00246 }
00247
00248 void Module::genReg(XStr& str) {
00249 if (external) {
00250 str << " _register" << name << "();" << endx;
00251 } else {
00252 if (clist) clist->genDefs(str);
00253 }
00254 }
00255
00256 bool Module::isTramTarget() {
00257 if (clist)
00258 return clist->isTramTarget();
00259 else
00260 return false;
00261 }
00262
00263 int Module::genAccels_spe_c_funcBodies(XStr& str) {
00264
00265 if (external) {
00266 str << "#include \"" << name << ".genSPECode.c\"\n";
00267 return 0;
00268 }
00269
00270
00271 if (isMain()) {
00272 str << "typedef void(*AccelFuncPtr)(DMAListEntry*);\n\n"
00273 << "typedef struct __func_lookup_table_entry {\n"
00274 << " int funcIndex;\n"
00275 << " AccelFuncPtr funcPtr;\n"
00276 << "} FuncLookupTableEntry;\n\n"
00277 << "FuncLookupTableEntry funcLookupTable[MODULE_" << name
00278 << "_FUNC_INDEX_COUNT];\n\n\n";
00279 }
00280
00281
00282 int rtn = 0;
00283 if (clist) {
00284 rtn += clist->genAccels_spe_c_funcBodies(str);
00285 }
00286
00287
00288
00289
00290
00291
00292 str << "int register_accel_funcs_" << name << "(int curIndex) {\n"
00293 << " static int hasAlreadyRegisteredFlag = 0;\n"
00294 << " if (hasAlreadyRegisteredFlag) { return curIndex; };\n"
00295 << " hasAlreadyRegisteredFlag = 1;\n";
00296 genAccels_spe_c_regFuncs(str);
00297 str << " return curIndex;\n"
00298 << "}\n\n\n";
00299
00300
00301 if (isMain()) {
00302 str << "\n\n";
00303 str << "#ifdef __cplusplus\n"
00304 << "extern \"C\"\n"
00305 << "#endif\n"
00306 << "void funcLookup(int funcIndex,\n"
00307 << " void* readWritePtr, int readWriteLen,\n"
00308 << " void* readOnlyPtr, int readOnlyLen,\n"
00309 << " void* writeOnlyPtr, int writeOnlyLen,\n"
00310 << " DMAListEntry* dmaList\n"
00311 << " ) {\n\n";
00312
00313 str << " if ((funcIndex >= SPE_FUNC_INDEX_USER) && (funcIndex < "
00314 "(SPE_FUNC_INDEX_USER + MODULE_"
00315 << name
00316 << "_FUNC_INDEX_COUNT))) {\n"
00317
00318
00319
00320
00321
00322 << " (funcLookupTable[funcIndex - SPE_FUNC_INDEX_USER].funcPtr)(dmaList);\n"
00323 << " } else if (funcIndex == SPE_FUNC_INDEX_INIT) {\n"
00324 << " if (register_accel_funcs_" << name << "(0) != MODULE_" << name
00325 << "_FUNC_INDEX_COUNT) {\n"
00326 << " printf(\"ERROR : register_accel_funcs_" << name
00327 << "() returned an invalid value.\\n\");\n"
00328 << " };\n";
00329 genAccels_spe_c_callInits(str);
00330 str << " } else if (funcIndex == SPE_FUNC_INDEX_CLOSE) {\n"
00331 << " // NOTE : Do nothing on close, but handle case...\n"
00332 << " } else {\n"
00333 << " printf(\"ERROR : Unknown funcIndex (%d) passed to funcLookup()... "
00334 "ignoring.\\n\", funcIndex);\n"
00335 << " }\n";
00336
00337 str << "}\n";
00338 }
00339
00340 return rtn;
00341 }
00342
00343 void Module::genAccels_spe_c_regFuncs(XStr& str) {
00344 if (external) {
00345 str << " curIndex = register_accel_funcs_" << name << "(curIndex);\n";
00346 } else {
00347 if (clist) {
00348 clist->genAccels_spe_c_regFuncs(str);
00349 }
00350 }
00351 }
00352
00353 void Module::genAccels_spe_c_callInits(XStr& str) {
00354 if (clist) {
00355 clist->genAccels_spe_c_callInits(str);
00356 }
00357 }
00358
00359 void Module::genAccels_spe_h_includes(XStr& str) {
00360 if (external) {
00361 str << "#include \"" << name << ".genSPECode.h\"\n";
00362 }
00363 if (clist) {
00364 clist->genAccels_spe_h_includes(str);
00365 }
00366 }
00367
00368 void Module::genAccels_spe_h_fiCountDefs(XStr& str) {
00369 if (external) {
00370 str << " + MODULE_" << name << "_FUNC_INDEX_COUNT";
00371 }
00372 if (clist) {
00373 clist->genAccels_spe_h_fiCountDefs(str);
00374 }
00375 }
00376
00377 void Module::genAccels_ppe_c_regFuncs(XStr& str) {
00378 if (external) {
00379 str << " curIndex = register_accel_spe_funcs__module_" << name << "(curIndex);\n";
00380 } else {
00381 if (clist) {
00382 clist->genAccels_ppe_c_regFuncs(str);
00383 }
00384 }
00385 }
00386
00387 }