/* Copyright (C) 1998 T. 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 gpasm; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // // symbol.cc // // The file contains the code that controls all of the symbol // stuff for gpsim. Most of the work is handled by the C++ map // container class. // #include "symbol.h" #include #include #include #include #include #include #include "../config.h" #include "14bit-processors.h" #include "stimuli.h" #include "symbol_orb.h" #include "expr.h" #include "ValueCollections.h" #include "operator.h" #include "errors.h" #include "protocol.h" #include "cmd_gpsim.h" #include "sim_context.h" class IIndexedCollection; // // ***NOTE*** Ideally, I would like to use a the std container 'map' // to implement symbol tables. Unfortunately, iterators do not work // correctly with maps in libg++ (?version 1.27?) // Create a map for the symbol table. Note that the scope of the // symbol table is only within symbol.cc. The symbol table is // indexed by the symbol's name (a string). If a symbol is found // in the table then a pointer to it is returned. //map > st; //map >::iterator sti; Symbol_Table symbol_table; // There's only one instance of "the" symbol table #if defined(_WIN32) Symbol_Table &get_symbol_table(void) { return symbol_table; } #endif Symbol_Table::Symbol_Table() { reserve(500); } void Symbol_Table::add_ioport(PortRegister *_ioport) { ioport_symbol *is = new ioport_symbol(_ioport); if(!add(is)) { delete is; } } void Symbol_Table::add_stimulus_node(Stimulus_Node *s) { node_symbol *sym = findNodeSymbol(s->name()); // New paradigm is for the named stimulus objects // to add themselves and remove them selves. // Since there is a lot of code that adds a stimulus // object we will ignore them if the stimulus already // exists unless it is a different object with the // same name. if(sym == NULL) { node_symbol *ns = new node_symbol(s); if(!add(ns)) { delete ns; } } else if(sym->getNode() != s) { GetUserInterface().DisplayMessage("Warning: Attempt to add symbol %s that already exists\n", s->name().c_str()); } else { // use this code to capture calls to add_stimulus_node() that are not needed GetUserInterface().DisplayMessage("Warning: Attempt to add symbol object '%s' twice\n", s->name().c_str()); } } void Symbol_Table::add_stimulus(stimulus *s) { stimulus_symbol *sym = findStimulusSymbol(s->name()); // New paradigm is for the named stimulus objects // to add themselves and remove them selves. // Since there is a lot of code that adds a stimulus // object we will ignore them if the stimulus already // exists unless it is a different object with the // same name. if(sym == NULL) { stimulus_symbol *ss = new stimulus_symbol(s); if(!add(ss)) { delete ss; } } else if(sym->getStimulus() != s) { GetUserInterface().DisplayMessage("Warning: Attempt to add symbol %s that already exists\n", s->name().c_str()); } else { // use this code to capture calls to add_stimulus() that are not needed GetUserInterface().DisplayMessage("Warning: Attempt to add symbol object '%s' twice\n", s->name().c_str()); } } // This is an experiment to have the symbol table ordered // case insensitive unless their is a match for a case insensitive // compare, then a case sensitive compare is made. int SymbolCompare(const char *pLeft, const char *pRight) { #if 0 int iResult = stricmp(pLeft, pRight); if(iResult < 0) { return -1; } else if(iResult > 0) { return 1; } else { return strcmp(pLeft, pRight); } #else return strcmp(pLeft, pRight); #endif } //------------------------------------------------------------------------ // add(Value *) - add a symbol to the symbol table bool Symbol_Table::add(Value *s) { if(s) { if(s->name().empty()) { printf("Symbol_Table::add() attempt to add a symbol with no name: %s\n", s->toString().c_str()); } else { iterator it = lower_bound(begin( ), end( ), s, NameLessThan()); if (it != end() && (*it)->name() == s->name()) { GetUserInterface().DisplayMessage( "Symbol_Table::add(): Warning: failed to add symbol " "because a symbol by the name '%s' already exists, new object is type %s\n", s->name().c_str(), s->showType().c_str()); return false; } if(verbose) cout << "Adding '" << s->name() << "' to the symbol table\n"; insert(it, s); return true; } } return false; } //------------------------------------------------------------------------ // add_register register_symbol *Symbol_Table::add_register(Register *new_reg, const char *symbol_name) { // mask of zero lets the register_symbol calculate a default mask return add_register(new_reg, symbol_name, 0); } register_symbol * Symbol_Table::add_register(Register *new_reg, const char *symbol_name, unsigned int uMask) { if(!new_reg) return 0; if(symbol_name) { string sName(symbol_name); if((new_reg->name() == sName && find(new_reg->name()) ) || new_reg->baseName() == sName && find(new_reg->baseName())) { if(verbose) GetUserInterface().DisplayMessage( "Symbol_Table::add_register(): Warning: Not adding register symbol '%s'" " to symbol table\n because it already exists.\n", symbol_name); return 0; } } register_symbol *rs = new register_symbol(symbol_name, new_reg, uMask); add(rs); return rs; } void Symbol_Table::add_w(WREG *new_w) { if(!new_w) return; w_symbol *ws = new w_symbol((char *)0, new_w); add(ws); } void Symbol_Table::add_constant(const char *_name, int value, bool bClearable) { Integer *i = new Integer(value); i->new_name(_name); i->setClearableSymbol(bClearable); add(i); } void Symbol_Table::add_address(const char *new_name, int value) { address_symbol *as = new address_symbol(new_name,value); add(as); } void Symbol_Table::add_line_number(int address, const char *symbol_name) { line_number_symbol *lns = new line_number_symbol(symbol_name, address); add(lns); } void Symbol_Table::add_module(Module * m, const char *cPname) { module_symbol *ms = new module_symbol(m,cPname); if(!add(ms)) { delete ms; } } void Symbol_Table::remove_module(Module * m) { iterator sti = FindIt(m->name()); Value *sym; while( sti != end()) { sym = *sti; if((typeid(sym) == typeid(module_symbol)) && sym->name() == m->name()) { erase(sti); return; } sti++; } } Value *Symbol_Table::remove(string &s) { iterator it = FindIt(s); if(it != end() && (*it)->name() == s) { Value *pValue = *it; erase(it); return pValue; } return NULL; } void Symbol_Table::rename(const char *pOldName, const char *pNewName) { // First make sure the old and new names are both valid. if (pNewName && pOldName && *pOldName && *pNewName) { iterator it = FindIt(pOldName); if(it != end() && (*it)->name() == pOldName) { Value *pValue = *it; erase(it); pValue->new_name(pNewName); add(pValue); } } } Value * Symbol_Table::find(const char *str) { string s(str); return(find(s)); } Value * Symbol_Table::find(type_info const &symt, const char *str) { string s(str); iterator sti = FindIt(str); while( sti != end()) { Value *val = *sti; int iResult = val->name().compare(s); if(iResult == 0) { return val; } else if(iResult > 0) { // leave early for efficiency return NULL; } sti++; } return 0; } Register * Symbol_Table::findRegister(unsigned int address) { iterator sti = begin(); while( sti != end()) { register_symbol *pSymbol = dynamic_cast(*sti); if(pSymbol != 0) { Register * pReg = pSymbol->getReg(); if(pReg->address == address && pSymbol->getBitmask() == pReg->get_cpu()->register_mask()) // This function will find the first symbol that // uses the entire bit field of the register. return(pReg); } sti++; } return NULL; } register_symbol * Symbol_Table::findRegisterSymbol(const char *pName) { iterator sti; register_symbol *pRegSym; for( sti = FindIt(pName) ;sti != end(); sti++) { Value *val = *sti; if(val->name() == pName) { if((pRegSym = dynamic_cast(val)) != NULL) { return pRegSym; } } } return 0; } register_symbol * Symbol_Table::findRegisterSymbol(unsigned int uAddress) { iterator sti = begin(); ostringstream sDumbLabel; sDumbLabel << "R" << hex << uppercase << uAddress; while( sti != end()) { register_symbol *pRegSymbol = dynamic_cast(*sti); if(pRegSymbol != 0) { Register * pReg = pRegSymbol->getReg(); if (0 && pReg && pReg->get_cpu() == NULL) { // hmmm we need to fix this... It's possible for // modules (which are not processors) to have registers. //cout << " Null cpu for reg named:"<name()<get_cpu() != NULL); if(pReg && pReg->get_cpu() && pRegSymbol->getAddress() == uAddress && pRegSymbol->getBitmask() == pReg->get_cpu()->register_mask() && // This function will find the first symbol that // uses the entire bit field of the register. sDumbLabel.str() != pRegSymbol->name()) { return(pRegSymbol); } } sti++; } return NULL; } register_symbol * Symbol_Table::findRegisterSymbol(unsigned int uAddress, unsigned int uBitmask) { if(uBitmask == 0) { uBitmask = get_active_cpu()->register_mask(); } iterator sti = begin(); ostringstream sDumbLabel; sDumbLabel << "R" << hex << uppercase << uAddress; while( sti != end()) { register_symbol *pRegSymbol = dynamic_cast(*sti); if(pRegSymbol != 0) { if(pRegSymbol->getAddress() == uAddress && pRegSymbol->getBitmask() == uBitmask && sDumbLabel.str() != pRegSymbol->name()) { return(pRegSymbol); } } sti++; } return NULL; } Register * Symbol_Table::findRegister(const char *s) { iterator sti = FindIt(s); // .begin(); while( sti != end()) { Value *val = *sti; if(val && typeid(*val) == typeid(register_symbol)) { if(val->name() == s) { return ((register_symbol*)val)->getReg(); } } sti++; } return NULL; } const char * Symbol_Table::findProgramAddressLabel(unsigned int address) { iterator sti = begin(); while( sti != end()) { Value *val = *sti; address_symbol * pAddSym = dynamic_cast(val); if(pAddSym != NULL) { gint64 iSymbolAddress; pAddSym->get(iSymbolAddress); if(iSymbolAddress == address && strncmp(pAddSym->name().c_str(), "line_", sizeof("line_") - 1) != 0) { return pAddSym->name().c_str(); } } sti++; } return ""; } const char * Symbol_Table::findConstant(unsigned int uValue, unsigned int uReferencedFromAddress) { // regarding uReferencingAddress // see comment in the header. iterator sti = begin(); while( sti != end()) { Integer *val = dynamic_cast(*sti); if(val != NULL) { gint64 uSymValue; val->get(uSymValue); if(uValue == (unsigned int)uSymValue) return(val->name().c_str()); } sti++; } return NULL; } Integer * Symbol_Table::findInteger(const char *s) { return findSymbol(s, (Integer*)NULL); } Boolean * Symbol_Table::findBoolean(const char *s) { return findSymbol(s, (Boolean*)NULL); } module_symbol *Symbol_Table::findModuleSymbol(const char *s) { return findSymbol(s, (module_symbol*)NULL); } Module * Symbol_Table::findModule(const char *s) { module_symbol * pNodeSym = findModuleSymbol(s); if( pNodeSym != NULL) { return pNodeSym->get_module(); } return ((Module *)0); } node_symbol * Symbol_Table::findNodeSymbol(const char *s) { return findSymbol(s, (node_symbol*)NULL); } Stimulus_Node * Symbol_Table::findNode(const char *s) { node_symbol * pNodeSym = findNodeSymbol(s); if( pNodeSym != NULL) { return pNodeSym->getNode(); } return ((Stimulus_Node *)0); } String * Symbol_Table::findString(const char *s) { return findSymbol(s, (String *)NULL); } template _symbol_iterator_t Symbol_Table::beginSymbol(_symbol_iterator_t *pit, _symbol_t*psym) { iterator it; iterator itEnd = _Myt::end(); for(it = _Myt::begin(); itEnd != it; it++) { if(dynamic_cast<_symbol_t*>(*it) != NULL) { return _symbol_iterator_t(this, it); } } return _symbol_iterator_t(this, itEnd); } template _symbol_iterator_t Symbol_Table::endSymbol(_symbol_iterator_t *pit, _symbol_t*psym) { return _symbol_iterator_t(this,_Myt::end()); } Symbol_Table::node_symbol_iterator Symbol_Table::beginNodeSymbol() { return (node_symbol_iterator)beginSymbol((node_symbol_iterator*)0, (node_symbol*)0); } Symbol_Table::node_symbol_iterator Symbol_Table::endNodeSymbol() { return endSymbol((node_symbol_iterator*) 0, (node_symbol*)0); } stimulus_symbol * Symbol_Table::findStimulusSymbol(const char *s) { return findSymbol(s, (stimulus_symbol*)NULL); } stimulus * Symbol_Table::findStimulus(const char *s) { stimulus_symbol * pNodeSym = findStimulusSymbol(s); if( pNodeSym != NULL) { return pNodeSym->getStimulus(); } attribute_symbol *pSymbol = findAttributeSymbol(s); if(pSymbol != NULL) { Value *pValue; pSymbol->get(&pValue); return dynamic_cast(pValue); } return ((stimulus *)0); } attribute_symbol * Symbol_Table::findAttributeSymbol(const char *s) { return findSymbol(s, (attribute_symbol*)NULL); } Symbol_Table::stimulus_symbol_iterator Symbol_Table::beginStimulusSymbol() { return (stimulus_symbol_iterator)beginSymbol( (stimulus_symbol_iterator*)NULL, (stimulus_symbol*)NULL); } Symbol_Table::stimulus_symbol_iterator Symbol_Table::endStimulusSymbol() { return endSymbol((stimulus_symbol_iterator*) NULL, (stimulus_symbol*)NULL); } Symbol_Table::module_symbol_iterator Symbol_Table::beginModuleSymbol() { iterator it; iterator itEnd = _Myt::end(); for(it = _Myt::begin(); itEnd != it; it++) { if(dynamic_cast(*it) != NULL && dynamic_cast(*it) == NULL) { return module_symbol_iterator(this, it); } } return module_symbol_iterator(this, itEnd); // return (module_symbol_iterator)beginSymbol( // (module_symbol_iterator*)NULL, // (module_symbol*)NULL); } Symbol_Table::module_symbol_iterator Symbol_Table::endModuleSymbol() { return endSymbol((module_symbol_iterator*) NULL, (module_symbol*)NULL); } Symbol_Table::module_symbol_iterator Symbol_Table::module_symbol_iterator::operator++(int) { // postincrement Symbol_Table::iterator & it = (Symbol_Table::iterator&)*this; for(it++; it != m_pSymbolTable->end(); it++) { if(dynamic_cast(*it) != NULL && dynamic_cast(*it) == NULL) { return (*this); } } return (*this); } bool Symbol_Table::Exist(const char *s) { return this->FindIt(s) != end(); } void Symbol_Table::dump_one(string *s) { Value *val = find(*s); if(val) cout << val->name() << " = " << val->toString() << endl; } void Symbol_Table::dump_one(const char *str) { string s = string(str); dump_one(&s); } void Symbol_Table::dump_all(void) { cout << " Symbol Table\n"; bool bUserCanceled = false; CSimulationContext::GetContext()->SetUserCanceledFlag(&bUserCanceled); iterator sti = begin(); iterator last; while( sti != end()) { Value *val = *sti; if(val && (typeid(*val) != typeid(line_number_symbol))) { if(dynamic_cast(val) == NULL) { cout << val->name() << " = " ; } cout << val->toString() << endl; } last = sti; sti++; if(sti != end() && (*last)->name() == (*sti)->name()) { cout << "***************** Duplicate Found ***********" << endl; } if(bUserCanceled) { cout << endl << "Symbol dump canceled." << endl; break; } } CSimulationContext::GetContext()->SetUserCanceledFlag(NULL); } bool beginsWith(string &sTarget, string &sBeginsWith) { string sT; sT = sTarget.substr(0, sBeginsWith.size()); return sT == sBeginsWith; } void Symbol_Table::dump_filtered(const string & sSymbol) { string sBeginsWith; int nLastCharPos = sSymbol.size() - 1; if(nLastCharPos < 1) { dump_all(); return; } bool bUserCanceled = false; CSimulationContext::GetContext()->SetUserCanceledFlag(&bUserCanceled); if(sSymbol[nLastCharPos] == '.') { sBeginsWith = sSymbol.substr(0, nLastCharPos); } else { dump_one(sSymbol.c_str()); } Value KeyValue(sBeginsWith.c_str(), "key value"); iterator sti = lower_bound(begin( ), end( ), &KeyValue, NameLessThan()); iterator last; while( sti != end()) { Value *val = *sti; if(val && (typeid(*val) != typeid(line_number_symbol)) && beginsWith(val->name(), sBeginsWith)) { if(dynamic_cast(val) == NULL) { cout << val->name() << " = " ; } cout << val->toString() << endl; } last = sti; sti++; if(bUserCanceled) { cout << endl << "Symbol dump canceled." << endl; break; } } CSimulationContext::GetContext()->SetUserCanceledFlag(NULL); } void Symbol_Table::dump_type(type_info const &symt) { cout << DisplayType(symt); } string Symbol_Table::DisplayType(type_info const &symt) { ostringstream stream; // Now loop through the whole table and display all instances of the type of interest int first=1; // On the first encounter of one, display the title iterator sti = begin(); while( sti != end()) { Value *sym = *sti; if(sym && (typeid(*sym) == symt)) { if(first) { first = 0; stream << "Symbol Table for \"" << sym->showType() << "\"" << endl; } stream << sym->toString() << endl; } sti++; } if(first) stream << "No symbols found" << endl << ends; return string(stream.str()); } bool IsClearable(Value* value) { return value->isClearable(); } void Symbol_Table::clear() { iterator it; for(it = begin(); it != end();) { Value *value = *it; if(value && value->isClearable()) { delete value; erase(it); } else { ++it; } } // remove_if(begin(), end(), IsClearable); } void Symbol_Table::Initialize() { #if 0 PopulateWithCommandLineSymbols(); #endif } void Symbol_Table::Reinitialize() { clear(); } void Symbol_Table::clear_all() { iterator it; for(it = begin(); it != end(); ++it) delete *it; _Myt::clear(); } Value * Symbol_Table::find(const string &s) { const bool findDuplicates=false; iterator sti = FindIt(s); // .begin(); Value *ret=0; while( sti != end()) { Value *val = *sti; if(val && val->name() == s) { if(!findDuplicates) return val; if(!ret) { ret = val; } else cout << "Found duplicate:" << val->show()<name() == key->name()) { return it; } return end(); } //------------------------------------------------------------------------ // symbols // // symbol::symbol(const char *_name) { new_name(_name); } symbol::symbol(string &_name) { new_name(_name); } symbol::~symbol(void) { } Value* symbol::evaluate() { string msg("symbol '"); msg.append(this->name()); msg.append("' of type '"); msg.append(showType()); msg.append("' cannot not be evaluated in an expression"); throw Error( msg ); } //------------------------------------------------------------------------ string symbol::toString() { return showType(); } //------------------------------------------------------------------------ node_symbol::node_symbol(Stimulus_Node *_sn) : symbol(0) , stimulus_node(_sn) { if(stimulus_node) new_name(stimulus_node->name()); } string node_symbol::toString(void) { return string("node:")+name(); } // Count LSB that are off static int BitShiftCount( unsigned int uMask ) { unsigned int uBitMaskCount = 0; if( uMask != 0 ) { for ( int i = 0; i < 16; i++ ) { if( (uMask & (0x1 << i)) == 0 ) uBitMaskCount++; else break; } } return uBitMaskCount; } //------------------------------------------------------------------------ // register_symbol // register_symbol::register_symbol(const register_symbol & regsym) : symbol(regsym.name_str.c_str()), reg(regsym.reg) { m_uMask = regsym.m_uMask; m_uMaskShift = regsym.m_uMaskShift; if (name_str.empty()) { name_str = regsym.reg->name(); } } register_symbol::register_symbol(const char *_name, Register *_reg) : symbol(_name), reg(_reg) { setMask(reg); if (_name == NULL && reg != NULL) { name_str = _reg->name(); } } register_symbol::register_symbol(const char *_name, Register *_reg, unsigned int uMask) : symbol(_name), reg(_reg) { if(uMask == 0) { setMask(reg); } else { m_uMask = uMask; m_uMaskShift = BitShiftCount(m_uMask); } if (_name == NULL && reg != NULL) { name_str = _reg->name(); } } register_symbol::register_symbol(Register *_reg) : symbol(_reg->name()), reg(_reg) { setMask(reg); } void register_symbol::setMask(Register *pReg) { m_uMask = 0xff; for(unsigned int i = 1; i < pReg->register_size(); i++) { m_uMask <<= 8; m_uMask |= 0xff; } m_uMaskShift = BitShiftCount(m_uMask); } unsigned int register_symbol::getAddress() { return reg ? reg->address : 0xffffffff; } unsigned int register_symbol::getBitmask(void) { return m_uMask; } string ®ister_symbol::name() const { return (string &)name_str; } char *register_symbol::name(char *buf, int len) { return symbol::name(buf, len); } string register_symbol::toString() { if(reg) { char buff[256]; char bits[256]; reg->toBitStr(bits,sizeof(bits)); int iDigits = reg->register_size() * 2; // turn off masked bits in dwRead unsigned int uValue = reg->get_value() & m_uMask; uValue = uValue >> m_uMaskShift; if ( (unsigned int)((1<<(4*iDigits))-1) != m_uMask) snprintf(buff,sizeof(buff),"[0x%x] BITS 0x%0*x = 0x%0*x = 0b", reg->address, iDigits, m_uMask, iDigits, uValue); else snprintf(buff,sizeof(buff),"[0x%x] = 0x%0*x = 0b", reg->address, iDigits, uValue); return string(buff) + string(bits); } return string(""); } char *register_symbol::toString(char *return_str, int len) { if(!return_str) return 0; if(reg) return reg->toString(return_str,len); *return_str=0; return return_str; } char *register_symbol::toBitStr(char *return_str, int len) { if(!return_str) return 0; if(reg) return reg->toBitStr(return_str,len); *return_str=0; return return_str; } void register_symbol::get(int &i) { if(reg) { i = reg->get_value() & m_uMask; i >>= m_uMaskShift; } else i = 0; } void register_symbol::get(gint64 &i) { if(reg) { i = reg->get_value() & m_uMask; i >>= m_uMaskShift; } else i = 0; } void register_symbol::get(char *buffer, int buf_size) { if(buffer) { int v; get(v); snprintf(buffer,buf_size,"%d",v); } } void register_symbol::get(Packet &p) { if(reg) { int i; get(i); p.EncodeUInt32(i); } } void register_symbol::set(int new_value) { if(reg) reg->putRV(RegisterValue(SetMaskedValue(new_value),0)); } void register_symbol::set(Value *v) { if(reg && v) { int i; v->get(i); reg->putRV(RegisterValue(SetMaskedValue(i),0)); } } void register_symbol::set(const char *buffer, int buf_size) { if(buffer) { int i; int converted=0; // if a straight decimal conversion fails, then try hexadecimal. converted = sscanf(buffer, "0x%x", &i); if(!converted) converted = sscanf(buffer, "%d", &i); if(!converted) converted = sscanf(buffer, "$%x", &i); if(converted) set(i); } } unsigned int register_symbol::SetMaskedValue(unsigned int uValue) { Register *reg = getReg(); unsigned int uCurrentValue = reg ? reg->get_value() & m_uMask: 0; // turn off masked bits in uCurrentValue uCurrentValue &= ~m_uMask; // turn off non-mask bits in uValue uValue = uValue << m_uMaskShift; uValue &= m_uMask; // map the passed in value into the target uCurrentValue |= ((long)uValue); return uCurrentValue; } void register_symbol::set(Packet &p) { unsigned int i; if(p.DecodeUInt32(i)) { set((int)i); } } bool register_symbol::compare(ComparisonOperator *compOp, Value *rvalue) { if(!compOp || !rvalue) return false; gint64 i,r; get(i); rvalue->get(r); if(i < r) return compOp->less(); if(i > r) return compOp->greater(); return compOp->equal(); } void register_symbol::update(void) { reg->update(); } symbol *register_symbol::copy() { return new register_symbol(*this); } Register *register_symbol::getReg() { return reg; } Value* register_symbol::evaluate() { gint64 v; get(v); return new Integer(v); } int register_symbol::set_break(ObjectBreakTypes bt, ObjectActionTypes at, Expression *pExpr) { return get_bp().set_break(bt,at, reg,pExpr); } int register_symbol::clear_break() { cout << showType() << " objects breakpoints can only be cleared by 'clear #'\n where # is the breakpoint number\n"; return -1; } //------------------------------------------------------------------------ w_symbol::w_symbol(const char *_name, Register *_reg) : register_symbol(_name, _reg) { } string w_symbol::toString() { if(reg) { char buff[256]; char bits[256]; reg->toBitStr(bits,sizeof(bits)); snprintf(buff,sizeof(buff)," = 0x%02x = 0b", reg->get_value() & 0xff); return string(buff) + string(bits); } return string(""); } //------------------------------------------------------------------------ ioport_symbol::ioport_symbol(PortRegister *_ioport) : register_symbol(_ioport->name().c_str(), _ioport) { } //------------------------------------------------------------------------ address_symbol::address_symbol(const char *_name, unsigned int _val) : Integer(_val) { new_name(_name); } string address_symbol::toString() { char buf[256]; int i = (int)getVal(); snprintf(buf,sizeof(buf), " at address %d = 0x%X",i,i); return string(buf); } Value* address_symbol::evaluate() { return copy(); } int address_symbol::set_break(ObjectBreakTypes bt, ObjectActionTypes at, Expression *pExpr) { if (bt == gpsimObject::eBreakExecute) return get_bp().set_execution_break(get_active_cpu(),getVal(),pExpr); return -1; } line_number_symbol::line_number_symbol(const char *_name, unsigned int _val) : address_symbol(_name,_val) { if(!_name) { char buf[64]; snprintf(buf,sizeof(buf), "line_%04x",_val); new_name(buf); } } //------------------------------------------------------------------------ module_symbol::module_symbol(Module *_module, const char *_name) : symbol(_name), module(_module) { } Value *module_symbol::copy() { cout << "copying module symbol: " << name() << endl; return new module_symbol(module,name().c_str()); } void module_symbol::set(const char *cP,int len) { throw new Error("object cannot be assigned a value\n"); } void module_symbol::get(char *cP, int len) { if(cP) { *cP = 0; } } string module_symbol::description() { return module ? module->description() : string("no description"); } string module_symbol::toString() { return module ? module->toString() : name(); } //------------------------------------------------------------------------ attribute_symbol::attribute_symbol(Module *_module, Value *_attribute) : module_symbol(_module, 0) , attribute(_attribute) { if(module && attribute) { char buf[256]; snprintf(buf,sizeof(buf),"%s.%s",module->name().c_str(), attribute->name().c_str()); if(verbose) cout << "creating attribute symbol named: " << buf << endl; new_name(buf); attribute->new_name(buf); } } string attribute_symbol::toString() { if(attribute) return attribute->toString(); else return string("(null)"); } char *attribute_symbol::toString(char *return_str, int len) { if(attribute) return attribute->toString(return_str,len); else if(return_str) *return_str=0; return return_str; } char *attribute_symbol::toBitStr(char *return_str, int len) { if(attribute) return attribute->toBitStr(return_str,len); else if(return_str) *return_str=0; return return_str; } string attribute_symbol::description() { if(attribute) return attribute->description(); else return string("no attribute"); // <-- this has to be an error } Value *attribute_symbol::copy() { if (attribute) return attribute->copy(); return copy(); } Value* attribute_symbol::evaluate() { return copy(); } void attribute_symbol::set(double d) { if(attribute) attribute->set(d); } void attribute_symbol::set(gint64 i) { if(attribute) attribute->set(i); } void attribute_symbol::set(int i) { if(attribute) attribute->set(i); } void attribute_symbol::set(Value *v) { if(attribute) attribute->set(v); } void attribute_symbol::set(const char *cp,int len) { if(attribute) attribute->set(cp,len); } void attribute_symbol::set(Expression *e) { if(attribute) attribute->set(e); } void attribute_symbol::set(Packet &p) { if(attribute) attribute->set(p); } void attribute_symbol::get(int &i) { if(attribute) attribute->get(i); } void attribute_symbol::get(gint64 &i) { if(attribute) attribute->get(i); } void attribute_symbol::get(double &d) { if(attribute) attribute->get(d); } void attribute_symbol::get(char *c, int len) { if(attribute) attribute->get(c,len); } void attribute_symbol::get(Packet &p) { if(attribute) attribute->get(p); } void attribute_symbol::get(Value **v) { if(attribute && v) *v = attribute; } void attribute_symbol::set_xref(Value *v) { if(attribute) { attribute->set_xref(v); } Value::set_xref(v); } Value *attribute_symbol::get_xref() { if(attribute) return attribute->get_xref(); return Value::get_xref(); } //------------------------------------------------------------------------ stimulus_symbol::stimulus_symbol(stimulus *_s) : symbol(_s->name().c_str()), s(_s) { } //------------------------------------------------------------------------ string &stimulus_symbol::name() const { if(s) return s->name(); return Value::name(); } char *stimulus_symbol::name(char *pName, int len) { if(s) return s->name(pName, len); return Value::name(pName, len); } void stimulus_symbol::new_name(const char *pNewName) { if(s) return s->new_name(pNewName); return Value::new_name(pNewName); } void stimulus_symbol::new_name(string &sNewName) { if(s) return s->new_name(sNewName); return Value::new_name(sNewName); } string stimulus_symbol::toString() { if(s) return s->toString(); return name(); } //------------------------------------------------------------------------ val_symbol::val_symbol(gpsimValue *v) : symbol((char*)0) { if(!v) throw string(" val_symbol"); val = v; } string val_symbol::toString() { return val->toString(); } void val_symbol::get(int &i) { if (val) i = val->get_value(); else i = 0; } void val_symbol::get(gint64 &i) { if (val) i = val->get_value(); else i = 0; } void val_symbol::set(int new_value) { if(val) val->put_value(new_value); } void val_symbol::set(gint64 new_value) { if(val) val->put_value((int)new_value); } string &val_symbol::name(void) const { return val->name(); } symbol *val_symbol::copy() { return new val_symbol(val); } bool val_symbol::compare(ComparisonOperator *compOp, Value *rvalue) { if(!compOp || !rvalue) return false; gint64 i,r; get(i); rvalue->get(r); if(i < r) return compOp->less(); if(i > r) return compOp->greater(); return compOp->equal(); }