/* Copyright (C) 1998-2004 Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __VALUE_H__ #define __VALUE_H__ #include "gpsim_object.h" #include class Processor; class Module; #include "xref.h" class Expression; class ComparisonOperator; class Packet; //------------------------------------------------------------------------ // /// Value - the base class that supports types /// /// Everything that can hold a value is derived from the Value class. /// The primary purpose of this is to provide external objects (like /// the gui) an abstract way of getting the value of diverse things /// like registers, program counters, cycle counters, etc. /// /// In addition, expressions of Values can be created and operated /// on. class Value : public gpsimObject { public: Value(); Value(const char *name, const char *desc); virtual ~Value(); virtual unsigned int get_leftVal() {return 0;} virtual unsigned int get_rightVal() {return 0;} /// Value 'set' methods provide a mechanism for casting values to the /// the type of this value. If the type cast is not supported in a /// derived class, an Error will be thrown. virtual void set(const char *cP,int len=0); virtual void set(double); virtual void set(gint64); virtual void set(int); virtual void set(bool); virtual void set(Value *); virtual void set(Expression *); virtual void set(Packet &); /// Value 'get' methods provide a mechanism of casting Value objects /// to other value types. If the type cast is not supported in a /// derived class, an Error will be thrown. virtual void get(bool &b); virtual void get(int &); virtual void get(guint64 &); virtual void get(gint64 &); virtual void get(double &); virtual void get(char *, int len); virtual void get(Packet &); inline operator gint64() { gint64 i; get(i); return i; } inline operator int() { gint64 i; get(i); return (int)i; } inline operator unsigned int() { gint64 i; get(i); return (unsigned int)i; } inline Value & operator =(int i) { set(i); return *this; } inline Value & operator =(unsigned int i) { set((int)i); return *this; } /// compare - this method will compare another object to this /// object. It takes a pointer to a ComparisonOperator as its /// input. Of the object's are mismatched for the particular /// operator, a 'Type Mismatch' Error will be thown. virtual bool compare(ComparisonOperator *compOp, Value *rvalue); /// copy - return an object that is identical to this one. virtual Value *copy(); /// xrefs - a cross reference allows a Value to notify another /// Value when it is changed. virtual void set_xref(Value *); virtual Value *get_xref(); virtual void setClearableSymbol(bool bClear); virtual bool isClearable(); // Some Value types that are used for symbol classes // contain a gpsimValue type that have update listeners. virtual void update(void) {} virtual Value* evaluate() { return copy(); } private: Value *xref; protected: bool m_bClearableSymbol; }; //======================================================================== // /// gpsimValue is a Value object that is unique to the simulator. /// All value objects of the behavioral models are derived from gpsimValue. /// A gpsimValue object 'belongs to' a Module. class gpsimValue : public gpsimObject { public: gpsimValue(void); gpsimValue(Module *); virtual ~gpsimValue(); /// Access functions /// \deprecated Use SimulatedGet() virtual unsigned int get(void) { return get_value(); } /// \deprecated Use SimulatedSet() virtual void put(unsigned int new_value) { put_value(new_value); } /// put_value is the same as put(), but some extra stuff like /// interfacing to the gui is done. (It's more efficient than /// burdening the run time performance with (unnecessary) gui /// calls.) /// /// \deprecated Use ShuntedSet() where appropriate. If ShuntedSet() /// does not meet the procise needs consider defining a new /// pair of access functions. virtual void put_value(unsigned int new_value) = 0; /// A variation of get(). (for register values, get_value returns /// just the value whereas get() returns the value and does other /// register specific things like tracing. virtual unsigned int get_value(void) = 0; /// SimulatedGet() invokes the full simulation of getting a /// a value from a simulated object. virtual unsigned int SimulatedGet(void) { return ShuntedGet(); } /// SimulatedSet() invokes the full simulation of setting a /// a value of a simulated object. virtual void SimulatedSet(unsigned int new_value) { ShuntedSet(new_value); } /// ShuntedGet() bypasses all simulated effects of a SimulatedSet(). /// \return Returns an identical value as a SimulatedGet() virtual unsigned int ShuntedGet(void) { // for now use old API return get_value(); } /// ShuntedSet() bypasses all simulated effects of a SimulatedSet(). virtual void ShuntedSet(unsigned int new_value){ // for now use old API put_value(new_value); } virtual void set_module(Module *new_cpu) { cpu = new_cpu; } Module *get_module(void) { return cpu; } virtual void set_cpu(Processor *new_cpu); Processor *get_cpu(void) const; // When the value changes, then update() is called // to update all things that are watching this value. virtual void update(void); virtual void add_xref(void *xref); virtual void remove_xref(void *xref); XrefObject xref(void) { return _xref; } virtual string toString(); protected: // If we are linking with a gui, then here are a // few declarations that are used to send data to it. // This is essentially a singly-linked list of pointers // to structures. The structures provide information // such as where the data is located, the type of window // it's in, and also the way in which the data is presented XrefObject _xref; // A pointer to the module that owns this value. Module *cpu; }; /***************************************************************** * Now we introduce classes for the basic built-in data types. * These classes are created by extending the Value class. For * convenience, they all must instantiate a getVal() method that * returns valueof the object in question as a simple value of * the base data type. For example, invoking getVal() on a * Boolean oject must return a simple 'bool' value. */ /*****************************************************************/ class Boolean : public Value { public: Boolean(bool newValue); Boolean(const char *_name, bool newValue, const char *desc=0); static bool Parse(const char *pValue, bool &bValue); static Boolean * NewObject(const char *_name, const char *pValue, const char *desc); virtual ~Boolean(); string toString(); string toString(char* format); static string toString(bool value); static string toString(char* format, bool value); virtual void get(bool &b); virtual void get(int &i); virtual void get(char *, int len); virtual void get(Packet &); virtual void set(bool); virtual void set(Value *); virtual void set(const char *cP,int len=0); virtual void set(Packet &); bool getVal() { return value; } static Boolean* typeCheck(Value* val, string valDesc); virtual bool compare(ComparisonOperator *compOp, Value *rvalue); virtual Value *copy(); /// copy the object value to a user char array virtual char *toString(char *, int len); virtual char *toBitStr(char *, int len); inline operator bool() { bool bValue; get(bValue); return bValue; } inline Boolean &operator = (bool bValue) { set(bValue); return *this; } private: bool value; }; inline bool operator!=(Boolean &LValue, Boolean &RValue) { return (bool)LValue != (bool)RValue; } //------------------------------------------------------------------------ /// Integer - built in gpsim type for a 64-bit integer. class Integer : public Value { public: Integer(const Integer &new_value); Integer(gint64 new_value); Integer(const char *_name, gint64 new_value, const char *desc=0); static bool Parse(const char *pValue, gint64 &iValue); static Integer * NewObject(const char *_name, const char *pValue, const char *desc); virtual ~Integer(); virtual string toString(); string toString(char* format); static string toString(gint64 value); static string toString(char* format, gint64 value); virtual void get(gint64 &i); virtual void get(double &d); virtual void get(char *, int len); virtual void get(Packet &); virtual void set(gint64 v); virtual void set(int); virtual void set(double d); virtual void set(Value *); virtual void set(const char *cP,int len=0); virtual void set(Packet &); static void setDefaultBitmask(gint64 bitmask); inline void setBitmask(gint64 bitmask) { this->bitmask = bitmask; } inline gint64 getBitmask() { return bitmask; } gint64 getVal() { return value; } virtual int set_break(ObjectBreakTypes bt=eBreakAny, ObjectActionTypes at=eActionHalt, Expression *expr=0); virtual Value *copy(); /// copy the object value to a user char array virtual char *toString(char *, int len); virtual char *toBitStr(char *, int len); static Integer* typeCheck(Value* val, string valDesc); static Integer* assertValid(Value* val, string valDesc, gint64 valMin); static Integer* assertValid(Value* val, string valDesc, gint64 valMin, gint64 valMax); virtual bool compare(ComparisonOperator *compOp, Value *rvalue); inline operator gint64() { gint64 i; get(i); return i; } inline operator guint64() { gint64 i; get(i); return (guint64)i; } inline operator bool() { gint64 i; get(i); return i != 0; } inline operator int() { gint64 i; get(i); return (int)i; } inline operator unsigned int() { gint64 i; get(i); return (unsigned int)i; } inline Integer & operator =(const Integer &i) { Integer & ii = (Integer &)i; gint64 iNew = (gint64)ii; set(iNew); bitmask = i.bitmask; return *this; } inline Integer & operator =(int i) { set(i); return *this; } inline Integer & operator =(unsigned int i) { set((int)i); return *this; } inline Integer & operator &=(int iValue) { gint64 i; get(i); set((int)i & iValue); return *this; } inline Integer & operator |=(int iValue) { gint64 i; get(i); set((int)i | iValue); return *this; } inline Integer & operator +=(int iValue) { gint64 i; get(i); set((int)i + iValue); return *this; } inline Integer & operator ++(int) { gint64 i; get(i); set((int)i + 1); return *this; } inline Integer & operator --(int) { gint64 i; get(i); set((int)i - 1); return *this; } inline Integer & operator <<(int iShift) { gint64 i; get(i); set(i << iShift); return *this; } inline bool operator !() { gint64 i; get(i); return i == 0; } private: gint64 value; // Used for display purposes gint64 bitmask; static gint64 def_bitmask; }; inline bool operator!=(Integer &iLValue, Integer &iRValue) { return (gint64)iLValue != (gint64)iRValue; } //------------------------------------------------------------------------ /// Float - built in gpsim type for a 'double' class Float : public Value { public: Float(double newValue = 0.0); Float(const char *_name, double newValue, const char *desc=0); static bool Parse(const char *pValue, double &fValue); static Float * NewObject(const char *_name, const char *pValue, const char *desc); virtual ~Float(); virtual string toString(); string toString(char* format); static string toString(double value); static string toString(char* format, double value); virtual void get(gint64 &i); virtual void get(double &d); virtual void get(char *, int len); virtual void get(Packet &); virtual void set(gint64 v); virtual void set(double d); virtual void set(Value *); virtual void set(const char *cP,int len=0); virtual void set(Packet &); double getVal() { return value; } virtual Value *copy(); /// copy the object value to a user char array virtual char *toString(char *, int len); static Float* typeCheck(Value* val, string valDesc); virtual bool compare(ComparisonOperator *compOp, Value *rvalue); inline operator double() { double d; get(d); return d; } inline Float & operator = (double d) { set((double)d); return *this; } inline Float & operator = (int d) { set((double)d); return *this; } inline Float & operator += (Float &d) { set((double)*this + (double)d ); return *this; } inline Float & operator *= (Float &d) { set((double)*this * (double)d ); return *this; } inline Float & operator *= (double d) { set((double)*this * d ); return *this; } private: double value; }; inline bool operator!=(Float &iLValue, Float &iRValue) { return (double)iLValue != (double)iRValue; } /*****************************************************************/ class String : public Value { public: String(const char *newValue); String(const char *_name, const char *newValue, const char *desc=0); virtual ~String(); virtual string toString(); const char *getVal(); virtual void set(Value *); virtual void set(const char *cP,int len=0); virtual void set(Packet &); virtual void get(char *, int len); virtual void get(Packet &); virtual Value *copy(); /// copy the object value to a user char array virtual char *toString(char *, int len); inline operator const char *() { return getVal(); } private: char *value; }; inline bool operator!=(String &LValue, String &RValue) { return strcmp((const char *)LValue, (const char *)RValue) != 0; } /*****************************************************************/ class AbstractRange : public Value { public: AbstractRange(unsigned int leftVal, unsigned int rightVal); virtual ~AbstractRange(); virtual string toString(); string toString(char* format); virtual unsigned int get_leftVal(); virtual unsigned int get_rightVal(); virtual void set(Value *); virtual Value *copy(); /// copy the object value to a user char array virtual char *toString(char *, int len); static AbstractRange* typeCheck(Value* val, string valDesc); virtual bool compare(ComparisonOperator *compOp, Value *rvalue); private: unsigned int left; unsigned int right; }; char * TrimWhiteSpaceFromString(char * pBuffer); char * UnquoteString(char * pBuffer); string &toupper(string & sStr); #endif // __VALUE_H__