slicc: removed unused atomics code from StateMachine
[gem5.git] / src / mem / slicc / symbols / Type.cc
1
2 /*
3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /*
31 * Type.cc
32 *
33 * Description: See Type.hh
34 *
35 * $Id$
36 * */
37
38 #include "mem/slicc/symbols/Type.hh"
39 #include "mem/slicc/generator/fileio.hh"
40 #include "mem/gems_common/Map.hh"
41 #include "mem/slicc/symbols/StateMachine.hh"
42
43 Type::Type(string id, const Location& location,
44 const Map<string, string>& pairs,
45 StateMachine* machine_ptr)
46 : Symbol(id, location, pairs)
47 {
48 if (machine_ptr == NULL) {
49 m_c_id = id;
50 } else if (isExternal() || isPrimitive()) {
51 if (existPair("external_name")) {
52 m_c_id = lookupPair("external_name");
53 } else {
54 m_c_id = id;
55 }
56 } else {
57 m_c_id = machine_ptr->toString() + "_" + id; // Append with machine name
58 }
59
60 if(existPair("desc")){
61 m_desc = lookupPair("desc");
62 } else {
63 m_desc = "No description avaliable";
64 }
65
66 // check for interface that this Type implements
67 if(existPair("interface")) {
68 string interface = lookupPair("interface");
69 if(interface == "Message" || interface == "NetworkMessage") {
70 addPair("message", "yes");
71 }
72 if(interface == "NetworkMessage") {
73 addPair("networkmessage", "yes");
74 }
75 }
76
77 // FIXME - all of the following id comparisons are fragile hacks
78 if ((getIdent() == "CacheMemory") || (getIdent() == "NewCacheMemory") ||
79 (getIdent() == "TLCCacheMemory") || (getIdent() == "DNUCACacheMemory") ||
80 (getIdent() == "DNUCABankCacheMemory") || (getIdent() == "L2BankCacheMemory") ||
81 (getIdent() == "CompressedCacheMemory") || (getIdent() == "PrefetchCacheMemory")) {
82 addPair("cache", "yes");
83 }
84
85 if ((getIdent() == "TBETable") || (getIdent() == "DNUCATBETable") || (getIdent() == "DNUCAStopTable")) {
86 addPair("tbe", "yes");
87 }
88
89 if ((getIdent() == "NewTBETable")) {
90 addPair("newtbe", "yes");
91 }
92
93 if ((getIdent() == "TimerTable")) {
94 addPair("timer", "yes");
95 }
96
97 if ((getIdent() == "DirectoryMemory")) {
98 addPair("dir", "yes");
99 }
100
101 if ((getIdent() == "PersistentTable")) {
102 addPair("persistent", "yes");
103 }
104
105 if ((getIdent() == "Prefetcher")) {
106 addPair("prefetcher", "yes");
107 }
108
109 if ((getIdent() == "DNUCA_Movement")) {
110 addPair("mover", "yes");
111 }
112
113 if (id == "MachineType") {
114 m_isMachineType = true;
115 } else {
116 m_isMachineType = false;
117 }
118 }
119
120 // Return false on error
121 bool Type::dataMemberAdd(string id, Type* type_ptr, Map<string, string>& pairs,
122 string* init_code)
123 {
124 if (dataMemberExist(id)) {
125 return false; // Error
126 } else {
127 m_data_member_map.add(id, type_ptr);
128 m_data_member_ident_vec.insertAtBottom(id);
129 m_data_member_type_vec.insertAtBottom(type_ptr);
130 m_data_member_pairs_vec.insertAtBottom(pairs);
131 m_data_member_init_code_vec.insertAtBottom(init_code);
132 }
133
134 return true;
135 }
136
137 string Type::methodId(string name,
138 const Vector<Type*>& param_type_vec)
139 {
140 string paramStr = "";
141 for (int i = 0; i < param_type_vec.size(); i++) {
142 paramStr += "_"+param_type_vec[i]->cIdent();
143 }
144 return name+paramStr;
145 }
146
147 bool Type::methodAdd(string name,
148 Type* return_type_ptr,
149 const Vector<Type*>& param_type_vec)
150 {
151 string id = methodId(name, param_type_vec);
152 if (methodExist(id)) {
153 return false; // Error
154 } else {
155 m_method_return_type_map.add(id, return_type_ptr);
156 m_method_param_type_map.add(id, param_type_vec);
157 return true;
158 }
159 }
160
161 bool Type::enumAdd(string id, Map<string, string> pairs_map)
162 {
163 if (enumExist(id)) {
164 return false;
165 } else {
166 m_enum_map.add(id, true);
167 m_enum_vec.insertAtBottom(id);
168 m_enum_pairs.insertAtBottom(pairs_map);
169
170 // Add default
171 if (!existPair("default")) {
172 addPair("default", cIdent()+"_NUM");
173 }
174
175 return true;
176 }
177 }
178
179 void Type::writeCFiles(string path)
180 {
181 if (isExternal()) {
182 // Do nothing
183 } else if (isEnumeration()) {
184 printEnumH(path);
185 printEnumC(path);
186 } else { // User defined structs and messages
187 printTypeH(path);
188 printTypeC(path);
189 }
190 }
191
192 void Type::printTypeH(string path) const
193 {
194 ostringstream out;
195 int size = m_data_member_type_vec.size();
196 string type_name = cIdent(); // Identifier for the type in C
197
198 // Header
199 out << "/** \\file " << type_name << ".hh" << endl;
200 out << " * " << endl;
201 out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
202 out << " */" << endl;
203 out << endl;
204 out << "#ifndef " << type_name << "_H" << endl;
205 out << "#define " << type_name << "_H" << endl;
206 out << endl;
207
208 // Include all of the #includes needed
209 out << "#include \"mem/ruby/common/Global.hh\"" << endl;
210 out << "#include \"mem/gems_common/Allocator.hh\"" << endl;
211 for (int i=0; i < size; i++) {
212 Type* type = m_data_member_type_vec[i];
213 if (!type->isPrimitive()) {
214 out << "#include \"mem/protocol/" << type->cIdent() << ".hh" << "\"" << endl;
215 }
216 }
217 string interface = "";
218 if(existPair("interface")) {
219 interface = lookupPair("interface");
220 out << "#include \"mem/protocol/" << interface << ".hh\"" << endl;
221 }
222
223 // Class definition
224 out << "class " << type_name;
225
226 if(interface != "") {
227 out << " : public " << interface ;
228 }
229
230 out << " {" << endl;
231 out << "public:" << endl;
232
233 // ******** Default constructor ********
234
235 out << " " << type_name << "() " << endl;
236
237 // Call superclass constructor
238 if (interface != "") {
239 out << " : " << interface << "()" << endl;
240 }
241
242 out << " {" << endl;
243
244 if(!isGlobal()) {
245 for (int i=0; i < size; i++) {
246
247 Type* type_ptr = m_data_member_type_vec[i];
248 string id = m_data_member_ident_vec[i];
249 if (m_data_member_pairs_vec[i].exist("default")) {
250 // look for default value
251 string default_value = m_data_member_pairs_vec[i].lookup("default");
252 out << " m_" << id << " = " << default_value << "; // default for this field " << endl;
253 } else if (type_ptr->hasDefault()) {
254 // Look for the type default
255 string default_value = type_ptr->getDefault();
256 out << " m_" << id << " = " << default_value << "; // default value of " << type_ptr->cIdent() << endl;
257 } else {
258 out << " // m_" << id << " has no default" << endl;
259 }
260 }
261 } // end of if(!isGlobal())
262 out << " }" << endl;
263
264 // ******** Default destructor ********
265 out << " ";
266 out << "~" << type_name << "() { };" << endl;
267
268 // ******** Full init constructor ********
269 if(! isGlobal()) {
270 out << " " << type_name << "(";
271
272 for (int i=0; i < size; i++) {
273 if (i != 0) {
274 out << ", ";
275 }
276 Type* type = m_data_member_type_vec[i];
277 string id = m_data_member_ident_vec[i];
278 out << "const " << type->cIdent() << "& local_" << id;
279 }
280
281 if (isMessage()) {
282 out << ", const unsigned local_proc_id" << flush;
283 }
284
285 out << ")" << endl;
286
287 // Call superclass constructor
288 if (interface != "") {
289 out << " : " << interface << "()" << endl;
290 }
291
292 out << " {" << endl;
293 for (int i=0; i < size; i++) {
294 Type* type_ptr = m_data_member_type_vec[i];
295 string id = m_data_member_ident_vec[i];
296 out << " m_" << id << " = local_" << id << ";" << endl;
297 if (m_data_member_pairs_vec[i].exist("nextLineCallHack")) {
298 string next_line_value = m_data_member_pairs_vec[i].lookup("nextLineCallHack");
299 out << " m_" << id << next_line_value << ";" << endl;
300 }
301 }
302 if (isMessage()) {
303 out << " proc_id = local_proc_id;" << endl << flush;
304 }
305 out << " }" << endl;
306 } // end of if(!isGlobal())
307
308 // create a static factory method
309 if (interface != "") {
310 out << " static " << interface << "* create() {" << endl;
311 out << " return new " << type_name << "(); " << endl;
312 out << " }" << endl;
313 }
314
315 // bobba -
316 //******** Partial init constructor ********
317 //** Constructor needs only the first n-1 data members for init
318 //** HACK to create objects with partially specified data members
319 //** Need to get rid of this and use hierarchy instead
320 // if(! isGlobal()) {
321 // out << " " << type_name << "(";
322
323 // for (int i=0; i < size-1; i++) {
324 // if (i != 0) {
325 // out << ", ";
326 // }
327 // Type* type = m_data_member_type_vec[i];
328 // string id = m_data_member_ident_vec[i];
329 // out << "const " << type->cIdent() << "& local_" << id;
330 // }
331 // out << ")" << endl;
332
333 // // Call superclass constructor
334 // if (interface != "") {
335 // out << " : " << interface << "()" << endl;
336 // }
337
338 // out << " {" << endl;
339 // for (int i=0; i < size-1; i++) {
340 // Type* type_ptr = m_data_member_type_vec[i];
341 // string id = m_data_member_ident_vec[i];
342 // out << " m_" << id << " = local_" << id << ";" << endl;
343 // if (m_data_member_pairs_vec[i].exist("nextLineCallHack")) {
344 // string next_line_value = m_data_member_pairs_vec[i].lookup("nextLineCallHack");
345 // out << " m_" << id << next_line_value << ";" << endl;
346 // }
347
348 // }
349 // out << " }" << endl;
350 // } // end of if(!isGlobal())
351
352 // ******** Message member functions ********
353 // FIXME: those should be moved into slicc file, slicc should support more of
354 // the c++ class inheritance
355
356 if (isMessage()) {
357 out << " Message* clone() const { checkAllocator(); return s_allocator_ptr->allocate(*this); }" << endl;
358 out << " void destroy() { checkAllocator(); s_allocator_ptr->deallocate(this); }" << endl;
359 out << " static Allocator<" << type_name << ">* s_allocator_ptr;" << endl;
360 out << " static void checkAllocator() { if (s_allocator_ptr == NULL) { s_allocator_ptr = new Allocator<" << type_name << ">; }}" << endl;
361 }
362
363 if(!isGlobal()) {
364 // const Get methods for each field
365 out << " // Const accessors methods for each field" << endl;
366 for (int i=0; i < size; i++) {
367 Type* type_ptr = m_data_member_type_vec[i];
368 string type = type_ptr->cIdent();
369 string id = m_data_member_ident_vec[i];
370 out << "/** \\brief Const accessor method for " << id << " field." << endl;
371 out << " * \\return " << id << " field" << endl;
372 out << " */" << endl;
373 out << " const " << type << "& get" << id
374 << "() const { return m_" << id << "; }" << endl;
375 }
376
377 out << endl;
378
379 // Non-const Get methods for each field
380 out << " // Non const Accessors methods for each field" << endl;
381 for (int i=0; i < size; i++) {
382 Type* type_ptr = m_data_member_type_vec[i];
383 string type = type_ptr->cIdent();
384 string id = m_data_member_ident_vec[i];
385 out << "/** \\brief Non-const accessor method for " << id << " field." << endl;
386 out << " * \\return " << id << " field" << endl;
387 out << " */" << endl;
388 out << " " << type << "& get" << id
389 << "() { return m_" << id << "; }" << endl;
390 }
391
392 out << endl;
393
394 // Set methods for each field
395 out << " // Mutator methods for each field" << endl;
396 for (int i=0; i < size; i++) {
397 Type* type_ptr = m_data_member_type_vec[i];
398 string type = type_ptr->cIdent();
399 string id = m_data_member_ident_vec[i];
400 out << "/** \\brief Mutator method for " << id << " field */" << endl;
401 out << " void set" << id << "(const " << type << "& local_"
402 << id << ") { m_" << id << " = local_" << id << "; }" << endl;
403 }
404
405 out << endl;
406 } // end of if(!isGlobal())
407
408 out << " void print(ostream& out) const;" << endl;
409 out << "//private:" << endl;
410
411 // Data members for each field
412 for (int i=0; i < size; i++) {
413 if (!m_data_member_pairs_vec[i].exist("abstract")) {
414 out << " ";
415 // global structure
416 if(isGlobal()) out << "static const ";
417
418 Type* type = m_data_member_type_vec[i];
419 string id = m_data_member_ident_vec[i];
420 out << type->cIdent() << " m_" << id;
421
422 // init value
423 string* init_code = m_data_member_init_code_vec[i];
424 if(init_code) {
425 // only global structure can have init value here
426 assert(isGlobal());
427 out << " = " << *init_code << " ";
428 }
429 out << ";";
430 if (m_data_member_pairs_vec[i].exist("desc")) {
431 string desc = m_data_member_pairs_vec[i].lookup("desc");
432 out << " /**< " << desc << "*/";
433 }
434 out << endl;
435 }
436 }
437
438 if (isMessage()) {
439 out << " unsigned proc_id;" << endl << flush;
440 }
441
442 out << "};" << endl; // End class
443
444 out << "// Output operator declaration" << endl;
445 out << "ostream& operator<<(ostream& out, const " << type_name << "& obj);" << endl;
446 out << endl;
447 out << "// Output operator definition" << endl;
448 out << "extern inline" << endl;
449 out << "ostream& operator<<(ostream& out, const " << type_name << "& obj)" << endl;
450 out << "{" << endl;
451 out << " obj.print(out);" << endl;
452 out << " out << flush;" << endl;
453 out << " return out;" << endl;
454 out << "}" << endl;
455 out << endl;
456 out << "#endif // " << type_name << "_H" << endl;
457
458 // Write it out
459 conditionally_write_file(path + type_name + ".hh", out);
460 }
461
462 void Type::printTypeC(string path) const
463 {
464 ostringstream out;
465 int size = m_data_member_type_vec.size();
466 string type_name = cIdent(); // Identifier for the type in C
467
468 // Header
469 out << "/** \\file " << type_name << ".cc" << endl;
470 out << " * " << endl;
471 out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
472 out << " */" << endl;
473 out << endl;
474 out << "#include \"mem/protocol/" << type_name << ".hh\"" << endl;
475 out << endl;
476 if (isMessage()) {
477 out << "Allocator<" << type_name << ">* " << type_name << "::s_allocator_ptr = NULL;" << endl;
478 }
479 out << "/** \\brief Print the state of this object */" << endl;
480 out << "void " << type_name << "::print(ostream& out) const" << endl;
481 out << "{" << endl;
482 out << " out << \"[" << type_name << ": \";" << endl;
483
484 // For each field
485 for (int i=0; i < size; i++) {
486 string id = m_data_member_ident_vec[i];
487 out << " out << \"" << id << "=\" << m_" << id << " << \" \";" << endl;
488 }
489
490 if (isMessage()) {
491 out << " out << \"" << "Time" << "=\" << getTime()" << " << \" \";" << endl;
492 }
493
494 // Trailer
495 out << " out << \"]\";" << endl;
496 out << "}" << endl;
497
498 // Write it out
499 conditionally_write_file(path + type_name + ".cc", out);
500 }
501
502 void Type::printEnumH(string path) const
503 {
504 ostringstream out;
505 int size = m_enum_vec.size();
506 string type_name = cIdent(); // Identifier for the type in C
507 string type_desc = desc();
508
509 // Header
510 out << "/** \\file " << type_name << ".hh" << endl;
511 out << " * " << endl;
512 out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
513 out << " */" << endl;
514
515 out << "#ifndef " << type_name << "_H" << endl;
516 out << "#define " << type_name << "_H" << endl;
517 out << endl;
518 // Include all of the #includes needed
519 out << "#include \"mem/ruby/common/Global.hh\"" << endl;
520 out << endl;
521
522 // Class definition
523 out << "/** \\enum " << type_name << endl;
524 out << " * \\brief " << type_desc << endl;
525 out << " */" << endl;
526 out << "enum " << type_name << " {" << endl;
527
528 out << " " << type_name << "_FIRST," << endl;
529
530 // For each field
531 for(int i = 0; i < size; i++ ) {
532 string id = m_enum_vec[i];
533 string description;
534 if(m_enum_pairs[i].exist("desc")){
535 description = m_enum_pairs[i].lookup("desc");
536 } else {
537 description = "No description avaliable";
538 }
539 if (i == 0) {
540 out << " " << type_name << "_" << id << " = " << type_name << "_FIRST, /**< " << description << " */" << endl;
541 }
542 else {
543 out << " " << type_name << "_" << id << ", /**< " << description << " */" << endl;
544 }
545 }
546 out << " " << type_name << "_NUM" << endl;
547 out << "};" << endl;
548
549 // Code to convert from a string to the enumeration
550 out << type_name << " string_to_" << type_name << "(const string& str);" << endl;
551
552 // Code to convert state to a string
553 out << "string " << type_name << "_to_string(const " << type_name << "& obj);" << endl;
554
555 // Code to increment an enumeration type
556 out << type_name << " &operator++( " << type_name << " &e);" << endl;
557
558 // MachineType hack used to set the base component id for each Machine
559 if (m_isMachineType) {
560 out << "int " << type_name << "_base_level(const " << type_name << "& obj);" << endl;
561 out << "MachineType " << type_name << "_from_base_level(int);" << endl;
562 out << "int " << type_name << "_base_number(const " << type_name << "& obj);" << endl;
563 out << "int " << type_name << "_base_count(const " << type_name << "& obj);" << endl;
564 // out << "int " << type_name << "_chip_count(const " << type_name << "& obj, int chipID);" << endl;
565
566 for(int i = 0; i < size; i++ ) {
567 string id = m_enum_vec[i];
568 out << "#define MACHINETYPE_" << id << " 1" << endl;
569 }
570 cout << endl;
571 }
572
573 // Trailer
574 out << "ostream& operator<<(ostream& out, const " << type_name << "& obj);" << endl;
575 out << endl;
576 out << "#endif // " << type_name << "_H" << endl;
577
578 // Write the file
579 conditionally_write_file(path + type_name + ".hh", out);
580 }
581
582 void Type::printEnumC(string path) const
583 {
584 ostringstream out;
585 int size = m_enum_vec.size();
586 string type_name = cIdent(); // Identifier for the type in C
587
588 // Header
589 out << "/** \\file " << type_name << ".hh" << endl;
590 out << " * " << endl;
591 out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
592 out << " */" << endl;
593
594 out << endl;
595 out << "#include \"mem/protocol/" << type_name << ".hh\"" << endl;
596 if (m_isMachineType) {
597 out << "#include \"mem/protocol/ControllerFactory.hh\"" << endl;
598 for( int i = 0; i<size; i++ ) {
599 out << "#include \"mem/protocol/" << m_enum_vec[i] << "_Controller.hh\"" << endl;
600 }
601 out << endl;
602 }
603 out << endl;
604
605 // Code for output operator
606 out << "ostream& operator<<(ostream& out, const " << type_name << "& obj)" << endl;
607 out << "{" << endl;
608 out << " out << " << type_name << "_to_string(obj);" << endl;
609 out << " out << flush;" << endl;
610 out << " return out;" << endl;
611 out << "}" << endl;
612
613 // Code to convert state to a string
614 out << endl;
615 out << "string " << type_name << "_to_string(const " << type_name << "& obj)" << endl;
616 out << "{" << endl;
617 out << " switch(obj) {" << endl;
618
619 // For each field
620 for( int i = 0; i<size; i++ ) {
621 out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl;
622 out << " return \"" << m_enum_vec[i] << "\";" << endl;
623 }
624
625 // Trailer
626 out << " default:" << endl;
627 out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
628 out << " return \"\";" << endl;
629 out << " }" << endl;
630 out << "}" << endl;
631
632 // Code to convert from a string to the enumeration
633 out << endl;
634 out << type_name << " string_to_" << type_name << "(const string& str)" << endl;
635 out << "{" << endl;
636 out << " if (false) {" << endl;
637
638 // For each field
639 for( int i = 0; i<size; i++ ) {
640 out << " } else if (str == \"" << m_enum_vec[i] << "\") {" << endl;
641 out << " return " << type_name << "_" << m_enum_vec[i] << ";" << endl;
642 }
643
644 out << " } else {" << endl;
645 out << " WARN_EXPR(str);" << endl;
646 out << " ERROR_MSG(\"Invalid string conversion for type " << type_name << "\");" << endl;
647 out << " }" << endl;
648 out << "}" << endl;
649
650 // Code to increment an enumeration type
651 out << endl;
652 out << type_name << "& operator++( " << type_name << "& e) {" << endl;
653 out << " assert(e < " << type_name << "_NUM);" << endl;
654 out << " return e = " << type_name << "(e+1);" << endl;
655 out << "}" << endl;
656
657 // MachineType hack used to set the base level and number of components for each Machine
658 if (m_isMachineType) {
659 out << endl;
660 out << "/** \\brief returns the base vector index for each machine type to be used by NetDest " << endl;
661 out << " * " << endl;
662 out << " * \\return the base vector index for each machine type to be used by NetDest" << endl;
663 out << " * \\see NetDest.hh" << endl;
664 out << " */" << endl;
665 out << "int " << type_name << "_base_level(const " << type_name << "& obj)" << endl;
666 out << "{" << endl;
667 out << " switch(obj) {" << endl;
668
669 // For each field
670 Vector < string > MachineNames;
671 for( int i = 0; i<size; i++ ) {
672 out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl;
673 out << " return " << MachineNames.size() << ";" << endl;
674 MachineNames.insertAtBottom(m_enum_vec[i]);
675 }
676
677 // total num
678 out << " case " << type_name << "_NUM:" << endl;
679 out << " return " << MachineNames.size() << ";" << endl;
680
681 // Trailer
682 out << " default:" << endl;
683 out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
684 out << " return -1;" << endl;
685 out << " }" << endl;
686 out << "}" << endl;
687
688 out << "/** \\brief returns the machine type for each base vector index used by NetDest" << endl;
689 out << " * " << endl;
690 out << " * \\return the MachineTYpe" << endl;
691 out << " */" << endl;
692 out << "MachineType " << type_name << "_from_base_level(int type)" << endl;
693 out << "{" << endl;
694 out << " switch(type) {" << endl;
695
696 // For each field
697 MachineNames.clear();
698 for( int i = 0; i<size; i++ ) {
699 out << " case " << MachineNames.size() << ":" << endl;
700 out << " return " << type_name << "_" << m_enum_vec[i] << ";" << endl;
701 MachineNames.insertAtBottom(m_enum_vec[i]);
702 }
703
704 // Trailer
705 out << " default:" << endl;
706 out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
707 out << " return MachineType_NUM;" << endl;
708 out << " }" << endl;
709 out << "}" << endl;
710
711
712 out << endl;
713 out << "/** \\brief The return value indicates the number of components created" << endl;
714 out << " * before a particular machine's components" << endl;
715 out << " * " << endl;
716 out << " * \\return the base number of components for each machine" << endl;
717 out << " */" << endl;
718 out << "int " << type_name << "_base_number(const " << type_name << "& obj)" << endl;
719 out << "{" << endl;
720 out << " switch(obj) {" << endl;
721
722 // For each field
723 MachineNames.clear();
724 for( int i = 0; i<size; i++ ) {
725 out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl;
726 out << " return 0";
727 for ( int m = 0; m<MachineNames.size(); m++) {
728 out << "+ " << MachineNames[m] << "_Controller::getNumControllers()";
729 }
730 out << ";" << endl;
731 MachineNames.insertAtBottom(m_enum_vec[i]);
732 }
733
734 // total num
735 out << " case " << type_name << "_NUM:" << endl;
736 out << " return 0";
737 for ( int m = 0; m<MachineNames.size(); m++) {
738 out << "+ " << MachineNames[m] << "_Controller::getNumControllers()";
739 }
740 out << ";" << endl;
741
742 // Trailer
743 out << " default:" << endl;
744 out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
745 out << " return -1;" << endl;
746 out << " }" << endl;
747 out << "}" << endl;
748
749
750 out << endl;
751 out << "/** \\brief returns the total number of components for each machine" << endl;
752 out << " * \\return the total number of components for each machine" << endl;
753 out << " */" << endl;
754 out << "int " << type_name << "_base_count(const " << type_name << "& obj)" << endl;
755 out << "{" << endl;
756 out << " switch(obj) {" << endl;
757
758 // For each field
759 for( int i = 0; i<size; i++ ) {
760 out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl;
761 out << " return " << m_enum_vec[i] << "_Controller::getNumControllers();" << endl;
762 }
763
764 // total num
765 out << " case " << type_name << "_NUM:" << endl;
766 // Trailer
767 out << " default:" << endl;
768 out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
769 out << " return -1;" << endl;
770 out << " }" << endl;
771 out << "}" << endl;
772
773 out << endl;
774
775 }
776
777 // Write the file
778 conditionally_write_file(path + type_name + ".cc", out);
779 }