Made sure the constructor for insts use ExtMachInst rather than MachInst, since other...
[gem5.git] / src / sim / param.hh
1 /*
2 * Copyright (c) 2002-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Steve Reinhardt
29 */
30
31 #ifndef __SIM_PARAM_HH__
32 #define __SIM_PARAM_HH__
33
34 #include <iostream>
35 #include <list>
36 #include <string>
37 #include <vector>
38
39 #include "sim/startup.hh"
40
41 // forward decls
42 class IniFile;
43 class BaseParam;
44 class SimObject;
45
46 //
47 // The context of a parameter definition... usually a subclass of
48 // SimObjectBuilder (which derives from ParamContext), but abstracted
49 // here to support more global simulator control parameters as well.
50 //
51 class ParamContext : protected StartupCallback
52 {
53 private:
54
55 // static list of all ParamContext objects, built as a side effect
56 // of the ParamContext constructor
57 static std::list<ParamContext *> *ctxList;
58
59 protected:
60
61 // .ini file (database) for parameter lookup... initialized on call
62 // to parseParams()
63 IniFile *iniFilePtr;
64
65 // .ini file section for parameter lookup
66 const std::string iniSection;
67
68 typedef std::vector<BaseParam *> ParamList;
69
70 // list of parameters defined in this context
71 ParamList *paramList;
72
73 ParamList *getParamList() {
74 if (!paramList)
75 paramList = new ParamList;
76 return paramList;
77 }
78
79 public:
80
81 /// Initialization phases for ParamContext objects.
82 enum InitPhase {
83 NoAutoInit = -1, ///< Don't initialize at all... params
84 /// will be parsed later (used by
85 /// SimObjectBuilder, which parses
86 /// params in SimObject::create().
87 OutputInitPhase = 0, ///< Output stream initialization
88 TraceInitPhase = 1, ///< Trace context initialization:
89 /// depends on output streams, but
90 /// needs to come before others so we
91 /// can use tracing in other
92 /// ParamContext init code
93 StatsInitPhase = 2, ///< Stats output initialization
94 DefaultInitPhase = 3 ///< Everything else
95 };
96
97 /// Records the initialization phase for this ParamContext.
98 InitPhase initPhase;
99
100 /// Constructor.
101 /// @param _iniSection Name of .ini section corresponding to this context.
102 /// @param _initPhase Initialization phase (see InitPhase).
103 ParamContext(const std::string &_iniSection,
104 InitPhase _initPhase = DefaultInitPhase);
105
106 virtual ~ParamContext() {}
107
108 // add a parameter to the context... called from the parameter
109 // object's constructor (see BaseParam::BaseParam())
110 void addParam(BaseParam *);
111
112 // call parse() on all params in this context to convert string
113 // representations to parameter values
114 virtual void parseParams(IniFile &iniFile);
115
116 // Check parameter values for validity & consistency. Default
117 // implementation is no-op; derive subclass & override to add
118 // actual functionality here
119 virtual void checkParams();
120
121 // Clean up at end of execution: close file descriptors, etc.
122 // Default implementation is no-op; derive subclass & override to
123 // add actual functionality here
124 virtual void cleanup();
125
126 // dump parameter descriptions
127 void describeParams(std::ostream &);
128
129 // Display the parameters & values used
130 void showParams(std::ostream &);
131
132 // print context information for parameter error
133 virtual void printErrorProlog(std::ostream &);
134
135 // generate the name for this instance of this context (used as a
136 // prefix to create unique names in resolveSimObject()
137 virtual const std::string &getInstanceName() { return iniSection; }
138
139 // Parse all parameters registered with all ParamContext objects.
140 static void parseAllContexts(IniFile &iniFile);
141
142 // Check all parameters registered with all ParamContext objects.
143 // (calls checkParams() on each)
144 static void checkAllContexts();
145
146 // Print all parameter values on indicated ostream.
147 static void showAllContexts(std::ostream &os);
148
149 // Clean up all registered ParamContext objects. (calls cleanup()
150 // on each)
151 static void cleanupAllContexts();
152
153 // print descriptions of all parameters registered with all
154 // ParamContext objects
155 static void describeAllContexts(std::ostream &os);
156 };
157
158
159 //
160 // Base class for all parameter objects
161 //
162 class BaseParam
163 {
164 public:
165
166 ParamContext *context;
167 std::string name;
168 std::string description; // text description for help message
169 bool wasSet; // true if parameter was set by user
170 bool hasDefault; // true if parameter has default value
171
172 BaseParam(ParamContext *_context, const std::string &_name,
173 const std::string &_description, bool _hasDefault)
174 : context(_context), name(_name), description(_description),
175 wasSet(false), hasDefault(_hasDefault)
176 {
177 context->addParam(this);
178 }
179
180 virtual ~BaseParam() {}
181
182 // a parameter is valid only if its value was set by the user or
183 // it has a default value
184 bool isValid() const
185 {
186 return (wasSet || hasDefault);
187 }
188
189 // set value by parsing string
190 virtual void parse(const std::string &s) = 0;
191
192 // display value to stream
193 virtual void showValue(std::ostream &) const = 0;
194
195 // display type to stream
196 virtual void showType(std::ostream &) const = 0;
197
198 // signal parse or usage error
199 virtual void die(const std::string &err) const;
200 };
201
202 //
203 // Template classes to specialize parameters to specific types.
204 //
205 // Param<T> is for single-valued (scalar) parameters of type T.
206 // VectorParam<T> is for multi-valued (vector) parameters of type T.
207 // These are specified in the .ini file as a space-delimited list of
208 // arguments.
209 //
210 template <class T>
211 class Param : public BaseParam
212 {
213 protected:
214
215 T value;
216
217 public:
218
219 // Param with default value: set value to default
220 Param(ParamContext *context,
221 const std::string &name, const std::string &description, T dfltValue)
222 : BaseParam(context, name, description, true),
223 value(dfltValue)
224 {
225 }
226
227 // Param with no default value: leave value uninitialized
228 Param(ParamContext *context,
229 const std::string &name, const std::string &description)
230 : BaseParam(context, name, description, false)
231 {
232 }
233
234 virtual ~Param() {}
235
236 operator T&()
237 {
238 // if we attempt to reference an invalid parameter (i.e., one
239 // with no default value that was not set by the user), die.
240 if (!isValid())
241 die("not found");
242 return value;
243 }
244
245 // display value to stream
246 virtual void showValue(std::ostream &os) const;
247
248 // display type to stream
249 virtual void showType(std::ostream &) const;
250
251 // set value by parsing string
252 virtual void parse(const std::string &s);
253 };
254
255
256 //
257 // Template class for vector-valued parameters (lists)
258 //
259 template <class T>
260 class VectorParam : public BaseParam
261 {
262 protected:
263
264 std::vector<T> value;
265
266 public:
267
268 typedef typename std::vector<T>::size_type size_type;
269
270 // Param with default value: set value to default
271 VectorParam(ParamContext *context, const std::string &name,
272 const std::string &description,
273 const std::vector<T> &dfltValue)
274 : BaseParam(context, name, description, true),
275 value(dfltValue)
276 {
277 }
278
279 // Param with no default value: leave value uninitialized
280 VectorParam(ParamContext *context,
281 const std::string &name, const std::string &description)
282 : BaseParam(context, name, description, false)
283 {
284 }
285
286 virtual ~VectorParam() {}
287
288 // basic vector access methods
289 size_type size() const
290 {
291 if (!isValid())
292 die("not found");
293 return value.size();
294 }
295
296 const T &operator[](size_type n) const
297 {
298 if (!isValid())
299 die("not found");
300 return value[n];
301 }
302
303 // return reference to value vector
304 operator std::vector<T>&()
305 {
306 if (!isValid())
307 die("not found");
308 return value;
309 }
310
311 // display value to stream
312 virtual void showValue(std::ostream &os) const;
313
314 // display type to stream
315 virtual void showType(std::ostream &) const;
316
317 // set value by parsing string
318 virtual void parse(const std::string &s);
319 };
320
321 //
322 // Specialization of Param<int> and VectorParam<int> to handle
323 // enumerated types is done in two ways, using SimpleEnumParam and
324 // MappedEnumParam (and their vector counterparts,
325 // SimpleEnumVectorParam and MappedEnumVectorParam). SimpleEnumParam
326 // takes an array of strings and maps them to integers based on array
327 // index. MappedEnumParam takes an array of string-to-int mappings,
328 // allowing for mapping strings to non-contiguous integer values, or
329 // mapping multiple strings to the same integer value.
330 //
331 // Both SimpleEnumParam and MappedEnumParam are implemented using a
332 // single template class, EnumParam<Map>, which takes the type of the map
333 // as a parameter (const char * or EnumParamMap). Similarly,
334 // SimpleEnumVectorParam and MappedEnumVectorParam are both
335 // implemented using EnumVectorParam<Map>.
336 //
337 template <class Map>
338 class EnumParam : public Param<int>
339 {
340 const int num_values;
341 const Map *map;
342
343 public:
344
345 // Param with default value: set value to default
346 EnumParam(ParamContext *context,
347 const std::string &name, const std::string &description,
348 const Map *_map, int _num_values,
349 int dfltValue)
350 : Param<int>(context, name, description, dfltValue),
351 num_values(_num_values), map(_map)
352 {
353 }
354
355 // Param with no default value: leave value uninitialized
356 EnumParam(ParamContext *context,
357 const std::string &name, const std::string &description,
358 const Map *_map, int _num_values)
359 : Param<int>(context, name, description),
360 num_values(_num_values), map(_map)
361 {
362 }
363
364 virtual ~EnumParam() {}
365
366 // display value to stream
367 virtual void showValue(std::ostream &os) const;
368
369 // display type to stream
370 virtual void showType(std::ostream &) const;
371
372 // set value by parsing string
373 virtual void parse(const std::string &s);
374 };
375
376 //
377 // Vector counterpart to SimpleEnumParam
378 //
379 template <class Map>
380 class EnumVectorParam : public VectorParam<int>
381 {
382 const int num_values;
383 const Map *map;
384
385 public:
386
387 // Param with default value: set value to default
388 EnumVectorParam(ParamContext *context,
389 const std::string &name, const std::string &description,
390 const Map *_map, int _num_values,
391 std::vector<int> &dfltValue)
392 : VectorParam<int>(context, name, description, dfltValue),
393 num_values(_num_values), map(_map)
394 {
395 }
396
397 // Param with no default value: leave value uninitialized
398 EnumVectorParam(ParamContext *context,
399 const std::string &name, const std::string &description,
400 const Map *_map, int _num_values)
401 : VectorParam<int>(context, name, description),
402 num_values(_num_values), map(_map)
403 {
404 }
405
406 virtual ~EnumVectorParam() {}
407
408 // display value to stream
409 virtual void showValue(std::ostream &os) const;
410
411 // display type to stream
412 virtual void showType(std::ostream &) const;
413
414 // set value by parsing string
415 virtual void parse(const std::string &s);
416 };
417
418 // Specialize EnumParam for a particular enumeration type ENUM
419 // (automates casting to get value of enum type)
420
421 template <class ENUM>
422 class SimpleEnumParam : public EnumParam<const char *>
423 {
424 public:
425
426 SimpleEnumParam(ParamContext *context,
427 const std::string &name, const std::string &description,
428 const char **_map, int _num_values,
429 ENUM dfltValue)
430 : EnumParam<const char *>(context, name, description,
431 _map, _num_values, (int)dfltValue)
432 {
433 }
434
435 SimpleEnumParam(ParamContext *context,
436 const std::string &name, const std::string &description,
437 const char **_map, int _num_values)
438 : EnumParam<const char *>(context, name, description,
439 _map, _num_values)
440 {
441 }
442
443 operator ENUM() const
444 {
445 if (!isValid())
446 die("not found");
447 return (ENUM)value;
448 }
449 };
450
451
452 // Specialize EnumParam for a particular enumeration type ENUM
453 // (automates casting to get value of enum type)
454
455 template <class ENUM>
456 class SimpleEnumVectorParam : public EnumVectorParam<const char *>
457 {
458 public:
459
460 // skip default value constructor: too much pain to convert
461 // vector<ENUM> initializer to vector<int>
462
463
464 SimpleEnumVectorParam(ParamContext *context,
465 const std::string &name,
466 const std::string &description,
467 const char **_map, int _num_values)
468 : EnumVectorParam<const char *>(context, name, description,
469 _map, _num_values)
470 {
471 }
472
473 ENUM operator[](size_type n)
474 {
475 if (!isValid())
476 die("not found");
477 return (ENUM)value[n];
478 }
479 };
480
481
482 //
483 // Handle enums via string-to-int map (see comment above).
484 //
485
486 // An array of string-to-int mappings must be supplied using the
487 // following type.
488 typedef struct {
489 const char *name;
490 int value;
491 } EnumParamMap;
492
493 // Specialize EnumParam for a particular enumeration type ENUM
494 // (automates casting to get value of enum type)
495
496 template <class ENUM>
497 class MappedEnumParam : public EnumParam<EnumParamMap>
498 {
499 public:
500
501 MappedEnumParam(ParamContext *context,
502 const std::string &name, const std::string &description,
503 const EnumParamMap *_map, int _num_values,
504 ENUM dfltValue)
505 : EnumParam<EnumParamMap>(context, name, description,
506 _map, _num_values, (int)dfltValue)
507 {
508 }
509
510 MappedEnumParam(ParamContext *context,
511 const std::string &name, const std::string &description,
512 const EnumParamMap *_map, int _num_values)
513 : EnumParam<EnumParamMap>(context, name, description,
514 _map, _num_values)
515 {
516 }
517
518 operator ENUM()
519 {
520 if (!isValid())
521 die("not found");
522 return (ENUM)value[this->n];
523 }
524 };
525
526
527 // Specialize EnumParam for a particular enumeration type ENUM
528 // (automates casting to get value of enum type)
529
530 template <class ENUM>
531 class MappedEnumVectorParam : public EnumVectorParam<EnumParamMap>
532 {
533 public:
534
535 // skip default value constructor: too much pain to convert
536 // vector<ENUM> initializer to vector<int>
537
538
539 MappedEnumVectorParam(ParamContext *context,
540 const std::string &name,
541 const std::string &description,
542 const EnumParamMap *_map, int _num_values)
543 : EnumVectorParam<EnumParamMap>(context, name, description,
544 _map, _num_values)
545 {
546 }
547
548 ENUM operator[](size_type n)
549 {
550 if (!isValid())
551 die("not found");
552 return (ENUM)value[n];
553 }
554 };
555
556
557 //
558 // Parameters that point to other simulation objects (e.g. caches,
559 // busses, etc.) are handled by specializing SimObjectBaseParam to the
560 // specific subtype. The main purpose of SimObjectBaseParam is to
561 // provide a place to stick several helper functions common to all
562 // SimObject-derived parameters.
563 //
564 class SimObjectBaseParam : public BaseParam
565 {
566 public:
567
568 SimObjectBaseParam(ParamContext *context, const std::string &name,
569 const std::string &description, bool hasDefault)
570 : BaseParam(context, name, description, hasDefault)
571 {
572 }
573
574 virtual ~SimObjectBaseParam() {}
575
576 // helper function for SimObjectParam<T>::showValue()
577 void showValue(std::ostream &os, SimObject *obj) const;
578
579 // helper function for SimObjectParam<T>::parse()
580 void parse(const std::string &s, SimObject *&value);
581
582 // helper function for SimObjectParam<T>::parse()
583 void parse(const std::string &s, std::vector<SimObject *>&value_vec);
584 };
585
586
587 //
588 // Parameter to a specific type of SimObject. Note that T must be a
589 // pointer to a class derived from SimObject (e.g., <CPU *>).
590 //
591
592 template <class T> class SimObjectParam;
593
594 template <class T>
595 class SimObjectParam<T *> : public SimObjectBaseParam
596 {
597 protected:
598
599 T *value;
600
601 public:
602
603 // initialization w/o default
604 SimObjectParam(ParamContext *context,
605 const std::string &name, const std::string &description)
606 : SimObjectBaseParam(context, name, description, false)
607 {
608 }
609
610 // initialization wit=h default
611 SimObjectParam(ParamContext *context,
612 const std::string &name, const std::string &description,
613 T *dfltValue)
614 : SimObjectBaseParam(context, name, description, true),
615 value(dfltValue)
616 {
617 }
618
619 virtual ~SimObjectParam() {}
620
621 // convert to pointer
622 operator T*()
623 {
624 if (!isValid())
625 die("not found");
626 return value;
627 }
628
629 T *operator->() const
630 {
631 if (!isValid())
632 die("not found");
633 return value;
634 }
635
636 // display value to stream
637 virtual void showValue(std::ostream &os) const
638 {
639 SimObjectBaseParam::showValue(os, value);
640 }
641
642 // display type to stream: see REGISTER_SIM_OBJECT macro in
643 // sim_object.hh for declaration
644 virtual void showType(std::ostream &os) const;
645
646 // set value by parsing string
647 virtual void parse(const std::string &s)
648 {
649 SimObject *so_ptr;
650 // first parse to generic SimObject *
651 SimObjectBaseParam::parse(s, so_ptr);
652 // now dynamic_cast to specific derived type
653 value = dynamic_cast<T *>(so_ptr);
654 // check for failure of dynamic_cast
655 if (value == NULL && so_ptr != NULL)
656 die("not of appropriate type");
657 }
658 };
659
660
661 //
662 // Vector counterpart to SimObjectParam<T>
663 //
664
665 template <class T> class SimObjectVectorParam;
666
667 template <class T>
668 class SimObjectVectorParam<T *> : public SimObjectBaseParam
669 {
670 protected:
671
672 std::vector<T *> value;
673
674 public:
675
676 typedef typename std::vector<T *>::size_type size_type;
677
678 SimObjectVectorParam(ParamContext *context,
679 const std::string &name,
680 const std::string &description)
681 : SimObjectBaseParam(context, name, description, false)
682 {
683 }
684
685 SimObjectVectorParam(ParamContext *context,
686 const std::string &name,
687 const std::string &description,
688 std::vector<T *> dfltValue)
689 : SimObjectBaseParam(context, name, description, true),
690 value(dfltValue)
691 {
692 }
693
694 virtual ~SimObjectVectorParam() {}
695
696 // basic vector access methods
697 size_type size() const
698 {
699 if (!isValid())
700 die("not found");
701 return value.size();
702 }
703
704 T *&operator[](size_type n)
705 {
706 if (!isValid())
707 die("not found");
708 return value[n];
709 }
710
711 // return reference to value vector
712 operator std::vector<T *>&()
713 {
714 if (!isValid())
715 die("not found");
716 return value;
717 }
718
719 // display value to stream
720 virtual void showValue(std::ostream &os) const
721 {
722 for (int i = 0; i < value.size(); i++) {
723 if (i != 0)
724 os << " ";
725 SimObjectBaseParam::showValue(os, value[i]);
726 }
727 }
728
729 // display type to stream: see
730 virtual void showType(std::ostream &os) const;
731
732 // set value by parsing string
733 virtual void parse(const std::string &s)
734 {
735 std::vector<SimObject *> so_ptr_vec;
736 // first parse to generic SimObject * vector (from SimObjectBaseParam)
737 SimObjectBaseParam::parse(s, so_ptr_vec);
738
739 value.resize(so_ptr_vec.size());
740
741 for (int i = 0; i < so_ptr_vec.size(); ++i) {
742 // now dynamic_cast to specific derived type
743 value[i] = dynamic_cast<T *>(so_ptr_vec[i]);
744 // check for failure of dynamic_cast
745 if (value[i] == NULL && so_ptr_vec[i] != NULL)
746 die("not of appropriate type");
747 }
748 }
749 };
750
751 //
752 // Macro to define showType() methods for SimObjectParam &
753 // SimObjectVectorParam. Can't do this automatically as it requires a
754 // string name for the type, which you can't get from a template
755 // argument. For concrete derived SimObject types, this macro is
756 // automatically invoked by REGISTER_SIM_OBJECT() (see sim_object.hh).
757 //
758 #define DEFINE_SIM_OBJECT_CLASS_NAME(CLASS_NAME, OBJ_CLASS) \
759 template<> \
760 void \
761 SimObjectParam<OBJ_CLASS *>::showType(std::ostream &os) const \
762 { \
763 os << CLASS_NAME; \
764 } \
765 \
766 template<> \
767 void \
768 SimObjectVectorParam<OBJ_CLASS *>::showType(std::ostream &os) const \
769 { \
770 os << "vector of " << CLASS_NAME; \
771 }
772
773
774 //
775 // Declarations for low-level parsing & displaying functions. These
776 // are used internally, but should not be used directly by clients of
777 // the parameter mechanism, but are declared here so they can be
778 // shared with the serialization code (see sim/serialize.cc).
779 template <class T> bool parseParam(const std::string &str, T &data);
780 template <class T> void showParam(std::ostream &os, const T &data);
781
782 #endif // _SIM_PARAM_HH_