diff options
Diffstat (limited to 'src/usr/hwpf/ifcompiler')
-rwxr-xr-x | src/usr/hwpf/ifcompiler/initCompiler.C | 354 | ||||
-rwxr-xr-x | src/usr/hwpf/ifcompiler/initCompiler.H | 128 | ||||
-rwxr-xr-x | src/usr/hwpf/ifcompiler/initCompiler.lex | 681 | ||||
-rwxr-xr-x | src/usr/hwpf/ifcompiler/initCompiler.y | 366 | ||||
-rwxr-xr-x | src/usr/hwpf/ifcompiler/initRpn.C | 1396 | ||||
-rwxr-xr-x | src/usr/hwpf/ifcompiler/initRpn.H | 329 | ||||
-rwxr-xr-x | src/usr/hwpf/ifcompiler/initScom.C | 1778 | ||||
-rwxr-xr-x | src/usr/hwpf/ifcompiler/initScom.H | 333 | ||||
-rwxr-xr-x | src/usr/hwpf/ifcompiler/initSymbols.C | 1160 | ||||
-rwxr-xr-x | src/usr/hwpf/ifcompiler/initSymbols.H | 295 |
10 files changed, 0 insertions, 6820 deletions
diff --git a/src/usr/hwpf/ifcompiler/initCompiler.C b/src/usr/hwpf/ifcompiler/initCompiler.C deleted file mode 100755 index 0ea6dfb7d..000000000 --- a/src/usr/hwpf/ifcompiler/initCompiler.C +++ /dev/null @@ -1,354 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/hwpf/ifcompiler/initCompiler.C $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2011,2014 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -// Change Log ************************************************************************************* -// -// Flag Track Userid Date Description -// ----- -------- -------- -------- ------------------------------------------------------------- -// D754106 dgilbert 06/14/10 Create -// dg002 SW039868 dgilbert 10/15/10 Add support to filter unneeded inits by EC -// dg003 D779902 dgilbert 12/08/10 Add ability to specify ouput if file -// andrewg 05/24/11 Port over for VPL/PgP -// andrewg 09/19/11 Updates based on review -// mjjones 11/17/11 Output attribute listing -// camvanng 04/12/12 Ability to specify search paths for include files -// camvanng 06/27/12 Improve error and debug tracing -// End Change Log ********************************************************************************* -// $Id: initCompiler.C,v 1.4 2014/06/27 19:59:45 thi Exp $ -/** - * @file initCompiler.C - * @brief Compile an initfile into bytecode. - */ -#include <stdint.h> -#include <stdio.h> -#include <string> -#include <sstream> -#include <iostream> -#include <fstream> -#include <iomanip> -#include <map> -#include <stdexcept> -#include <initCompiler.H> -#include <initRpn.H> -#include <initSymbols.H> -#include <initScom.H> -//#include <initSpy.H> - -using namespace init; -using namespace std; - -//Globals - -int yyline = 1; -init::ScomList * yyscomlist = NULL; -vector<string> yyincludepath; //path to search for include files -vector<string> yyfname; //list of initfile/define files being parsed -string dbg_fname; //file to dump dbg stringstream - -ostringstream init::dbg; -ostringstream init::erros; -ostringstream init::stats; // TODO move to Parser - -// Main -int main(int narg, char ** argv) -{ - int rc = 0; - -#if 0 - yyin = fopen("sample.initfile","r"); - if(!yyin) - { - std::cerr << "\nERROR: Failed to open sample.initfile! " << std::endl; - exit(-1); - } - yyparse(); - fclose(yyin); -#endif - - try - { - // Parser: - // - Parse args - // - Set up source location and source type - // - Load & parse Symbols & Spy/Array tables - // - Load & parse the initfile (if there is one) - // - Parser parsed(narg,argv); - - string initfile = parsed.source_fn(); - uint32_t type = parsed.get_source_type(); - - BINSEQ bin_seq; - bin_seq.reserve(0x38000); - - if(type == Parser::IF_TYPE) // input is binary *.if file - build listing from it. - { - - //for(SPY_LIST::iterator i = yyspylist->begin(); i != yyspylist->end(); ++i) - //{ - // cout << (*i)->listing() << endl; - //} - - ifstream ifs(initfile.c_str(), ios_base::in | ios_base::binary); - if(!ifs) - { - std::ostringstream msg; - msg << "initCompiler.C: main: Could not open " << initfile << endl; - throw invalid_argument(msg.str()); - } - while(1) - { - int ch = ifs.get(); - if (!(ifs.good())) break; - bin_seq.push_back(ch); - } - ifs.close(); - - yyscomlist->listing(bin_seq, cout); - - erros << yyscomlist->get_symbols()->not_found_listing(); - - } - else // normal initfile processing - { - // Already parsed - yyscomlist->compile(bin_seq); - - - std::cerr << "Compiled size = " << std::dec << bin_seq.size() << endl; - - // if there are missing symbols, SpyList::listing() will add duplicates - // So get the listing now - erros << yyscomlist->get_symbols()->not_found_listing(); - - string if_fn = parsed.binseq_fn(); - ofstream ofs(if_fn.c_str(), ios_base::out | ios_base::binary); - if(!ofs) - { - std::ostringstream msg; - msg << "initCompiler.C: main: Could not open " << if_fn << endl; - throw invalid_argument(msg.str()); - } - else - { - for(BINSEQ::const_iterator bli = bin_seq.begin(); bli != bin_seq.end(); ++bli) - ofs.put((char)(*bli)); - - ofs.close(); - } - //cout << dbg << std::endl; - printf("Generate Listing\n"); - yyscomlist->listing(bin_seq, parsed.listing_ostream()); - yyscomlist->attr_listing(bin_seq, parsed.attr_listing_ostream()); - - // open if file and read in to new SpyList - - printf("Generate Stats\n"); - stats << "*********************************************************\n"; - - cerr << stats.str() << endl; // TODO -> cout - - } - - if (parsed.debug_mode()) - { - printf("Generate Debug\n"); - capture_dbg(dbg_fname); - } - //if(parsed.debug_mode()) cout << dbg.str() << endl; - } - catch(exception & e) - { - //Dump dbg stringstream to file - capture_dbg(dbg_fname); - - //Dump current stats - stats << "*********************************************************\n"; - cerr << stats.str() << endl; - - cerr << "ERROR! exception caught: " << e.what() << endl; - rc = 2; - } - - if(erros.str().size()) - { - rc = 1; - cerr << erros.str() << endl; - } - return rc; -} - -// ------------------------------------------------------------------------------------------------ -// Parser: -// Check the args and build the symbol table -// ----------------------------------------------------------------------------------------------- - -Parser::Parser(int narg, char ** argv) -: iv_type(0), iv_scomlist(NULL), iv_dbg(false), iv_ec(0xFFFFFFFF) //dg002c -{ - set<string> header_files; - iv_prog_name = argv[0]; - - stats << iv_prog_name << endl; - --narg; ++argv; - - string type; - - pair<string,string> compare; - - for(int i = 0; i < narg; ++i) - { - string arg(argv[i]); - if(arg.compare(0,5,"-init") == 0) iv_source_path = argv[++i]; - else if (arg.compare(0,3,"-kw") == 0 || - arg.compare(0,4,"-spy") == 0 || - arg.compare(0,5,"-attr") == 0 || - arg.compare(0,6,"-array") == 0 ) header_files.insert(string(argv[++i])); - else if (arg.compare(0,7,"-outdir") == 0) iv_outdir = argv[++i]; - else if (arg.compare(0,2,"-o") == 0) iv_outfile = argv[++i]; //dg003a - else if (arg.compare(0,3,"-if") == 0) iv_source_path = argv[++i]; - else if (arg.compare(0,3,"-ec") == 0) iv_ec = strtoul(argv[++i],NULL,16); //dg002a - else if (arg.compare(0,2, "-I") == 0) yyincludepath.push_back(argv[++i]); - else if (arg.compare(0,9,"--compare") == 0) - { - compare.first = argv[++i]; - compare.second = argv[++i]; - } - else if (arg.compare(0,7,"--debug") == 0) iv_dbg = true; - - } - if(iv_source_path.size() == 0) - { - iv_source_path = compare.first; - } - else - { - yyfname.push_back(iv_source_path); - } - - if(!narg) // TEST MODE - { - iv_source_path = "p7.initfile"; - header_files.insert("p7_init_spies.h"); - header_files.insert("p7_init_arrays.h"); - header_files.insert("ciniIfSymbols.H"); - } - - size_t pos = iv_source_path.rfind('.'); - if(pos != string::npos) - { - string type = iv_source_path.substr(pos+1); - if(type.compare(0,2,"if") == 0) iv_type = IF_TYPE; - else if(type.compare(0,8,"initfile") == 0) iv_type = INITFILE_TYPE; - - size_t pos1 = iv_source_path.rfind('/',pos); - if(pos1 == string::npos) pos1 = 0; - else ++pos1; - - iv_initfile = iv_source_path.substr(pos1,pos-pos1); - } - - if(iv_outdir.length() == 0) iv_outdir.push_back('.'); - if(iv_outdir.at(iv_outdir.size()-1) != '/') iv_outdir.push_back('/'); - - if(iv_outfile.size() == 0) - { - iv_outfile.append(iv_initfile); - iv_outfile.append(".if"); - } - - iv_outfile.insert(0,iv_outdir); - - dbg_fname = dbg_fn(); - - stats << "*********************************************************" << endl; - stats << "* source: " << iv_source_path << endl; - stats << "* listing: " << listing_fn() << endl; - stats << "* attr: " << attr_listing_fn() << endl; - stats << "* binary: " << binseq_fn() << endl; - - if (yyincludepath.size()) - { - stats << "* search paths for include files:" << endl; - for (size_t i = 0; i < yyincludepath.size(); i++) - { - stats << "* " << yyincludepath.at(i) << endl; - } - stats << "*" << endl; - } - - iv_scomlist = new ScomList(iv_source_path, header_files, stats, iv_ec); //dg002c - if(compare.second.size()) - { - ScomList cmplist(compare.second, header_files, stats, iv_ec); //dg002c - if(iv_scomlist->compare(cmplist)) - { - cout << "Compare SUCCESS" << endl; - } - else - { - cout << stats; - } - } - - iv_list_ostream.open(listing_fn().c_str()); - if(!iv_list_ostream) - { - std::ostringstream msg; - msg << "initCompiler.C: Parser: Could not open " << listing_fn() << endl; - throw invalid_argument(msg.str()); - } - - iv_attr_list_ostream.open(attr_listing_fn().c_str()); - if(!iv_attr_list_ostream) - { - std::ostringstream msg; - msg << "initCompiler.C: Parser: Could not open " << attr_listing_fn() << endl; - throw invalid_argument(msg.str()); - } -} - -Parser::~Parser() -{ - iv_list_ostream.close(); - iv_attr_list_ostream.close(); -} - -void init::capture_dbg(string i_fname) -{ - ofstream dbgfs(i_fname.c_str()); - if(!dbgfs) - { - std::ostringstream msg; - msg << "initCompiler.C: capture_dbg: Could not open " << i_fname << endl; - throw invalid_argument(msg.str()); - } - dbgfs << dbg.str() << endl; - dbgfs.close(); -} - -// TODO -// - Detect all errors down to a line # ? -// - bad rows/cols check - have already? -// diff --git a/src/usr/hwpf/ifcompiler/initCompiler.H b/src/usr/hwpf/ifcompiler/initCompiler.H deleted file mode 100755 index 9655554e5..000000000 --- a/src/usr/hwpf/ifcompiler/initCompiler.H +++ /dev/null @@ -1,128 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/hwpf/ifcompiler/initCompiler.H $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2011,2014 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -#if !defined(INITCOMPILER_H) -#define INITCOMPILER_H - -// Change Log ************************************************************************************* -// -// Flag Track Userid Date Description -// ----- -------- -------- -------- ------------------------------------------------------------- -// D754106 dgilbert 06/14/10 Create -// dg002 SW039868 dgilbert 10/15/10 Add support to filter unneeded inits by EC -// dg003 D779902 dgilbert 12/08/10 Ability to specify output if file -// andrewg 05/24/11 Port over for VPL/PgP -// andrewg 09/19/11 Updates based on review -// mjjones 11/17/11 Output attribute listing -// camvanng 04/12/12 Ability to specify search paths for include files -// camvanng 06/27/12 Improve error and debug tracing -// End Change Log ********************************************************************************* -// $Id: initCompiler.H,v 1.4 2014/06/27 20:02:27 thi Exp $ -/** - * @file initCompiler.H - * @brief Compile an initfile into bytecode. - */ - -#include <initRpn.H> -#include <initScom.H> -#include <set> -#include <string> -#include <fstream> - -using namespace std; - - -// bison & flex globals - -extern int yyline; -extern FILE * yyin; -extern int yyparse(); -void yyerror(const char * s); -extern init::ScomList * yyscomlist; -extern vector<string> yyincludepath; -extern vector<string> yyfname; -extern string dbg_fname; - -namespace init -{ - - - extern ostringstream dbg; // debug (verbose) output - extern ostringstream erros; // error output stream - extern ostringstream stats; // Misc info to be displayed - - /** - * Dump the dbg stringstream to a file - * @param i_fname file to dump dbg stringstream - */ - void capture_dbg(string i_fname); - - - - class Parser - { - public: - - enum - { - IF_TYPE = 1, - INITFILE_TYPE = 2 - }; - - Parser(int narg, char ** argv); - ~Parser(); - - string listing_fn() { return (binseq_fn()).append(".list"); } - string attr_listing_fn() { return (binseq_fn()).append(".attr"); } - string source_fn() { return iv_source_path; } - string binseq_fn() { return iv_outfile; } //dg003a - //{ string s(iv_outdir); s.append(iv_initfile); s.append(".if"); return s; } //dg003d - - // File to dump dbg stringstream - string dbg_fn() {string fname(iv_outdir); fname += iv_initfile + ".dbg"; return fname; } - - uint32_t get_source_type() { return iv_type; } - - ostream & listing_ostream() { return iv_list_ostream; } - ostream & attr_listing_ostream() { return iv_attr_list_ostream; } - - bool debug_mode() { return iv_dbg; } - - private: - string iv_prog_name; - string iv_source_path; - string iv_initfile; - string iv_outdir; - string iv_outfile; //dg003a - ofstream iv_list_ostream; - ofstream iv_attr_list_ostream; - uint32_t iv_type; - ScomList * iv_scomlist; - bool iv_dbg; - uint32_t iv_ec; // ec filter (if there is one) dg002a - - }; -} - -#endif diff --git a/src/usr/hwpf/ifcompiler/initCompiler.lex b/src/usr/hwpf/ifcompiler/initCompiler.lex deleted file mode 100755 index 26248e7d9..000000000 --- a/src/usr/hwpf/ifcompiler/initCompiler.lex +++ /dev/null @@ -1,681 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/hwpf/ifcompiler/initCompiler.lex $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2011,2014 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -/* Change Log ************************************************************************************* -// $Id: initCompiler.lex,v 1.15 2014/07/07 20:44:40 thi Exp $ -// -// Flag Track Userid Date Description -// ---- -------- -------- -------- ------------------------------------------------------------- -// D754106 dgilbert 06/14/10 Create -// dg01 D766229 dgilbert 08/03/10 add check for hex/bin data > 64 bits -// dg02 SW058986 dgilbert 02/28/11 More noticeable fail for missing col headers -// andrewg 09/19/11 Updates based on review -// camvanng 11/08/11 Added support for attribute enums -// camvanng 11/16/11 Support system & target attributes -// camvanng 12/12/11 Support multiple address ranges within a SCOM address -// camvanng 01/20/12 Support for using a range of indexes for array attributes -// camvanng 02/07/12 Ability to #include common scom initfile defines -// camvanng 02/14/12 Support binary and hex scom addresses -// Support for array at beginning of scom address -// camvanng 04/12/12 Right justify SCOM data -// Ability to specify search paths for include files -// camvanng 04/16/12 Support defines for SCOM address -// Support defines for bits, scom_data and attribute columns -// camvanng 05/07/12 Support for associated target attributes -// Save and restore line numbers for each include file -// camvanng 05/22/12 Fix "OP" definition -// camvanng 06/11/12 Fix shift/reduce warnings from yacc -// camvanng 06/15/12 Ability to do bitwise OR and AND operations -// camvanng 06/27/12 Improve error handling -// camvanng 07/12/12 Support for "ANY" -// thi 07/07/14 Add compilation option to sync with HB and CVS -// End Change Log *********************************************************************************/ -/** - * @file initCompiler.lex - * @brief Contains the rules for the lex/flex lexical scanner for scanning initfiles - * - * This code runs as part of the build process to generate a - * byte-coded representation of an initfile - */ -%{ -#include <stdint.h> -#include <iostream> -#include <sstream> -#include <iomanip> -#include <vector> -#include <initRpn.H> - -#ifdef HOSTBOOT_COMPILE -#include <ifcompiler.y.tab.h> -#else -#include <y.tab.h> -#endif - -uint64_t bits2int( const char * bitString); -uint64_t hexs2int(const char * hexString, int32_t size); -void pushBackScomBody(); -void push_col(const char *s); -void lex_err(const char *s ); -void add_define(const char *s); -void pushBackDefine(const char *s); - -std::ostringstream oss; -std::ostringstream t_oss; - -typedef std::vector<std::ostringstream *> OSS_LIST; -OSS_LIST g_colstream; - -inline void clear_colstream() -{ for( OSS_LIST::iterator i = g_colstream.begin(); i != g_colstream.end(); ++i) delete *i; - g_colstream.clear(); -} -uint32_t g_scomcol; -uint32_t g_coltype = 0; -uint32_t g_scomtype = 0; -uint32_t g_paren_level = 0; -bool g_equation = false; // equation inside scomv col -std::string g_scomdef_name; -std::map<std::string,std::string> g_defines; //container for all the defines - //i.e. define def_A = (attrA > 1) => key = "DEF_A", value = "(attr_A > 1)" - -std::string g_target; //storage for current target - -extern int yyline; -extern std::vector<std::string> yyincludepath; -extern std::map<std::string,std::string> yytarget; //container for all defined targets - //i.e. define MBA0 = TGT1 => key = "TGT1", value = "MBA0" - -#define MAX_INCLUDE_DEPTH 10 -YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; -int yyline_stack[MAX_INCLUDE_DEPTH]; -int include_stack_num = 0; - -extern std::vector<std::string> yyfname; - -%} - - - - -NEWLINE \n -FILENAME [A-Za-z][A-Za-z0-9_\.]* -ID [A-Za-z][A-Za-z0-9_]* -ID2 [A-Za-z][A-Za-z0-9_]*(\[[0-9]+(\.\.[0-9]+)?(,[0-9]+(\.\.[0-9]+)?)*\]){0,4} -ID3 [0-9]+[A-Za-z_]+[0-9]* -DIGIT [0-9] -COMMENT #.*\n -OP "="|"+"|"-"|"!"|"<"|">"|"*"|"/"|"%"|"&"|"|" -FLOAT [0-9]+"."[0-9]* -BINARY 0[bB][0-1]+ -SINGLE_BIN [0-1] -SCOM_DATA [ ]*[scom_data][ ]+ -HEX 0[xX][A-Fa-f0-9]+ -SINGLE_HEX [A-Fa-f0-9] -ATTRIBUTE [\[[A-Fa-f0-9]\]] -MULTI_DIGIT [0-9]+ -MULTI_INDEX_RANGE [0-9]+(\.\.[0-9]+)?(,[0-9]+(\.\.[0-9]+)?)* - -%x scomop -%x scomop_hex -%x scomop_hex_array -%x scomop_hex_suffix -%x scomop_bin -%x scomop_bin_array -%x scomop_bin_suffix -%x scomdata -%x when_kw -%x when_expr -%x scomcolname -%x scomrow -%x list -%x enumcol -%x fnames -%x target -%x attribute -%x array -%x incl -%x scomdef -%x scomdef_value - - -%% - -{COMMENT} ++yyline; /* toss comments - need first line */ -\$Id:.*\n ++yyline; /* toss this - read by initCompiler.C */ - - /* Special end-of-file character. */ -<<EOF>> { - if (--include_stack_num < 0) - { - g_defines.clear(); - return 0; - } - else - { - yy_delete_buffer(YY_CURRENT_BUFFER); - fclose(yyin); - yy_switch_to_buffer(include_stack[include_stack_num]); - yyline = yyline_stack[include_stack_num]; - yyfname.pop_back(); - } - } - -SyntaxVersion return INIT_VERSION; - - /* The list of initfile versions is just copied into the *.if file - * so just make it one chunk of string data */ -Versions BEGIN(fnames); -<fnames>[=] oss.str(""); -<fnames>{FLOAT} oss << yytext; -<fnames>[:] oss << yytext; -<fnames>[,] oss << ", "; -<fnames>{FILENAME} oss << yytext; -<fnames>{NEWLINE} { ++yyline; - yylval.str_ptr = new std::string(oss.str()); - BEGIN(INITIAL); - return INIT_VERSIONS; - } - -include { BEGIN(incl); } -<incl>[ \t]* /* Eat up whitespace */ -<incl>[^ \t\n]+ { /* Got the include file name */ - /*printf("lex: include file %s\n", yytext);*/ - if ( include_stack_num >= MAX_INCLUDE_DEPTH ) - { - lex_err("Include nested too deeply"); - lex_err(yytext); - exit( 1 ); - } - - /* Save current line number */ - yyline_stack[include_stack_num] = - yyline; - - /* Save current input buffer */ - include_stack[include_stack_num++] = - YY_CURRENT_BUFFER; - - /* Switch input buffer */ - std::string filename = yytext; - yyin = fopen( filename.c_str(), "r" ); - for (size_t i = 0; (i < yyincludepath.size()) && (NULL == yyin); i++) - { - filename = yyincludepath.at(i) + "/" + yytext; - yyin = fopen( filename.c_str(), "r" ); - } - if (NULL == yyin) - { - oss.str(""); - oss << "Cannot open include file: " << yytext; - lex_err(oss.str().c_str()); - exit(1); - } - printf("Include file %s\n", filename.c_str()); - yyline = 1; //set line number for new buffer - yyfname.push_back(filename); //save file name of new file being parsed - yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); - - BEGIN(INITIAL); - } - - /* Adding the ability to use defines for SCOM address and the different - * columns (bits, scom_data and attribute columns). - * Since the SCOM address and the different columns all have different - * parsing rules, it is complicated to handle this in both the scanner and parser. - * The simplest thing to do is to keep track of all the defines in the scanner - * then push the specific define value back into the input stream for scanning - * when it is used. - */ - -define { BEGIN(scomdef); } - -<scomdef>{ID} { g_scomdef_name = yytext; } -<scomdef>[ \t\r]*=[ \t\r]* { BEGIN(scomdef_value); } -<scomdef_value>[^;\n#\{\}]+ { add_define(yytext); } -<scomdef_value>; { g_scomdef_name = ""; BEGIN(INITIAL); } - -scom { BEGIN(scomop); oss.str(""); return INIT_SCOM; } - -<scomop>{HEX} { /*printf("lex: hex string %s\n", yytext);*/ - yylval.str_ptr = new std::string(yytext); - BEGIN(scomop_hex); - return INIT_SCOM_ADDR; - } - -<scomop>0[xX] { BEGIN(scomop_hex); } -<scomop>0[bB] { BEGIN(scomop_bin); } - -<scomop_hex,scomop_hex_suffix>[\(] { - /*printf("lex: hex string %s\n", yytext);*/ - BEGIN(scomop_hex_array); - } - -<scomop_hex_array>{SINGLE_HEX}+\.\.{SINGLE_HEX}+ { - /*printf("lex: hex string %s\n", yytext);*/ - yylval.str_ptr = new std::string(yytext); - return INIT_INT64_STR; - } - -<scomop_hex_array>{SINGLE_HEX}+ { - /*printf("lex: hex string %s\n", yytext);*/ - yylval.str_ptr = new std::string(yytext); - return INIT_INT64_STR; - } - -<scomop_hex_array>[\)] { - /*printf("lex: hex string %s\n", yytext);*/ - BEGIN(scomop_hex_suffix); - } - -<scomop_hex,scomop_hex_suffix>{SINGLE_HEX}+ { - /*printf("lex: hex string %s\n", yytext);*/ - yylval.str_ptr = new std::string(yytext); - return INIT_SCOM_SUFFIX; - } - -<scomop_hex,scomop_hex_suffix>\.0[bB] { BEGIN(scomop_bin); return yytext[0]; } - -<scomop_bin>{SINGLE_BIN}+ { - /*printf("lex: bin string %s\n", yytext);*/ - yylval.str_ptr = new std::string(yytext); - return INIT_SCOM_ADDR_BIN; - } - -<scomop_bin,scomop_bin_suffix>[\(] { - /*printf("lex: bin string %s\n", yytext);*/ - BEGIN(scomop_bin_array); - } -<scomop_bin_array>{SINGLE_BIN}+\.\.{SINGLE_BIN}+ { - /*printf("lex: bin string %s\n", yytext);*/ - yylval.str_ptr = new std::string(yytext); - return INIT_BINARY_STR; - } - -<scomop_bin_array>{SINGLE_BIN}+ { - /*printf("lex: bin string %s\n", yytext);*/ - yylval.str_ptr = new std::string(yytext); - return INIT_BINARY_STR; - } - -<scomop_bin_array>[\)] { - /*printf("lex: bin string %s\n", yytext);*/ - BEGIN(scomop_bin_suffix); - } - -<scomop_bin_suffix>{SINGLE_BIN}+ { - /*printf("lex: bin string %s\n", yytext);*/ - yylval.str_ptr = new std::string(yytext); - return INIT_SCOM_SUFFIX_BIN; - } - -<scomop_bin,scomop_bin_suffix>\.(0[xX])? { - /*printf("lex: bin string %s\n", yytext);*/ - BEGIN(scomop_hex); return yytext[0]; - } - -<scomop_bin,scomop_bin_suffix>\.0[bB] { - /*printf("lex: bin string %s\n", yytext);*/ - } - -<scomop_hex_array,scomop_bin_array>{ID}\.\.{ID} { pushBackDefine(yytext); } -<scomop_hex,scomop_hex_suffix,scomop_bin,scomop_bin_suffix>\.{ID} { pushBackDefine(yytext + 1); unput('.'); } -<scomop,scomop_hex_array,scomop_hex_suffix,scomop_bin_array,scomop_bin_suffix>{ID} { pushBackDefine(yytext); } - -<scomop>[:;\[] { BEGIN(INITIAL); g_coltype = 0; return yytext[0]; } -<scomop>{NEWLINE} { BEGIN(INITIAL); ++yyline; } - -<scomop_hex,scomop_hex_suffix,scomop_bin,scomop_bin_suffix>[\{] { - oss.str(""); - BEGIN(scomcolname); - return yytext[0]; - } - - - - - /* The column & row format is really hard to handle in the parser, - * especially since each column can have different parsing rules. - * So fix it here in the scanner by converting the format to - * coltitle1 , row1, row2, ..., row n ; - * coltitle2 , row1, row2, ..., row n ; - * then push it all back into the input stream and scan the new format - */ - -<scomcolname>{COMMENT} ++yyline; -<scomcolname>\n ++yyline; -<scomcolname>{ID} { // Only non-array attributes are supported for attribute column - g_colstream.push_back(new std::ostringstream()); - *(g_colstream.back()) << yytext; - } -<scomcolname>, {} -<scomcolname>; { BEGIN(scomrow); g_scomcol = 0; } - -<scomrow>{COMMENT} ++yyline; -<scomrow>{NEWLINE} ++yyline; -<scomrow>([^,;\n#\{\}]+{ID2}*)+ push_col(yytext); -<scomrow>[,] ++g_scomcol; -<scomrow>[;] { - if ((g_scomcol + 1) < g_colstream.size()) - { - lex_err("# Scom columns < # of column headers"); - exit(1); - } - g_scomcol = 0; - } -<scomrow>[\}] { - pushBackScomBody(); // create new format and put it back on yyin - BEGIN(INITIAL); - } - - - /* The scombody is the modified format - don't track yyline as it's already - * accounted for. Any errors in here will point back to the last line in the - * 'real' scombody - */ - -bits { g_coltype = INIT_BITS; return INIT_BITS;} -expr { g_coltype = INIT_EXPR; return INIT_EXPR;} -scom_data { g_coltype = INIT_SCOMD; return INIT_SCOMD;} - - /*HEX and Binary numbers in the scombody can be up to 64bit, - * decimal numbers will always fit in 32bit int */ - -{BINARY} { yylval.uint64 = bits2int(yytext); return INIT_INT64; } - -<*>; { g_coltype = 0; return ';'; } - -END_INITFILE return INIT_ENDINITFILE; - -<*>SYS\. yymore(); //System attribute - -<*>TGT{MULTI_DIGIT}\. { - if (g_target.length()) - { - std::string tgt(yytext); - tgt = tgt.substr(0, tgt.length() -1); - yytarget[tgt] = g_target; - g_target.clear(); - } - - yymore(); //Associated target attribute - } - - /* All attribute enums start with "ENUM_ATTR_" */ -<*>ENUM_ATTR_{ID} { - yylval.str_ptr = new std::string(yytext); return ATTRIBUTE_ENUM; - } - - /* All attributes start with "ATTR_"; then there's "any". */ -<*>ATTR_{ID}|"any"|"ANY" { - yylval.str_ptr = new std::string(yytext); return INIT_ID; - } - - /* Anything else is a define. - * Removing any requirements that defines has to start with "def_" or "DEF_" */ -<*>{ID}\. { // push back the define value for scanning - g_target = yytext; - g_target = g_target.substr(0, g_target.length() - 1); - //printf("lex: %s\n", g_target.c_str()); - unput('.'); - pushBackDefine(g_target.c_str()); - } - -<*>{ID} { // push back the define value for scanning - pushBackDefine(yytext); - } - -<*>{DIGIT}+ { - sscanf(yytext, "%d", &yylval.integer); return INIT_INTEGER; - } - -<*>{HEX} { - // normal right-justified 64 bit hex integer - yylval.uint64 = hexs2int(yytext,yyleng); - return INIT_INT64; - } - -<*>"&&" return INIT_LOGIC_AND; -<*>"||" return INIT_LOGIC_OR; -<*>"==" return INIT_EQ; -<*>"!=" return INIT_NE; -<*>"<=" return INIT_LE; -<*>">=" return INIT_GE; -<*>">>" return INIT_SHIFT_RIGHT; -<*>"<<" return INIT_SHIFT_LEFT; - -<*>{OP} { g_equation = true; return yytext[0]; } -<*>[\(] { ++g_paren_level; return yytext[0]; } -<*>[\)] { --g_paren_level; return yytext[0]; } - -<*>\[{MULTI_INDEX_RANGE}\] { yylval.str_ptr = new std::string(yytext); return ATTRIBUTE_INDEX; } - -<*>[\{\},:] {g_equation = false; return yytext[0]; } - -<*>[ \t\r]+ /* Eat up whitespace */ -[\n] { BEGIN(INITIAL);++yyline;} - -<*>. { - oss.str(""); - oss << yytext << " is not valid syntax"; - lex_err(oss.str().c_str()); - exit(1); - } - -%% - -int yywrap() { return 1; } - -void lex_err(const char *s ) -{ - std::cerr << "\nERROR: lex: " << yyfname.back().c_str() - << ", line " << yyline << ": " << s << std::endl << std::endl; -} - -// Convert left justified bitstring to right-justified 64 bit integer -uint64_t bits2int( const char * bitString) -{ - uint32_t idx = 0; - uint64_t mask = 0x0000000000000001ull; - uint64_t val = 0; - - if( (bitString[0] != '0') || - ((bitString[1] != 'b') && (bitString[1] != 'B'))) - { - lex_err("Invalid bit string"); - lex_err(bitString); - exit(1); - } - idx = 2; - - while( bitString[idx] != 0 ) - { - val <<= 1; - char c = bitString[idx]; - if( c == '1') val |= mask; - else if(c != '0') - { - lex_err("Invalid bit string"); - lex_err(bitString); - exit(1); - } - ++idx; - } - if(idx > 66) //dg01a 64bits + "0B" prefix - { - lex_err("Bit string greater than 64 bits!"); - lex_err(bitString); - exit(1); - } - - return val; -} - -// Convert left justified hex string to 64 right-justified bit integer -uint64_t hexs2int(const char * hexString, int32_t size) -{ - uint64_t val = 0; - std::string s(hexString); - if(size > 18) //dg01a - { - lex_err("HEX literal greater than 64 bits"); - lex_err(hexString); - exit(1); - } - s.insert(2, 18-size,'0'); // 0x + 16 digits - val = strtoull(s.c_str(),NULL,16); - return val; -} - -void pushBackScomBody() -{ - std::ostringstream ost; - for(OSS_LIST::iterator i = g_colstream.begin(); i != g_colstream.end(); ++i) - { - ost << (*i)->str() << ';'; - } - ost << '}'; - std::string t = ost.str(); // Was causing weird stuff if I didn't copy the string out first - //std::cout << "<lex comment> Pushing:" << t << std::endl; - //std::cout << "<lex comment> " << std::endl; - - for(std::string::reverse_iterator r = t.rbegin(); - r != t.rend(); - ++r) - { - //std::cout << *r; - unput(*r); - } - //std::cout << std::endl; - clear_colstream(); -} - - -/// help collect column data -void push_col(const char * s) -{ - if(g_scomcol >= g_colstream.size()) // more data cols than headers cols - { - lex_err("Missing column header"); - exit(1); - } - - std::ostringstream & o = *(g_colstream[g_scomcol]); - std::ostringstream token; - std::istringstream iss(s); - std::string t; - //std::cout << "Pushing "; - while(iss >> t) token << t; // get rid of white space - if(token.str().size()) // don't add blank tokens - { - //std::cout << "Pushing ," << token.str() << std::endl; - o << ',' << token.str(); - } -} - - -/// Save the define -void add_define(const char * s) -{ - if (g_defines.end() != g_defines.find(g_scomdef_name)) - { - oss.str(""); - oss << g_scomdef_name << " already defined"; - lex_err(oss.str().c_str()); - exit(1); - } - - //remove trailing white spaces - std::string str(s); - std::string whitespaces(" \t\r"); - size_t pos; - pos=str.find_last_not_of(whitespaces); - if (pos != std::string::npos) - { - str.erase(pos+1); - } - - g_defines[g_scomdef_name] = str; - //std::cout << "g_defines[" << g_scomdef_name << "] = " << g_defines[g_scomdef_name] << std::endl; -} - -// Push the define(s) back into the input stream for scanning -void pushBackDefine(const char *s) -{ - std::string key(s); //set key to input string - std::string key2; - std::string value; - - //std::cout << "lex: pushBackDefine input string: " << s << " key: " << key << std::endl; - - //Is this a range? - size_t pos = key.find(".."); - if (pos != std::string::npos) - { - key2 = key.substr(pos+2); //2nd key in the range - key = key.substr(0,pos); //Reset 1st key in the range - } - - //Exit if cannot find 1st key - if (g_defines.end() == g_defines.find(key)) - { - oss.str(""); - oss << "Cannot find define " << key; - lex_err(oss.str().c_str()); - exit(1); - } - - // Set value string - value = g_defines[key]; - if (key2.size()) - { - //Exit if cannot find 2nd key - if (g_defines.end() == g_defines.find(key2)) - { - oss.str(""); - oss << "Cannot find define " << key; - lex_err(oss.str().c_str()); - exit(1); - } - - //Get rid of spaces & append key2 value - size_t pos = value.find(' '); - if (pos != std::string::npos) - { - value = value.substr(0,pos); - } - value += ".." + g_defines[key2]; - } - - //std::cout << "lex: pushBackDefine: " << value << std::endl; - - //Push back the value into the input stream - for(std::string::reverse_iterator r = value.rbegin(); - r != value.rend(); - ++r) - { - //std::cout << *r; - unput(*r); - } - //std::cout << std::endl; -} diff --git a/src/usr/hwpf/ifcompiler/initCompiler.y b/src/usr/hwpf/ifcompiler/initCompiler.y deleted file mode 100755 index cacc890f3..000000000 --- a/src/usr/hwpf/ifcompiler/initCompiler.y +++ /dev/null @@ -1,366 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/hwpf/ifcompiler/initCompiler.y $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2011,2014 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -// Change Log ************************************************************************************* -// -// Flag Track Userid Date Description -// ---- -------- -------- -------- ------------------------------------------------------------- -// D754106 dgilbert 06/14/10 Create -// D774126 dgilbert 09/30/10 Add ERROR: to yyerror message -// andrewg 09/19/11 Updates based on review -// camvanng 11/08/11 Added support for attribute enums -// andrewg 11/09/11 Refactor to use common include with hwp framework. -// camvanng 12/12/11 Support multiple address ranges within a SCOM address -// camvanng 01/20/12 Support for using a range indexes for array attributes -// camvanng 02/14/12 Support binary and hex scom addresses -// Support for array at beginning of scom address -// camvanng 04/16/12 Support defines for SCOM address -// Support defines for bits, scom_data and attribute columns -// Delete obsolete code for defines support -// camvanng 05/22/12 Ability to do simple operations on attributes -// in the scom_data column -// camvanng 06/11/12 Ability to do logical operations with attribute columns -// Fix shift/reduce warnings from yacc -// camvanng 06/15/12 Ability to do bitwise OR and AND operations -// camvanng 06/27/12 Improve error and debug tracing -// End Change Log ********************************************************************************* -// $Id: initCompiler.y,v 1.10 2014/06/30 19:49:24 thi Exp $ -/** - * @file initCompiler.y - * @brief Contains the yacc/bison code for parsing an initfile. - * - * This code runs as part of the build process to generate a - * byte-coded representation of an initfile - */ -%{ -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <string> -#include <iostream> -#include <iomanip> -#include <sstream> -#include <initCompiler.H> -#include <initSymbols.H> - - -init::Scom * current_scom = NULL; - -extern int yylex(); -void yyerror(const char * s); - -int scom; - -%} - -/* Union for the yylval variable in lex or $$ variables in bsion code. - * Used to store the data associated with a parsed token. - */ -%union{ - uint32_t integer; - uint64_t uint64; - std::string * str_ptr; - init::Rpn * rpn_ptr; -} - - /* indicates the name for the start symbol */ -%start input - - /* Define terminal symbols and the union type - * associated with each. */ - -%token <integer> INIT_INTEGER -%token <uint64> INIT_INT64 -%token <str_ptr> INIT_INT64_STR -%token <str_ptr> INIT_SCOM_ADDR -%token <str_ptr> INIT_SCOM_SUFFIX -%token <str_ptr> INIT_BINARY_STR -%token <str_ptr> INIT_SCOM_ADDR_BIN -%token <str_ptr> INIT_SCOM_SUFFIX_BIN -%token <uint64> INIT_SCOM_DATA -%token <str_ptr> INIT_ID -%token <str_ptr> INIT_VERSIONS -%token <str_ptr> ATTRIBUTE_INDEX -%token <str_ptr> ATTRIBUTE_ENUM - - - /* Define terminal symbols that don't have any associated data */ - -%token INIT_VERSION -%token INIT_ENDINITFILE -%token INIT_BITS -%token INIT_EXPR -%token INIT_TARG -%token INIT_EQ -%token INIT_NE -%token INIT_LE -%token INIT_GE -%token INIT_SCANINIT -%token INIT_SCOMINIT -%token INIT_SCOM -%token INIT_SCOMD - - - /* non-terminal tokens and the union data-type associated with them */ - -%type <str_ptr> bitsrows -%type <rpn_ptr> expr id_colexpr id_col num_list scomdexpr - - - - - -/* top is lowest precedent - done last */ -%left INIT_LOGIC_OR -%left INIT_LOGIC_AND -%left '|' /* bitwise OR */ -%left '^' /* bitwise XOR */ -%left '&' /* bitwise AND */ -%left INIT_EQ INIT_NE -%left INIT_LE INIT_GE '<' '>' -%left INIT_SHIFT_RIGHT INIT_SHIFT_LEFT -%left '-' '+' -%left '*' '/' '%' -%right '!' '~' /* logic negation bitwise complement*/ -%left ATTRIBUTE_INDEX /* highest precedence */ -/* bottom is highest precedent - done first */ - - - - -%% -/* Grammars */ - /* the 'input' is simply all the lines */ -input: - | input line -; - -line: scom - | cvs_versions - | syntax_version - | INIT_ENDINITFILE {} -; - - -cvs_versions: INIT_VERSIONS - { - yyscomlist->set_cvs_versions($1); delete $1; - } -; - -syntax_version: INIT_VERSION '=' INIT_INTEGER - { - yyscomlist->set_syntax_version($3); - } -; - -scom: INIT_SCOM {current_scom = new init::Scom(yyscomlist->get_symbols(),yyline);} - | scom scomaddr '{' scombody '}' - { - /* printf("Found an INIT_SCOM!\n"); */ - /* current_scom = new init::Scom(yyscomlist->get_symbols(),yyline); */ - yyscomlist->insert(current_scom); - init::dbg << current_scom->addr_listing() << std::endl; - } -; - -scomaddr: - scomaddr_hex { /*printf("Found a hex scom address\n");*/ } - | scomaddr_bin { /*printf("Found a binary scom address\n");*/ - current_scom->append_scom_address_bin(); } - | scomaddr '.' scomaddr_hex { /*printf("Found a hex scom address 2\n");*/ } - | scomaddr '.' scomaddr_bin { /*printf("Append binary scom address 2\n");*/ - current_scom->append_scom_address_bin(); } -; - - - -scomaddr_hex: INIT_SCOM_ADDR { /*printf("Found an INIT_SCOM_ADDR %s\n", (*($1)).c_str());*/ - current_scom->set_scom_address(*($1)); delete $1; } - | scom_list { current_scom->copy_dup_scom_address(); } - | INIT_SCOM_SUFFIX { current_scom->set_scom_suffix(*($1)); delete $1; } - | scomaddr_hex scom_list { /*printf("Found a scom_list 2\n");*/ - current_scom->copy_dup_scom_address(); } - | scomaddr_hex INIT_SCOM_SUFFIX { /*printf("Found a scom suffix %s\n", (*($2)).c_str());*/ - current_scom->set_scom_suffix(*($2)); delete $2;} -; - - -scom_list: INIT_INT64_STR { current_scom->dup_scom_address(*($1));delete $1;} - | scom_list ',' INIT_INT64_STR { current_scom->dup_scom_address(*($3));delete $3;} -; - - -scomaddr_bin: INIT_SCOM_ADDR_BIN { /*printf("Found an INIT_SCOM_ADDR_BIN %s\n", (*($1)).c_str());*/ - current_scom->set_scom_address_bin(*($1)); delete $1; } - | scom_bin_list { /*printf("Found a scom_bin_list\n");*/ - current_scom->copy_dup_scom_address_bin(); } - | scomaddr_bin INIT_SCOM_ADDR_BIN { /*printf("Found an INIT_SCOM_ADDR_BIN 2 %s\n", (*($2)).c_str());*/ - current_scom->set_scom_suffix_bin(*($2)); delete $2;} - | scomaddr_bin scom_bin_list { /*printf("Found a scom_bin_list 2\n");*/ - current_scom->copy_dup_scom_address_bin(); } - | scomaddr_bin INIT_SCOM_SUFFIX_BIN { /*printf("Found a scom binary suffix %s\n", (*($2)).c_str());*/ - current_scom->set_scom_suffix_bin(*($2)); delete $2;} -; - -scom_bin_list: INIT_BINARY_STR { current_scom->dup_scom_address_bin(*($1));delete $1; } - | scom_bin_list ',' INIT_BINARY_STR { current_scom->dup_scom_address_bin(*($3));delete $3; } -; - - /* The scombody was reformatted by the scanner - * colname1 , row1 , row 2, ... , row n ; - * colname2 , row1 , row 2, ... , row n ; - */ - -scombody: scombodyline ';' {} - | scombody scombodyline ';' {} -; - -scombodyline: INIT_SCOMD ',' scomdrows {} - | INIT_BITS ',' bitsrows {} - | INIT_EXPR ',' exprrows { init::dbg << "Add col EXPR" << endl; current_scom->add_col("EXPR"); } - | INIT_ID ',' idrows { - current_scom->add_col(*($1)); - init::dbg << "Add col " << *($1) << endl; - delete $1; - } -; - - -scomdrows: scomdexpr { - /* printf("\n\nscomdrows - RPN Address:0x%X\n\n\n",$1); */ - init::dbg << $1->listing("Length scom RPN"); - current_scom->add_scom_rpn($1); - } - | scomdrows ',' scomdexpr { init::dbg << $3->listing("Length scom RPN"); current_scom->add_scom_rpn($3); } -; - -scomdexpr: INIT_INTEGER { $$= new init::Rpn($1,yyscomlist->get_symbols());} - | INIT_ID { $$= new init::Rpn(*($1),yyscomlist->get_symbols()); delete $1;} - | ATTRIBUTE_ENUM { $$= new init::Rpn((yyscomlist->get_symbols())->get_attr_enum_val(*($1)),yyscomlist->get_symbols()); delete $1; } - | INIT_INT64 { $$=new init::Rpn($1,yyscomlist->get_symbols()); } - | scomdexpr ATTRIBUTE_INDEX { $1->push_array_index(*($2)); delete $2; } - | scomdexpr INIT_SHIFT_RIGHT scomdexpr { $$ = $1->push_merge($3,SHIFTRIGHT); } - | scomdexpr INIT_SHIFT_LEFT scomdexpr { $$ = $1->push_merge($3,SHIFTLEFT); } - | scomdexpr '+' scomdexpr { $$ = $1->push_merge($3,PLUS); } - | scomdexpr '-' scomdexpr { $$ = $1->push_merge($3,MINUS); } - | scomdexpr '*' scomdexpr { $$ = $1->push_merge($3,MULT); } - | scomdexpr '/' scomdexpr { $$ = $1->push_merge($3,DIVIDE); } - | scomdexpr '%' scomdexpr { $$ = $1->push_merge($3,MOD); } - | scomdexpr '&' scomdexpr { $$ = $1->push_merge($3,BITWISEAND); } - | scomdexpr '|' scomdexpr { $$ = $1->push_merge($3,BITWISEOR); } - | '!' scomdexpr { $$ = $2->push_op(NOT); } - | '(' scomdexpr ')' { $$ = $2; } -; - -bitsrows: bitrange {} - | bitsrows ',' bitrange {} -; - -bitrange: INIT_INTEGER { current_scom->add_bit_range($1,$1); } - | INIT_INTEGER ':' INIT_INTEGER - { current_scom->add_bit_range($1,$3); } -; - -exprrows: expr { init::dbg << $1->listing(NULL); current_scom->add_row_rpn($1); } - | exprrows ',' expr - { init::dbg << $3->listing(NULL); current_scom->add_row_rpn($3); } -; - -idrows: id_colexpr { init::dbg << $1->listing(NULL); current_scom->add_row_rpn($1); } - | idrows ',' id_colexpr { init::dbg << $3->listing(NULL); current_scom->add_row_rpn($3); } -; - - // TODO num_list could be VARs,LITs, or even ranges eg {1,2..5,7} - -id_colexpr: id_col { $1->push_op(EQ); } - | INIT_EQ id_col { $$ = $2; $2->push_op(EQ); } - | INIT_NE id_col { $$ = $2; $2->push_op(NE); } - | INIT_LE id_col { $$ = $2; $2->push_op(LE); } - | INIT_GE id_col { $$ = $2; $2->push_op(GE); } - | '<' id_col { $$ = $2; $2->push_op(LT); } - | '>' id_col { $$ = $2; $2->push_op(GT); } -; - -id_col: INIT_ID { $$ = new init::Rpn(*($1),yyscomlist->get_symbols()); delete $1; } - | INIT_INTEGER { $$ = new init::Rpn($1,yyscomlist->get_symbols()); } - | '{' num_list '}' { $$ = $2; $2->push_op(LIST); } - | ATTRIBUTE_ENUM { $$ = new init::Rpn((yyscomlist->get_symbols())->get_attr_enum_val(*($1)),yyscomlist->get_symbols()); delete $1; } -; - -num_list: INIT_INTEGER { $$ = new init::Rpn($1,yyscomlist->get_symbols()); } - | INIT_ID { $$ = new init::Rpn(*($1),yyscomlist->get_symbols()); } - | num_list ',' INIT_INTEGER { $$ = $1; $1->merge(new init::Rpn($3,yyscomlist->get_symbols())); } - | num_list ',' INIT_ID { $$ = $1; $1->merge(new init::Rpn(*($3),yyscomlist->get_symbols())); } - | ATTRIBUTE_ENUM { $$ = new init::Rpn((yyscomlist->get_symbols())->get_attr_enum_val(*($1)),yyscomlist->get_symbols()); } -; - - /* expr should return an RPN string of some kind */ -expr: INIT_INTEGER { $$= new init::Rpn($1,yyscomlist->get_symbols()); } - | INIT_ID { $$= new init::Rpn(*($1),yyscomlist->get_symbols()); delete $1; } - | ATTRIBUTE_ENUM { $$= new init::Rpn((yyscomlist->get_symbols())->get_attr_enum_val(*($1)),yyscomlist->get_symbols()); delete $1; } - | INIT_INT64 { $$=new init::Rpn($1,yyscomlist->get_symbols()); } - | expr ATTRIBUTE_INDEX { $1->push_array_index(*($2)); delete $2; } - | expr INIT_LOGIC_OR expr { $$ = $1->push_merge($3,OR); } - | expr INIT_LOGIC_AND expr { $$ = $1->push_merge($3,AND); } - | expr INIT_EQ expr { $$ = $1->push_merge($3,EQ); } - | expr INIT_NE expr { $$ = $1->push_merge($3,NE); } - | expr INIT_LE expr { $$ = $1->push_merge($3,LE); } - | expr INIT_GE expr { $$ = $1->push_merge($3,GE); } - | expr '<' expr { $$ = $1->push_merge($3,LT); } - | expr '>' expr { $$ = $1->push_merge($3,GT); } - | expr INIT_SHIFT_RIGHT expr { $$ = $1->push_merge($3,SHIFTRIGHT); } - | expr INIT_SHIFT_LEFT expr { $$ = $1->push_merge($3,SHIFTLEFT); } - | expr '+' expr { $$ = $1->push_merge($3,PLUS); } - | expr '-' expr { $$ = $1->push_merge($3,MINUS); } - | expr '*' expr { $$ = $1->push_merge($3,MULT); } - | expr '/' expr { $$ = $1->push_merge($3,DIVIDE); } - | expr '%' expr { $$ = $1->push_merge($3,MOD); } - | expr '&' expr { $$ = $1->push_merge($3,BITWISEAND); } - | expr '|' expr { $$ = $1->push_merge($3,BITWISEOR); } - | '!' expr { $$ = $2->push_op(NOT); } - | '(' expr ')' { $$ = $2; } -; - - -%% - -void yyerror(const char * s) -{ - //dump dbg stringstream to file - init::capture_dbg(dbg_fname); - - init::erros << setfill('-') << setw(80) << '-' << endl; - init::erros << setfill('0'); - init::erros << "Parse Error: " << yyfname.back().c_str() << ", line " - << dec << setw(4) << yyline << ": yychar = " - << dec << (uint32_t) yychar << " = 0x" << hex << (uint32_t) yychar << " = '"; - if(isprint(yychar)) init::erros << (char)yychar; - else init::erros << ' '; - init::erros << "' yylval = " << hex << "0x" << setw(16) << yylval.uint64 << endl; - init::erros << "ERROR: " << s << endl; - init::erros << setfill('-') << setw(80) << '-' << endl << endl; - - cout << init::erros.str() << endl; -} diff --git a/src/usr/hwpf/ifcompiler/initRpn.C b/src/usr/hwpf/ifcompiler/initRpn.C deleted file mode 100755 index 1679d38c6..000000000 --- a/src/usr/hwpf/ifcompiler/initRpn.C +++ /dev/null @@ -1,1396 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/hwpf/ifcompiler/initRpn.C $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2011,2014 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -// Change Log ************************************************************************************* -// -// Flag Reason Userid Date Description -// ----- -------- -------- -------- ------------------------------------------------------------- -// D754106 dgilbert 06/14/10 Create -// dg002 SW039868 dgilbert 10/15/10 Add support to filter unneeded inits by EC -// dg003 SW047506 dgilbert 12/09/10 SERIES filtering -// andrewg 05/24/11 Port over for VPL/PgP -// andrewg 09/19/11 Updates based on review -// camvanng 11/08/11 Added support for attribute enums -// andrewg 11/09/11 Multi-dimensional array and move to common fapi include -// camvanng 01/06/12 Support for writing an attribute to a SCOM register -// camvanng 01/20/12 Support for using a range of indexes for array attributes -// camvanng 04/16/12 Support defines for SCOM address -// Support defines for bits, scom_data and attribute columns -// Delete obsolete code for defines support -// camvanng 05/07/12 Support for associated target attributes -// camvanng 05/22/12 Ability to do simple operations on attributes -// in the scom_data column -// SW146714 camvanng 06/08/12 Use two bytes to store row rpn sequence byte count -// camvanng 06/15/12 Ability to do bitwise OR and AND operations -// camvanng 06/27/12 Improve error and debug tracing -// End Change Log ********************************************************************************* -// $Id: initRpn.C,v 1.11 2014/06/30 19:56:40 thi Exp $ -/** - * @file initRpn.C - * @brief Definition of the initRpn class. Handles Reverse Polish Notation equations for initfiles - */ -#include <initRpn.H> -#include <initSymbols.H> -//#include <initSpy.H> -#include <stdlib.h> -#include <sstream> -#include <iomanip> -#include <iostream> -#include <stdexcept> -#include <cstring> -#include <fapiHwpInitFileInclude.H> // Requires file from hwpf - -extern void yyerror(const char * s); - -using namespace init; - -const char * OP_TXT[] = -{ - "PUSH", - "AND", - "OR", - "NOT", - "EQ", - "NE", - "GT", - "GE", - "LT", - "LE", - "PLUS", - "MINUS", - "MULT", - "DIVIDE", - "MOD", - "LIST", - "SHIFTLEFT", - "SHIFTRIGHT", - "FALSE", //dg003a - "TRUE", //dg003a - "BITWISEAND", - "BITWISEOR", -}; - -std::string Rpn::cv_empty_str; - -//------------------------------------------------------------------------------------------------- - -Rpn::Rpn(uint32_t i_uint,Symbols * symbols) : iv_symbols(symbols) -{ push_int(i_uint); } - -//------------------------------------------------------------------------------------------------- - -Rpn::Rpn(std::string i_id, Symbols * symbols, TYPE i_type) : iv_symbols(symbols) -{ push_id(i_id, i_type); } - -//------------------------------------------------------------------------------------------------- - -Rpn::Rpn(uint64_t i_uint, Symbols * symbols) : iv_symbols(symbols) -{ - push_int64(i_uint); -} - -//------------------------------------------------------------------------------------------------- - -bool Rpn::operator==(const Rpn & r) -{ - bool result = false; - if (iv_rpnstack.size() == r.iv_rpnstack.size()) - { - if (iv_symbols == r.iv_symbols) - { - result = true; - RPNSTACK::const_iterator c1 = iv_rpnstack.begin(); - RPNSTACK::const_iterator c2 = r.iv_rpnstack.begin(); - for (; c1 != iv_rpnstack.end(); ++c1, ++c2) - { - if (*c1 != *c2) - { - result = false; - break; - } - } - } - else // they have different symbol tables - { - result = true; - RPNSTACK::const_iterator c1 = iv_rpnstack.begin(); - RPNSTACK::const_iterator c2 = r.iv_rpnstack.begin(); - for (; c1 != iv_rpnstack.end(); ++c1, ++c2) - { - uint32_t t1 = (*c1) & TYPE_MASK; - uint32_t t2 = (*c2) & TYPE_MASK; - if(t1 != t2) - { - result = false; - break; - } - switch (t1) - { - case SYMBOL: - { - string s1 = iv_symbols->find_name(*c1); - string s2 = (r.iv_symbols)->find_name(*c2); - if(s1 != s2) result = false; - } - break; - case NUMBER: - { - uint32_t size = 0; - uint64_t data1 = iv_symbols->get_numeric_data(*c1,size); - uint64_t data2 = (r.iv_symbols)->get_numeric_data(*c2,size); - // do we care if the size is different only the value? - if(data1 != data2) result = false; - } - break; - case OPERATION: // independent of symbol table - just compare - default: // just compare - if(*c1 != *c2) result = false; - break; - } - if(result == false) break; - } - } - } - return result; -} - -//------------------------------------------------------------------------------------------------- - -void Rpn::push_int(uint32_t i_uint) -{ - uint32_t rpn_id = iv_symbols->find_numeric_lit(i_uint,4); - iv_rpnstack.push_back(rpn_id); -} - -//------------------------------------------------------------------------------------------------- - -void Rpn::push_int64(uint64_t i_uint) -{ - uint32_t rpn_id = iv_symbols->find_numeric_lit(i_uint,8); - iv_rpnstack.push_back(rpn_id); -} - -//------------------------------------------------------------------------------------------------- - -void Rpn::push_id(std::string & i_id, TYPE i_type) -{ - uint32_t rpn_id = 0; - std::string s(i_id); - - for (std::string::iterator c = s.begin(); c != s.end(); ++c) - { - *c = toupper(*c); - } - - rpn_id = iv_symbols->use_symbol(s); - - iv_rpnstack.push_back(rpn_id); - - //If this is an associated target's attribute, - //Add the target number as a numerical literal - size_t pos = s.find(ASSOC_TGT_ATTR); - if (pos != string::npos) - { - size_t len = ASSOC_TGT_ATTR.length(); - pos = s.find('.'); - if ((pos != string::npos) && (pos > len)) - { - uint32_t targetNum = strtoul(s.substr(len, pos-len).c_str(), NULL, 0); - //printf("Rpn::push_id: Target# %u\n", targetNum); - push_int(targetNum); - } - else - { - std::ostringstream oss; - oss << "Rpn::push_id: Invalid associated target attribute " << i_id.c_str(); - yyerror(oss.str().c_str()); - } - } -} - -//------------------------------------------------------------------------------------------------- - -void Rpn::push_array_index(std::string &i_array_idx) -{ - string l_idx = i_array_idx; - // strip of leading "[" and last "]" - l_idx = l_idx.substr(1,(l_idx.length() - 2)); - uint32_t l_num_idx = 0; - std::vector<string> l_idxstr; - - // find index strings in comma separated list and save in vector - size_t l_pos = 0; - l_pos = l_idx.find(','); - while(l_pos != string::npos) - { - l_idxstr.push_back(l_idx.substr(0, l_pos)); - l_idx = l_idx.substr(l_pos+1); - l_pos = l_idx.find(','); - } - - // Push back the original idx string or the last string in the list - l_idxstr.push_back(l_idx); - - uint32_t l_array_val = 0, l_array_val2 = 0; - uint32_t rpn_id = 0; - for (size_t i = 0; i < l_idxstr.size(); i++) - { - //Is it a range? - l_pos = l_idxstr.at(i).find(".."); - if (l_pos != string::npos) - { - l_array_val = atoi(l_idxstr.at(i).substr(0,l_pos).c_str()); - l_array_val2 = atoi(l_idxstr.at(i).substr(l_pos + 2).c_str()); - //printf("I>Rpn::push_array_index: %u..%u\n", l_array_val, l_array_val2); - if (l_array_val >= l_array_val2) - { - std::ostringstream oss; - oss << "Rpn::push_array_index: Invalid attribute array index range: " - << l_idxstr.at(i); - yyerror(oss.str().c_str()); - } - - for (uint32_t val = l_array_val; val <= l_array_val2; val++) - { - l_num_idx++; - rpn_id = iv_symbols->find_numeric_array_lit(val,4); - iv_rpnstack.push_back(rpn_id); - //printf("Array Index: %u rpn_id:0x%8X\n", val, rpn_id); - } - } - else - { - l_num_idx++; - l_array_val = atoi(l_idxstr.at(i).c_str()); - rpn_id = iv_symbols->find_numeric_array_lit(l_array_val,4); - iv_rpnstack.push_back(rpn_id); - - //printf("Array Index: %s decimal:%u rpn_id:0x%8X\n",l_idxstr.at(i).c_str(),l_array_val,rpn_id); - } - } - - // Save the index range for this rpn - if (iv_array_idx_range.size()) - { - if (iv_array_idx_range.back() != l_num_idx) - { - std::ostringstream oss; - oss << "Rpn::push_array_index: Array attribute has different range of index " - << "for each dimension: " << i_array_idx << " iv_array_idx_range: " - << iv_array_idx_range.back() << " l_num_idx: " << l_num_idx; - yyerror(oss.str().c_str()); - } - } - else - { - iv_array_idx_range.push_back(l_num_idx); - } - - //printf("Rpn::push_array_index: %s, iv_array_idx_range.size %u\n", i_array_idx.c_str(), iv_array_idx_range.size()); -} - -//------------------------------------------------------------------------------------------------- - -bool Rpn::isTrue() const //dg003a -{ - if((iv_rpnstack.size() == 1) && (iv_rpnstack[0] == (TRUE_OP | OPERATION))) return true; - return false; -} - -//------------------------------------------------------------------------------------------------- - -bool Rpn::isFalse() const //dg003a -{ - if((iv_rpnstack.size() == 1) && (iv_rpnstack[0] == (FALSE_OP | OPERATION))) return true; - return false; -} - -//------------------------------------------------------------------------------------------------- - -Rpn * Rpn::push_op(IfRpnOp op) -{ - uint32_t v = op; - if(op == LIST) // calculate list size - { - uint32_t count = 0; - for(RPNSTACK::const_reverse_iterator r = iv_rpnstack.rbegin(); r != iv_rpnstack.rend(); ++r) - { - if(((*r) & TYPE_MASK) == OPERATION) break; - ++count; - } - v |= (count << 8); - } - iv_rpnstack.push_back(v | OPERATION); - - return this; -} - -//------------------------------------------------------------------------------------------------- -// @post i_rpn is deleted - -Rpn * Rpn::push_merge(Rpn * i_rpn, IfRpnOp op) -{ - //dg003a begin - Rpn * result = this; - - // oportunity for Rpn optimization - // rpn && true, -> rpn - // rpn && false, -> false - // rpn || false, -> rpn - // rpn || true, -> true - if(op == AND) - { - if(i_rpn->isTrue()) - { - delete i_rpn; - return result; // leave this RPN alone - } - if(this->isTrue()) - { - iv_rpnstack.clear(); - iv_array_idx_range.clear(); - return merge(i_rpn); // merge deletes i_rpn - } - if(i_rpn->isFalse() || this->isFalse()) - { - iv_rpnstack.clear(); - iv_array_idx_range.clear(); - delete i_rpn; - push_op(FALSE_OP); - return result; - } - } - else if(op == OR) - { - if(i_rpn->isFalse()) - { - delete i_rpn; - return result; - } - if(this->isFalse()) - { - iv_rpnstack.clear(); - iv_array_idx_range.clear(); - return merge(i_rpn); // merge deletes i_rpn - } - if(i_rpn->isTrue() || this->isTrue()) - { - iv_rpnstack.clear(); - iv_array_idx_range.clear(); - delete i_rpn; - push_op(TRUE_OP); - return result; - } - } - - // Filter out SERIES calculations since this is for SERIES_IP only - // There might be a better place/way to do this?? - // TODO - No idea what this is really -#if 0 - Rpn r1("SERIES",iv_symbols); - Rpn r2("SERIES_IP",iv_symbols); - Rpn r3("SERIES_Z",iv_symbols); - if( *this == r1) - { - if((op == EQ && *i_rpn == r2) || (op == NE && *i_rpn == r3)) - { - iv_rpnstack.clear(); - iv_array_idx_range.clear(); - push_op(TRUE_OP); - delete i_rpn; - return result; - } - if((op == EQ && *i_rpn == r3) || (op == NE && *i_rpn == r2)) - { - iv_rpnstack.clear(); - iv_array_idx_range.clear(); - push_op(FALSE_OP); - delete i_rpn; - return result; - } - } -#endif - // These two expressions are seen as a result of macro expansion - // Reduce (expr1 == expr2) == 0 -> expr1 != expr2 - // Reduce (expr1 == expr2) == 1 -> expr1 == expr2 - // Reduce for any logic operation - if(op == EQ) - { - Rpn r_zero((uint32_t)0,iv_symbols); - Rpn r_one((uint32_t)1, iv_symbols); - - if ((*i_rpn) == r_zero) - { - if((*this) == r_zero) - { - delete i_rpn; - iv_rpnstack.pop_back(); - push_op(TRUE_OP); - return result; - } - if((*this) == r_one) - { - delete i_rpn; - iv_rpnstack.pop_back(); - push_op(FALSE_OP); - return result; - } - // else check for logical op - switch (iv_rpnstack.back()) - { - case (AND | OPERATION): - case (OR | OPERATION): - push_op(NOT); - delete i_rpn; - return result; - - case (NOT | OPERATION): // untie the NOT - iv_rpnstack.pop_back(); - delete i_rpn; - return result; - - case (EQ | OPERATION): - iv_rpnstack.back() = (NE | OPERATION); - delete i_rpn; - return result; - - case (NE | OPERATION): - iv_rpnstack.back() = (EQ | OPERATION); - delete i_rpn; - return result; - - case (GT | OPERATION): - iv_rpnstack.back() = (LE | OPERATION); - delete i_rpn; - return result; - - case (GE | OPERATION): - iv_rpnstack.back() = (LT | OPERATION); - delete i_rpn; - return result; - - case (LT | OPERATION): - iv_rpnstack.back() = (GE | OPERATION); - delete i_rpn; - return result; - - case (LE | OPERATION): - iv_rpnstack.back() = (GT | OPERATION); - delete i_rpn; - return result; - - case (TRUE_OP | OPERATION): - iv_rpnstack.back() = (FALSE_OP | OPERATION); - delete i_rpn; - return result; - - case (FALSE_OP | OPERATION): - iv_rpnstack.back() = (TRUE_OP | OPERATION); - delete i_rpn; - return result; - - default: // Not a logic operation - leave it alone - break; - } - } - else if((*i_rpn) == r_one) - { - if((*this) == r_one) - { - delete i_rpn; - iv_rpnstack.pop_back(); - push_op(TRUE_OP); - return result; - } - if((*this) == r_zero) - { - delete i_rpn; - iv_rpnstack.pop_back(); - push_op(FALSE_OP); - return result; - } - // else check for logical op - leave it as is - uint32_t l_op = iv_rpnstack.back(); - if((l_op == (AND | OPERATION)) || - (l_op == (OR | OPERATION)) || - (l_op == (NOT | OPERATION)) || - (l_op == (EQ | OPERATION)) || - (l_op == (NE | OPERATION)) || - (l_op == (GT | OPERATION)) || - (l_op == (GE | OPERATION)) || - (l_op == (LT | OPERATION)) || - (l_op == (LE | OPERATION)) || - (l_op == (TRUE_OP | OPERATION)) || - (l_op == (FALSE_OP | OPERATION))) - { - delete i_rpn; - return result; - } - } - } - - // other stuff i've seen TODO - // (0 == 1) == 1 , reduced already to (0 == 1) used to turn off a row - Could eliminate the row? - // - - - //dg003a end - - iv_rpnstack.insert(iv_rpnstack.end(), i_rpn->iv_rpnstack.begin(), i_rpn->iv_rpnstack.end()); - for (size_t i = 0; i < i_rpn->iv_array_idx_range.size(); i++) - { - iv_array_idx_range.push_back(i_rpn->iv_array_idx_range.at(i)); - } - result = push_op(op); - - delete i_rpn; - return result; -} - -//------------------------------------------------------------------------------------------------- -// @post i_rpn is deleted - -Rpn * Rpn::merge(Rpn * i_rpn) -{ - iv_rpnstack.insert(iv_rpnstack.end(), i_rpn->iv_rpnstack.begin(), i_rpn->iv_rpnstack.end()); - for (size_t i = 0; i < i_rpn->iv_array_idx_range.size(); i++) - { - iv_array_idx_range.push_back(i_rpn->iv_array_idx_range.at(i)); - } - delete i_rpn; - return this; -} - -//------------------------------------------------------------------------------------------------- -// See header file for contract -void Rpn::bin_read(BINSEQ::const_iterator & bli, uint16_t i_size, Symbols * symbols) -{ - - if(symbols) iv_symbols = symbols; - iv_rpnstack.clear(); - iv_array_idx_range.clear(); - - while(i_size) - { - uint32_t v = *bli++; - --i_size; - if(v < LAST_OP) // operator - { - if(v == LIST) - { - --i_size; - v |= (*bli++) << 8; - } - iv_rpnstack.push_back(v | OPERATION); - } - else // tag - { - v = (v << 8) + (*bli++); - --i_size; - - uint32_t l_rpn_id = iv_symbols->get_rpn_id(v); - iv_rpnstack.push_back(l_rpn_id); - - //Check for attribute of array type - if (v & IF_ATTR_TYPE) - { - //Check for associated target attribute - if ((v & IF_TYPE_MASK) == IF_ASSOC_TGT_ATTR_TYPE) - { - v = *bli++; - v = (v << 8) + (*bli++); - i_size -= 2; - iv_rpnstack.push_back(iv_symbols->get_rpn_id(v)); - //printf("Rpn::bin_read: Assoc target attribute id 0x%x\n", v); - } - - //Get the attribute dimension & shift it to the LS nibble - uint32_t l_type = iv_symbols->get_attr_type(l_rpn_id); - uint8_t l_attrDimension = (static_cast<uint8_t>(l_type) & ATTR_DIMENSION_MASK) >> 4; - for(uint8_t i=0; i < l_attrDimension; i++) - { - v = *bli++; - v = (v << 8) + (*bli++); - iv_rpnstack.push_back(iv_symbols->get_rpn_id(v)); - i_size -= 2; - } - } - } - } -} - -//------------------------------------------------------------------------------------------------- -BINSEQ::const_iterator Rpn::bin_read_one_op(BINSEQ::const_iterator & bli, Symbols * symbols) -{ - if(symbols) iv_symbols = symbols; - while(true) - { - uint32_t v = *bli++; - if(v < LAST_OP) // operator - { - if(v == LIST) // list has a size and another OP associated with it. - { - v |= (*bli++) << 8; // merge size into LIST op - iv_rpnstack.push_back(v | OPERATION); - v = *bli++; // get the list operation (EQ or NE) - } - iv_rpnstack.push_back(v | OPERATION); - // we are done - break; - } - // not op - always two bytes - v = (v << 8) + (*bli++); - iv_rpnstack.push_back(iv_symbols->get_rpn_id(v)); - } - return bli; -} - -//------------------------------------------------------------------------------------------------- -void Rpn::bin_read_one_id(BINSEQ::const_iterator & io_bli, Symbols * i_symbols) -{ - if(i_symbols) iv_symbols = i_symbols; - - uint32_t v = *io_bli++; - if(v < LAST_OP) // operator - { - std::ostringstream errss; - errss << "Rpn::bin_read_one_id: This is an op 0x" << hex << v << endl; - throw std::invalid_argument(errss.str()); - } - - // not op - always two bytes - v = (v << 8) + (*io_bli++); - - uint32_t l_rpn_id = iv_symbols->get_rpn_id(v); - iv_rpnstack.push_back(l_rpn_id); - - //Check for attribute of array type - if (v & IF_ATTR_TYPE) - { - //Check for associated target attribute - if ((v & IF_TYPE_MASK) == IF_ASSOC_TGT_ATTR_TYPE) - { - v = *io_bli++; - v = (v << 8) + (*io_bli++); - iv_rpnstack.push_back(iv_symbols->get_rpn_id(v)); - //printf("Rpn::bin_read_one_id: Assoc target attribute id 0x%x\n", v); - } - - //Get the attribute dimension & shift it to the LS nibble - uint32_t l_type = iv_symbols->get_attr_type(l_rpn_id); - uint8_t l_attrDimension = (static_cast<uint8_t>(l_type) & ATTR_DIMENSION_MASK) >> 4; - for(uint8_t i=0; i < l_attrDimension; i++) - { - v = *io_bli++; - v = (v << 8) + (*io_bli++); - iv_rpnstack.push_back(iv_symbols->get_rpn_id(v)); - } - } -} - -//------------------------------------------------------------------------------------------------- - -void Rpn::append(const Rpn & i_rpn) -{ - iv_rpnstack.insert(iv_rpnstack.end(), i_rpn.iv_rpnstack.begin(), i_rpn.iv_rpnstack.end()); - for (size_t i = 0; i < i_rpn.iv_array_idx_range.size(); i++) - { - iv_array_idx_range.push_back(i_rpn.iv_array_idx_range.at(i)); - } -} - -//------------------------------------------------------------------------------------------------- - -std::string Rpn::symbol_names() const -{ - std::string result; - for(RPNSTACK::const_iterator i = iv_rpnstack.begin(); i != iv_rpnstack.end(); ++i) - { - if((*i) & SYMBOL) - { - if(result.size()) result.append(" "); // space or lf?? - result.append(iv_symbols->find_name(*i)); - } - } - return result; -} - -//------------------------------------------------------------------------------------------------- - -std::string Rpn::listing(const char * i_desc, const std::string & spyname, bool i_final) -{ - std::ostringstream odesc; - std::ostringstream oss; - uint32_t rpn_byte_size = 0; - - - oss << std::hex << std::setfill('0'); - - //oss << "0x" << std::setw(2) << iv_rpnstack.size() << '\t' << i_desc << std::endl; - for(RPNSTACK::iterator i = iv_rpnstack.begin(); i != iv_rpnstack.end(); ++i) - { - if( (*i) & OPERATION ) // operator - { - ++rpn_byte_size; - uint32_t op_id = (*i) - OPERATION; - uint32_t count = op_id >> 8; // NOTE: only the LIST operator has a count - op_id &= OP_MASK; - - if(op_id < LAST_OP) - { - oss << "0x" << std::setw(2) << op_id << "\t\t" << OP_TXT[op_id] << std::endl; - if(op_id == LIST) - { - ++rpn_byte_size; - oss << "0x" << std::setw(2) << count << "\t\t" - << std::dec << count << std::hex << std::endl; - } - } - else - { - oss << "0x" << op_id << "\t\t" << "INVALID OPERATION" << std::endl; - } - } - else if((*i) & NUMBER) - { - uint32_t size = 0; - uint64_t data = iv_symbols->get_numeric_data(*i,size); - if(i_final) - { - uint32_t tag = iv_symbols->get_numeric_tag(*i); - rpn_byte_size += 2; - oss << "0x" << std::setw(4) << tag << "\t\t" << "PUSH 0x" - << std::setw(size*2) << data << std::endl; - } - else - { - rpn_byte_size += size; - oss << "0x" << std::setw(size * 2) << data << '\t' << "Numerical Literal" << std::endl; - } - } - else if((*i) & ARRAY_INDEX) - { - uint32_t size = 0; - uint64_t data = iv_symbols->get_numeric_array_data(*i,size); - if(i_final) - { - uint32_t tag = iv_symbols->get_numeric_array_tag(*i); - rpn_byte_size += 2; - oss << "0x" << std::setw(4) << tag << "\t\t" << "PUSH 0x" - << std::setw(size*2) << data << std::endl; - } - else - { - rpn_byte_size += size; - oss << "0x" << std::setw(size * 2) << data << '\t' << "Numerical Literal (array index)" << std::endl; - } - } - else if((*i) & SYMBOL) - { - std::string name = iv_symbols->find_name(*i); - - if(i_final) - { - uint32_t val = iv_symbols->get_tag(*i); - - if (val & IF_ATTR_TYPE) - { - rpn_byte_size += 2; - oss << "0x" << std::setw(4) << val << "\t\t" << "PUSH " << name << std::endl; - } - else - { - rpn_byte_size +=4; - oss << "0x" << std::setw(8) << val << '\t' << name << "\tUnresolved!" << std::endl; - } - } - else // debug listing - { - rpn_byte_size +=2; - //oss << "0x" << std::setw(8) << *i << '\t' - oss << "\t\t" << "PUSH " << name << std::endl; - - } - } - else - { - oss << "0x" << std::setw(8) << *i << '\t' << "Unknown RPN id" << std::endl; - } - } - - //Skip size and desc for empty desc string and SYMBOL literal - if(i_desc && (0 == strlen(i_desc)) && (iv_rpnstack.front() & SYMBOL)) - { - odesc << oss.str(); - } - else - { - odesc << std::hex << std::setfill('0') - << "0x" << std::setw(4) << rpn_byte_size << "\t\t"; - if(i_desc) odesc << i_desc; - else odesc << std::dec << rpn_byte_size << " BYTES"; - odesc << std::endl; - odesc << oss.str(); - } - - return odesc.str(); -} - -//------------------------------------------------------------------------------------------------- - -// binary version to write to file -void Rpn::bin_str(BINSEQ & o_blist, uint32_t i_num_addrs, uint32_t i_addr_num, - bool i_prepend_count, bool i_one_byte_count) -{ - BINSEQ blist; - uint32_t count = 0; - uint32_t l_num_idx = 0; //number of array index in the range - uint32_t l_num_array_attrs = 0; - - for(RPNSTACK::iterator i = iv_rpnstack.begin(); i != iv_rpnstack.end(); ++i) - { - uint32_t v = *i; - uint32_t type = v & TYPE_MASK; - uint16_t tag; - - switch (type) - { - case OPERATION: blist.push_back((uint8_t)v); - ++count; - if((v & OP_MASK) == LIST) - { - ++count; - blist.push_back((uint8_t)(v >> 8)); - } - l_num_idx = 0; //reset - break; - - case SYMBOL: tag = iv_symbols->get_tag(v); - blist.push_back((uint8_t)(tag >> 8)); - blist.push_back((uint8_t) tag); - count += 2; - l_num_idx = 0; //reset - break; - - case NUMBER: tag = iv_symbols->get_numeric_tag(v); - blist.push_back((uint8_t)(tag >> 8)); - blist.push_back((uint8_t) tag); - count += 2; - l_num_idx = 0; //reset - break; - case ARRAY_INDEX: - //Check if this rpn has any array attribute with a range of index specified - if ((0 == l_num_idx) && iv_array_idx_range.size()) - { - if (iv_array_idx_range.size() > l_num_array_attrs) - { - l_num_idx = iv_array_idx_range.at(l_num_array_attrs); - l_num_array_attrs++; - - //Error if index range is not equal to address range - if ((1 < l_num_idx) && (l_num_idx != i_num_addrs)) - { - std::ostringstream errss; - errss << "Rpn::bin_str: Index range " << l_num_idx - << " != Address range " << i_num_addrs << endl; - throw std::invalid_argument(errss.str()); - } - } - } - - if (0 == l_num_idx) - { - //Error if no index range specified - std::ostringstream errss; - errss << "Rpn::bin_str: No index range specified for array attribute\n"; - throw std::invalid_argument(errss.str()); - } - - if (1 < l_num_idx) - { - v = *(i + i_addr_num); - if ((v & TYPE_MASK) != ARRAY_INDEX) - { - std::ostringstream errss; - errss << "Rpn::bin_str: Rpn 0x" << hex << v - << " is not array index " << endl; - throw std::invalid_argument(errss.str()); - } - } - tag = iv_symbols->get_numeric_array_tag(v); - blist.push_back((uint8_t)(tag >> 8)); - blist.push_back((uint8_t) tag); - count += 2; - if (1 < l_num_idx) //Skip the other indexes in the range - { - i += l_num_idx - 1; - } - break; - - default: - std::ostringstream errss; - errss << "Rpn::bin_str: Invalid Rpn type: 0x" << hex << v << endl; - throw std::invalid_argument(errss.str()); - break; - } - } - - //std::cout << "Rpn::bit_str(): iv_rpnstack size: " << iv_rpnstack.size() << std::endl; - //std::cout << " Rpn::bit_str(): rpn byte count: " << count << std::endl; - if (i_prepend_count) - { - if (true == i_one_byte_count) - { - //Expect count <= 255 - if (0xFF < count) - { - std::ostringstream errss; - errss << "Rpn::bin_str: count " << count << " > 0xFF\n"; - throw std::invalid_argument(errss.str()); - } - - o_blist.push_back((uint8_t) count); - } - else - { - //Expect count <= 65535 - if (0xFFFF < count) - { - std::ostringstream errss; - errss << "Rpn::bin_str: count " << count << " > 0xFFFF\n"; - throw std::invalid_argument(errss.str()); - } - - o_blist.push_back((uint8_t)(count >> 8)); - o_blist.push_back((uint8_t) count); - } - } - - o_blist.insert(o_blist.end(), blist.begin(), blist.end()); -} - -//------------------------------------------------------------------------------------------------- -// Used for RPN filtering (resolve()) -void Rpn::pop_bool(EVAL_STACK & i_stack, RPN_VALUE & o_value) //dg002a -{ - // convert numbers or any to bool - if(i_stack.size()) - { - o_value = i_stack.back(); - i_stack.pop_back(); - if(o_value.type == RPN_NUMBER) - { - if(o_value.data == 0) o_value.type = RPN_FALSE; - else - { - o_value.type = RPN_TRUE; - if(o_value.data != 1) - { - cerr << "Was expecting a bool, got a number - assume true" << endl; - } - } - } - else if(o_value.type == RPN_ANY) o_value.type = RPN_TRUE; - // else already a bool - } - else - { - o_value.type = RPN_TRUE; - cerr << "Empty stack!" << endl; - } -} -//------------------------------------------------------------------------------------------------- - -void Rpn::pop_number(EVAL_STACK & i_stack, RPN_VALUE & o_value) //dg002a -{ - // Convert bools to ANY if a number is expected (eg true == 1) - if(i_stack.size()) - { - o_value = i_stack.back(); - i_stack.pop_back(); - //if(o_value.type != RPN_NUMBER && o_value.type != RPN_ANY) - //{ - // if(o_value.type == RPN_FALSE) o_value.data = 0; - // else if(o_value.type == RPN_TRUE) o_value.data = 1; - // //o_value.type = RPN_NUMBER; // not safe when just checking EC - // o_value.type = RPN_ANY; - //} - // else leave as is - } - else - { - o_value.type = RPN_ANY; - cerr << "Empty stack!" << endl; - } -} - -//------------------------------------------------------------------------------------------------- - -bool Rpn::resolve_ec(uint32_t i_ec) //dg002a -{ - SYMBOL_VAL_LIST v; - SYMBOL_VAL_PAIR p(string("EC"),i_ec); - v.push_back(p); - - //SYMBOL_VAL_PAIR p1(string("SERIES"),0xA000006C); - //SYMBOL_VAL_PAIR p2(string("SERIES_IP"),0xA000006C); - //SYMBOL_VAL_PAIR p3(string("SERIES_Z"),0xA000006D); - //v.push_back(p1); - //v.push_back(p2); - //v.push_back(p3); - - return resolve(v); -} - -//------------------------------------------------------------------------------------------------- -// Tries to resolve as much of the RPN as possible -// @return false means that based on the given varlist, the RPN will never evaluate to true. -// eg. unconditionally false -// true means RPN either evaluated to true or there is not enough information to evaluate the RPN -// @note SPY RPNs are not supported -// -bool Rpn::resolve(SYMBOL_VAL_LIST & i_varlist) -{ - - bool result = true; - - EVAL_STACK stack; - RPN_VALUE rpn_true(RPN_TRUE); - RPN_VALUE rpn_false(RPN_FALSE); - RPN_VALUE r1; - RPN_VALUE r2; - - for(RPNSTACK::const_iterator i = iv_rpnstack.begin(); i != iv_rpnstack.end(); ++i) - { - if( (*i) & OPERATION ) - { - uint32_t op = (*i) - OPERATION; - uint32_t count = op >> 8; - op &= OP_MASK; - - switch(op) - { - case AND: - pop_bool(stack,r1); - pop_bool(stack,r2); - if(r1.type == RPN_TRUE && r2.type == RPN_TRUE) stack.push_back(rpn_true); - else stack.push_back(rpn_false); - break; - - case OR: - pop_bool(stack,r1); - pop_bool(stack,r2); - if(r1.type == RPN_TRUE || r2.type == RPN_TRUE) stack.push_back(rpn_true); - else stack.push_back(rpn_false); - break; - - case NOT: - pop_bool(stack,r1); - if(r1.type == RPN_TRUE) stack.push_back(rpn_false); - else if(r1.type == RPN_FALSE) stack.push_back(rpn_true); - break; - - case EQ: - pop_number(stack,r1); - pop_number(stack,r2); - if(r1.type == RPN_ANY || r2.type == RPN_ANY) stack.push_back(rpn_true); - else if(r1.type == RPN_NUMBER && r2.type == RPN_NUMBER) - { - if(r1.data == r2.data) stack.push_back(rpn_true); - else stack.push_back(rpn_false); - } - else if(r1.type == RPN_TRUE && r2.type == RPN_NUMBER) - { - if(r2.data == 0) stack.push_back(rpn_false); - else stack.push_back(rpn_true); - } - else if(r2.type == RPN_TRUE && r1.type == RPN_NUMBER) - { - if(r1.data == 0) stack.push_back(rpn_false); - else stack.push_back(rpn_true); - } - else if(r1.type == RPN_FALSE && r2.type == RPN_NUMBER) - { - if(r2.data == 0) stack.push_back(rpn_true); - else stack.push_back(rpn_false); - } - else if(r2.type == RPN_FALSE && r1.type == RPN_NUMBER) - { - if(r1.data == 0) stack.push_back(rpn_true); - else stack.push_back(rpn_false); - } - else if((r1.type == RPN_TRUE && r2.type == RPN_FALSE) || - (r1.type == RPN_FALSE && r2.type == RPN_TRUE)) stack.push_back(rpn_false); - else stack.push_back(rpn_true); - break; - - case NE: - pop_number(stack,r1); - pop_number(stack,r2); - if(r1.type == RPN_ANY || r2.type == RPN_ANY) stack.push_back(rpn_true); - else - { - if(r1.data != r2.data) stack.push_back(rpn_true); - else stack.push_back(rpn_false); - } - break; - - case GT: - pop_number(stack,r1); - pop_number(stack,r2); - if(r1.type == RPN_ANY || r2.type == RPN_ANY) stack.push_back(rpn_true); - else - { - if(r2.data > r1.data) stack.push_back(rpn_true); - else stack.push_back(rpn_false); - } - break; - - case GE: - pop_number(stack,r1); - pop_number(stack,r2); - if(r1.type == RPN_ANY || r2.type == RPN_ANY) stack.push_back(rpn_true); - else - { - if(r2.data >= r1.data) stack.push_back(rpn_true); - else stack.push_back(rpn_false); - } - break; - - case LT: - pop_number(stack,r1); - pop_number(stack,r2); - if(r1.type == RPN_ANY || r2.type == RPN_ANY) stack.push_back(rpn_true); - else - { - if(r2.data < r1.data) stack.push_back(rpn_true); - else stack.push_back(rpn_false); - } - break; - - case LE: - pop_number(stack,r1); - pop_number(stack,r2); - if(r1.type == RPN_ANY || r2.type == RPN_ANY) stack.push_back(rpn_true); - else - { - if(r2.data <= r1.data) stack.push_back(rpn_true); - else stack.push_back(rpn_false); - } - break; - - case PLUS: - r1 = stack.back(); stack.pop_back(); - r2 = stack.back(); stack.pop_back(); - if(r1.type == RPN_NUMBER && r2.type == RPN_NUMBER) - stack.push_back(RPN_VALUE(r1.data + r2.data,RPN_NUMBER)); - else cerr << "Was not expecting a non-numeric value for operator +" << endl; - break; - - case MINUS: - r1 = stack.back(); stack.pop_back(); - r2 = stack.back(); stack.pop_back(); - if(r1.type == RPN_NUMBER && r2.type == RPN_NUMBER) - stack.push_back(RPN_VALUE(r2.data - r1.data,RPN_NUMBER)); - else cerr << "Was not expecting a non-numeric value for operator -" << endl; - break; - - case MULT: - r1 = stack.back(); stack.pop_back(); - r2 = stack.back(); stack.pop_back(); - if(r1.type == RPN_NUMBER && r2.type == RPN_NUMBER) - stack.push_back(RPN_VALUE(r2.data * r1.data,RPN_NUMBER)); - else cerr << "Was not expecting a non-numeric value for operator *" << endl; - break; - - case DIVIDE: - r1 = stack.back(); stack.pop_back(); - r2 = stack.back(); stack.pop_back(); - if(r1.type == RPN_NUMBER && r2.type == RPN_NUMBER) - stack.push_back(RPN_VALUE(r2.data / r1.data,RPN_NUMBER)); - else cerr << "Was not expecting a non-numeric value for operator /" << endl; - break; - - case MOD: - r1 = stack.back(); stack.pop_back(); - r2 = stack.back(); stack.pop_back(); - if(r1.type == RPN_NUMBER && r2.type == RPN_NUMBER) - stack.push_back(RPN_VALUE(r2.data % r1.data,RPN_NUMBER)); - else cerr << "Was not expecting a non-numeric value for operator %" << endl; - break; - - case LIST: // lists are always true - TODO look for EC list ?? - ++i; - while(count--) stack.pop_back(); - stack.push_back(rpn_true); - break; - - case SHIFTLEFT: - r1 = stack.back(); stack.pop_back(); - r2 = stack.back(); stack.pop_back(); - if(r1.type == RPN_NUMBER && r2.type == RPN_NUMBER) - stack.push_back(RPN_VALUE(r2.data << r1.data,RPN_NUMBER)); - else cerr << "Was not expecting a non-numeric value for operator <<" << endl; - break; - - case SHIFTRIGHT: - r1 = stack.back(); stack.pop_back(); - r2 = stack.back(); stack.pop_back(); - if(r1.type == RPN_NUMBER && r2.type == RPN_NUMBER) - stack.push_back(RPN_VALUE(r2.data >> r1.data,RPN_NUMBER)); - else cerr << "Was not expecting a non-numeric value for operator >>" << endl; - break; - - case TRUE_OP: //dg003a - stack.push_back(rpn_true); - break; - - case FALSE_OP: //dg003a - stack.push_back(rpn_false); - break; - - default: - cerr << "Invalid operator " << op << endl; - break; - } - } - else if((*i) & NUMBER) - { - uint32_t size = 0; - uint64_t data = iv_symbols->get_numeric_data(*i,size); - stack.push_back(RPN_VALUE(data,RPN_NUMBER)); - } - else if((*i) & SYMBOL) // variables and cini enums - { - std::string name = iv_symbols->find_name(*i); - SYMBOL_VAL_LIST::iterator vvi = i_varlist.begin(); - for(; vvi != i_varlist.end(); ++vvi) - { - if(name == vvi->first) - { - // cerr << name << " = " << vvi->second << endl; - stack.push_back(RPN_VALUE((uint64_t)vvi->second,RPN_NUMBER)); - break; - } - } - if(vvi == i_varlist.end()) - { - // cerr << name << " = ANY" << endl; - stack.push_back(RPN_VALUE(RPN_ANY)); - } - } - } - // an empty RPN is true, if it's not empty then check for false - if(stack.size()) - { - RPN_VALUE r = stack.back(); - if(r.type == RPN_FALSE) result = false; - } - return result; -} - -//------------------------------------------------------------------------------------------------- - -uint8_t Rpn::extract8(BINSEQ::const_iterator & bli) -{ - uint8_t val = 0; - val += (uint8_t)(*bli++); - return val; -} - - -//------------------------------------------------------------------------------------------------- - -uint16_t Rpn::extract16(BINSEQ::const_iterator & bli) -{ - uint16_t val = 0; - val = ((uint16_t)(*bli++)) << 8; - val += (uint16_t)(*bli++); - return val; -} - -//------------------------------------------------------------------------------------------------- - -uint32_t Rpn::extract32(BINSEQ::const_iterator & bli) -{ - uint32_t val = extract16(bli); - val <<= 16; - val += extract16(bli); - return val; -} - - -//------------------------------------------------------------------------------------------------- - -uint64_t Rpn::extract64(BINSEQ::const_iterator & bli) -{ - uint64_t val = extract32(bli); - val <<= 32; - val += extract32(bli); - return val; -} - -//------------------------------------------------------------------------------------------------- - -void Rpn::set8(BINSEQ & bl, uint8_t v) -{ - bl.push_back((uint8_t)(v)); -} - -//------------------------------------------------------------------------------------------------- - -void Rpn::set16(BINSEQ & bl, uint16_t v) -{ - bl.push_back((uint8_t)(v >> 8)); - bl.push_back((uint8_t)(v)); -} - -//------------------------------------------------------------------------------------------------- - -void Rpn::set32(BINSEQ & bl, uint32_t v) -{ - bl.push_back((uint8_t)(v >> 24)); - bl.push_back((uint8_t)(v >> 16)); - bl.push_back((uint8_t)(v >> 8)); - bl.push_back((uint8_t)(v)); -} - -//------------------------------------------------------------------------------------------------- - -void Rpn::set64(BINSEQ & bl, uint64_t v) -{ - bl.push_back((uint8_t)(v >> 56)); - bl.push_back((uint8_t)(v >> 48)); - bl.push_back((uint8_t)(v >> 40)); - bl.push_back((uint8_t)(v >> 32)); - bl.push_back((uint8_t)(v >> 24)); - bl.push_back((uint8_t)(v >> 16)); - bl.push_back((uint8_t)(v >> 8)); - bl.push_back((uint8_t)(v)); -} - - -//------------------------------------------------------------------------------------------------- - - diff --git a/src/usr/hwpf/ifcompiler/initRpn.H b/src/usr/hwpf/ifcompiler/initRpn.H deleted file mode 100755 index c63933a33..000000000 --- a/src/usr/hwpf/ifcompiler/initRpn.H +++ /dev/null @@ -1,329 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/hwpf/ifcompiler/initRpn.H $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2011,2014 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -#if !defined(INITRPN_H) -#define INITRPN_H - -// Change Log ************************************************************************************* -// -// Flag Reason Userid Date Description -// ---- -------- -------- -------- ------------------------------------------------------------- -// D754106 dgilbert 06/14/10 Create -// dgilbert 10/15/10 Add support to filter unneeded inits by EC -// dg002 SW039868 dgilbert 10/15/10 Add support to filter unneeded inits by EC -// dg003 SW047506 dgilbert 12/09/10 SERIES filtering -// andrewg 09/19/11 Updates based on review -// camvanng 11/08/11 Added support for attribute enums -// andrewg 11/09/11 Multi-dimensional array and move to common fapi include -// camvanng 01/20/12 Support for using a range of indexes for array attributes -// camvanng 05/22/12 Ability to do simple operations on attributes -// in the scom_data column -// SW146714 camvanng 06/08/12 Use two bytes to store row rpn sequence byte count -// camvanng 06/27/12 Delete push_attr_enum() -// End Change Log ********************************************************************************* -// $Id: initRpn.H,v 1.8 2014/06/30 19:56:53 thi Exp $ -/** - * @file initRpn.H - * @brief Declaration of the initRpn class. Handles Reverse Polish Notation equations for initfiles - */ - -#include <stdint.h> -#include <string> -#include <vector> -#include <map> -#include <fapiHwpInitFileInclude.H> - - -namespace init -{ - class Symbols; - - typedef std::vector<uint8_t> BINSEQ; - - typedef std::pair<std::string,uint32_t> SYMBOL_VAL_PAIR; - typedef std::vector<SYMBOL_VAL_PAIR> SYMBOL_VAL_LIST; - - class Rpn - { - public: - - enum TYPE - { - DEFINE = 0x08000000, - SYMBOL = 0x10000000, - NUMBER = 0x20000000, - ARRAY_INDEX = 0x40000000, - OPERATION = 0x80000000, - TYPE_MASK = 0xF8000000, - - }; - - /** - * @brief Create empty RPN - * - */ - Rpn() : iv_symbols(NULL) {} - - /** - * @brief Create empty RPN w/ symbol table - * - * @param[in] i_symbols Pointer to Symbol Table - */ - Rpn(Symbols * i_symbols) : iv_symbols(i_symbols) {} - - /** - * @brief Create empty RPN w/ symbol table and input integer - * - * @param[in] i_int Integer to populate RPN with - * @param[in] i_symbols Pointer to Symbol Table - */ - Rpn(uint32_t i_int, Symbols * i_symbols); - - Rpn(uint64_t i_int, Symbols * symbols); //<<< Create RPN with single 64 bit integer - Rpn(std::string i_id, Symbols * symbols, TYPE i_type=SYMBOL); //<<< Create RPN with single symbol - Rpn(BINSEQ::const_iterator & bli, Symbols * symbols) //<<< Create RPN from binary sequence - : iv_symbols(symbols) { bin_read(bli); } - - /** - * Compare two Rpn sequences for equivalence - * @note Currently the two Rpn sequences must use the same symbol table to be considered equal. - * @note TODO: Allow different symbol tables and resolve the symbols before comparing. - */ - bool operator==(const Rpn & r); - bool operator!=(const Rpn & r) { return !(this->operator==(r)); } - - void push_int(uint32_t i_val); //<<< Add a 32 bit integer to the Rpn sequence - void push_id(std::string & i_id, TYPE i_type=SYMBOL); //<<Add a symbol or Spy enum to the Rpn sequence - void push_int64(uint64_t i_uint); //<<< Add a 64 bit integer to the Rpn sequence - - /** - * @brief Add an attribute array index - * - * @param[in] i_array_idx Array index for this attribute - * - * @return Void - */ - void push_array_index(std::string &i_array_idx); - - Rpn * push_op(IfRpnOp op); //<<< Add an operation to the Rpn sequence - - /** - * @brief Merge an Rpn to this Rpn sequence with input operation - * - * @param[inout] io_rpn Input RPN to merge into this one. Will be deleted. - * @param[in] i_op Operation to perform between the 2 RPN's - * - * @return Merged RPN - */ - Rpn * push_merge(Rpn * io_rpn, IfRpnOp i_op); - - /** - * Merge (append) Rpn with this Rpn sequence - * @returns this - * @post i_rpn is deleted - */ - Rpn * merge(Rpn * i_rpn); - - /** - * Append a copy of an Rpn sequence to this Rpn sequence - */ - void append(const Rpn & i_rpn); - - void append(uint32_t i_rpn_id) { iv_rpnstack.push_back(i_rpn_id); } - - /** - * isTrue returns true if the RPN has a single element that is RPN_TRUE - * @note Used in RPN optimization - */ - bool isTrue() const; //dg003a - - /** - * isFalse returns true if the RPN has a single element that is RPN_FALSE - * @note Used in RPN optimization - */ - bool isFalse() const; //dg003a - - void clear() { iv_rpnstack.clear(); } //<<< clear the sequence - - /** - * Human readable listing of RPN string - * @param String Description to use; NULL -> use default: "n BYTES" - * @param bool i_final true: convert cini symbol id's to offset tags - * @returns string - * @NOTE i_final should never be set to true until all symbols in the - * init file have been "looked up" - */ - std::string listing(const char * i_desc, - const std::string & spyname = cv_empty_str, - bool i_final = false); - - std::string symbol_names() const; //<<< Return a string of all the SYMBOL names in the Rpn - - /** - * @brief Push all RPN stack entries of object as numerical values onto input blist - * - * @param blist Binary string of RPN to write to file - * @param i_num_addrs number of Scom addresses for this Scom - * @param i_addr_num the nth addr with the range of Scom addresses - * @param i_prepend_count Flag to indicate prepend rpn count to binary string - * @param i_one_byte_count Flag to indicate whether to use 1 byte to store - * the byte count (default is to use 2 bytes) when i_prepend_count == true - * @PRE should never be called until all symbols in the initfile have been - * "looked up" or the binary tags for Symbols and Numbers may not be accurate - * @return void - */ - void bin_str(BINSEQ & blist, uint32_t i_num_addrs, uint32_t i_addr_num, - bool i_prepend_count = false, bool i_one_byte_count = false); - - /** - * Read binary sequence to recreate this Rpn sequence - * @param binary sequence interator - * @param number of bytes to read - * @param symbol table to use - * @post this rpn sequence is appended - * @post if symbols != NULL then iv_symbols is replaced with symbols - */ - void bin_read(BINSEQ::const_iterator & bli, - uint16_t i_size = 2, - Symbols * symbols = NULL); // read binary sequence to recreate RPN - - /** - * Copy one rpn operation from bli and add to this Rpn sequence - * @returns an iterator one past the last byte used. - * @param iterator of a binary rpn sequence - * @param symbol table to use. - * @pre bli points to a valid rpn sequence - ie the correct number of PUSHES for the operand - * @post this Rpn sequence is appended - * @post Internal symbol table ptr is replace with given symbol table ptr if not NULL - * @note Reads byte sequence from bli sequence until an operation is found. - * @note The input sequence should NOT have a size byte on the front - */ - BINSEQ::const_iterator bin_read_one_op(BINSEQ::const_iterator & bli, Symbols * symbols = NULL); // read one rpn operation from bli to create Rpn - - /** - * Copy one numeric literal or attribute from io_bli and add to this Rpn sequence - * @param[in,out] io_bli iterator of a binary rpn sequence - * @param[in] i_symbols table to use. - * @pre io_bli points to a valid rpn sequence - * @post this Rpn sequence is appended - * @post Internal symbol table ptr is replaced with given symbol table ptr if not NULL - * @post iterator of binary sequence is one past the last byte used. - */ - void bin_read_one_id(BINSEQ::const_iterator & io_bli, Symbols * i_symbols = NULL); - - //dg002a - /** - * Resolve the RPN and returns false if the given EC level causes the RPN expression to be false. - * @returns true | false - * @note This routine will always return true unless the RPN contains an EC comparison that resolves to false. - */ - bool resolve_ec(uint32_t i_ec); - - //dg003a - /** - * Resove as much of the RPN as possible, given the list of Symbol -> value substitutions. Result is true until proven false. - * @returns true | false. False is returned if the Rpn is unconditionally false; otherwise true is returned. - * @note Any Symbol found in the RPN not included in i_varlist resolves to ANY. All comparison operands to ANY resolves to true - * @code - * // Example 1 - * SYMBOL_VAL_PAIR p(string("EC"),0x10); - * SYMBOL_VAL_LIST lst; - * lst.push_back(p); - * if(anRpn.resolve(lst)) { .... } - * // In this example, any instants of the variable "EC" in the RPN will be replaced with the value 0x10. - * // Any other variables will be set to ANY and the RPN will be evaluated. - * // if the RPN does not contain the variable "EC", it will resolve to true. - * - * // Example 2 - * SYMBOL_VAL_PAIR p1(string("SERIES"),0xA000006C); - * SYMBOL_VAL_PAIR p2(string("SERIES_IP"),0xA000006C); - * SYMBOL_VAL_PAIR p3(string("SERIES_Z"),0xA000006D); - * SYMBOL_VAL_LIST lst; - * lst.push_back(p1); - * lst.push_back(p2); - * lst.push_back(p3); - * if(anRpn.resolve(lst)) {.....} // resolves to false if rpn contains SERIES == SERIES_Z - * // or SERIES != SERIES_IP - * @endcode - */ - bool resolve(SYMBOL_VAL_LIST & i_varlist); - - - uint32_t op_count() const { return iv_rpnstack.size(); } - - // Helper functions in reading and writing binary sequences (compiled initfiles *.if) - static uint8_t extract8(BINSEQ::const_iterator & bli); - static uint16_t extract16(BINSEQ::const_iterator & bli); - static uint32_t extract32(BINSEQ::const_iterator & bli); - static uint64_t extract64(BINSEQ::const_iterator & bli); - static void set8(BINSEQ & bl, uint8_t v); - static void set16(BINSEQ & bl, uint16_t v); - static void set32(BINSEQ & bl, uint32_t v); - static void set64(BINSEQ & bl, uint64_t v); - - static std::string cv_empty_str; - - private: // types and data - typedef std::vector<uint32_t> RPNSTACK; - typedef std::vector<uint32_t> INDEXRANGE; - - RPNSTACK iv_rpnstack; ///< Rpn sequence - Symbols * iv_symbols; ///< Symbol table to use - INDEXRANGE iv_array_idx_range; ///< indicates range of indexes for an array attribute - - - - - //dg002a begin Used in resolve operations to interpret the Rpn sequence - enum RPN_TYPE - { - RPN_NUMBER = 0, - RPN_FALSE = 1, - RPN_TRUE = 2, - RPN_ANY = 3, - }; - - // Used in resolve operations to interpret the Rpn sequence - struct RPN_VALUE - { - uint64_t data; - RPN_TYPE type; - RPN_VALUE() : data(0), type(RPN_NUMBER) {} - RPN_VALUE(RPN_TYPE i_type) : data(0), type(i_type) {} - RPN_VALUE(uint64_t i_data, RPN_TYPE i_type) : data(i_data), type(i_type) {} - RPN_VALUE(uint64_t i_data) : data(i_data), type(RPN_NUMBER) {} - }; - - typedef std::vector<RPN_VALUE> EVAL_STACK; - - private: // functions - - // Used in resolve operations to interpret the Rpn sequence - static void pop_bool(EVAL_STACK & i_stack, RPN_VALUE & o_value); - static void pop_number(EVAL_STACK & i_stack, RPN_VALUE & o_value); - // dg002a end - }; -}; - -#endif diff --git a/src/usr/hwpf/ifcompiler/initScom.C b/src/usr/hwpf/ifcompiler/initScom.C deleted file mode 100755 index 35b93812c..000000000 --- a/src/usr/hwpf/ifcompiler/initScom.C +++ /dev/null @@ -1,1778 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/hwpf/ifcompiler/initScom.C $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2011,2014 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -// Change Log ************************************************************************************* -// -// Flag Track Userid Date Description -// ----- -------- -------- -------- ------------------------------------------------------------- -// D754106 dgilbert 06/14/10 Create -// dg001 D774126 dgilbert 09/30/10 Check that colname EXPR is last column in spytable -// dg002 SW039868 dgilbert 10/15/10 Add support to filter unneeded inits by EC -// dg003 SW047506 dgilbert 12/09/10 More filtering enhancements -// andrewg 05/24/11 Port over for VPL/PgP -// andrewg 09/19/11 Updates based on review -// andrewg 11/09/11 Multi-dimensional array and move to common fapi include -// mjjones 11/17/11 Output attribute listing -// camvanng 12/12/11 Support multiple address ranges within a SCOM address -// Use strtoull vs strtoul for 32-bit platforms -// camvanng 12/15/11 Support for multiple duplicate addresses setting different bits -// camvanng 01/20/12 Support for using a range of indexes for array attributes -// camvanng 02/14/12 Support binary and hex scom addresses -// Support for array at beginning of scom address -// Fix bug in string size when converting decimal to hex string -// camvanng 05/07/12 Support for associated target attributes -// camvanng 05/22/12 Ability to do simple operations on attributes -// in the scom_data column -// SW146714 camvanng 06/08/12 Use two bytes to store row rpn sequence byte count -// Handle case where after row_optimize(), there's no Scom to write -// camvanng 06/27/12 Improve error and debug tracing -// End Change Log ********************************************************************************* -// $Id: initScom.C,v 1.11 2014/06/30 20:20:00 thi Exp $ -/** - * @file initSpy.C - * @brief Definition of the initScom Class. Represents the information parsed from an initfile scom - * statement. - */ - -#include <initScom.H> -#include <initSymbols.H> -#include <initCompiler.H> -#include <stdlib.h> -#include <iostream> -#include <iomanip> -#include <sstream> -#include <fstream> -#include <set> -#include <stdexcept> - -extern void yyerror(const char * s); -extern init::ScomList * yyscomlist; // only use this during parsing -std::map<string,string> yytarget; //generic target name & corresponding real name - -namespace init { -extern ostringstream dbg; // debug output -}; - -using namespace init; - -Scom::WHEN_SUBTYPE_MAP Scom::cv_when_subtypes; - -//------------------------------------------------------------------------------------------------- - -Scom::Scom(BINSEQ::const_iterator & bli, Symbols * i_symbols): - iv_symbols(i_symbols), - iv_when(NONE), - iv_scom_length(0), - iv_scom_offset(0), - iv_when_rpn(i_symbols) - -{ - - iv_scom_length = Rpn::extract16(bli); - iv_scom_offset = Rpn::extract16(bli); - uint32_t id = Rpn::extract16(bli); - uint32_t numcols = Rpn::extract16(bli); - uint32_t numrows = Rpn::extract16(bli); - - numcols &= ~SUBTYPE_MASK; - - // Get our SCOM address - uint32_t l_addr_size = 0; - iv_scom_addr_hex = iv_symbols->get_numeric_data(iv_symbols->get_rpn_id(id),l_addr_size); - - - if( iv_scom_length != 0 && iv_scom_length != 0xffff) // most common values - { - if(iv_scom_length < 65) // max scom len is 64 bits - { - for(size_t i = 0; i < numrows; ++i) - add_bit_range(iv_scom_offset, iv_scom_offset + iv_scom_length - 1); - } - else // What's this? - { - ostringstream errs; - errs << "ERROR: Scom::Scom: Invalid scom bit length [" - << iv_scom_length << "]" << endl; - throw range_error(errs.str()); - } - } - - for(size_t i = 0; i < numrows; ++i) - { - uint8_t length = *bli++; // first byte is length of rpn sequence - //printf("Creating scom data rpn, length %u\n", length); - - Rpn rpn(iv_symbols); // blank RPNs - rpn.bin_read(bli, length); // read rpn sequence - iv_scom_rpn.push_back(rpn); - } - - if(numcols) - { - for(size_t i = 0; i < numrows; ++i) iv_row_rpn.push_back(Rpn(iv_symbols)); // blank RPNs - - // Read col heads - for(size_t i = 0; i < numcols; ++i) - { - Rpn col_name_rpn(iv_symbols); // blank RPNs - col_name_rpn.bin_read_one_id(bli); - iv_col_vars.push_back(col_name_rpn); - iv_cols_rpn.push_back(iv_row_rpn); // copy in blank row RPNs for this column - } - - for(size_t row_n = 0; row_n < numrows; ++row_n) - { - COL_LIST::iterator cli = iv_cols_rpn.begin(); // *cli is list of row rpns for col - RPN_LIST::iterator rpi = (*cli).begin() + row_n; // *rpi is current row rpn for first col - - // The next len bytes belong to this row - uint16_t rpn_byte_count = (*bli++ << 8) + (*bli++); // length of rpn sequece - //printf("Create scom from binseq: rpn byte count: %u\n", rpn_byte_count); - BINSEQ::const_iterator bli_end = bli + rpn_byte_count; // end of rpn in bin seq - - // Simple cols are divided by OPs - // LIST op has two additional bytes (len,op) - while(bli < bli_end) - { - // Last col rpn is not limited to one op if it's "expr" - it gets the rest of the RPN - if(cli == (iv_cols_rpn.end() - 1)) - { - while(bli < bli_end) bli = rpi->bin_read_one_op(bli); - break; - } - bli = rpi->bin_read_one_op(bli); - ++cli; - rpi = (*cli).begin() + row_n; - } - } - } - else ++bli; -} - -//------------------------------------------------------------------------------------------------- - -void Scom::set_when(const string * when_str) -{ - - string s(*when_str); - for(string::iterator c = s.begin(); c != s.end(); ++c) *c = toupper(*c); - if(s.size()) - { - size_t i = 0; - for(size_t i = 1; i < sizeof(when_char)/sizeof(when_char[0]); ++i) - { - if(s[0] == when_char[i]) - { - set_when((SCOM_WHEN)i); - break; - } - } - if(i == sizeof(when_char)/sizeof(when_char[0])) - { - string errs("Illegal when="); - errs.append(s); - yyerror(errs.c_str()); - } - s.erase(0,1); - - if(s.size()) - { - WHEN_SUBTYPE_MAP::const_iterator i = cv_when_subtypes.find(s); - if(i != cv_when_subtypes.end()) - { - set_sub_when(i->second); - } - else - { - std::ostringstream oss; - oss << "Illegal 'when=' subvalue: [" << s << ']'; - yyerror(oss.str().c_str()); - } - } - } - else - { - yyerror("Missing 'when =' value"); - } -} - -//------------------------------------------------------------------------------------------------- - -void Scom::add_col(const string & i_colname) -{ - string s(i_colname); - for(string::iterator i = s.begin(); i != s.end(); ++i) *i = toupper(*i); - Rpn col_rpn(s,iv_symbols); // = iv_symbols->use_symbol(s); - - // add check - Can't add any more cols after EXPR column dg001a - if(iv_col_vars.size()) - { - Rpn exp_rpn("EXPR",iv_symbols); - if(exp_rpn == iv_col_vars.back()) // expr col already added - can't add any more cols - { - if (s == "EXPR") - { - yyerror("Scom:: add_col: Multiple EXPR columns specified."); - } - else - { - yyerror("Scom:: add_col: EXPR must be the last column"); - } - } - } - - // if the entire column is unconditionally true it can be left out - // This check will be done later as this scom might be split by bit-ranges. - - iv_col_vars.push_back(col_rpn); - iv_cols_rpn.push_back(iv_row_rpn); // add the collected row RPNs - iv_row_rpn.clear(); -} - -//------------------------------------------------------------------------------------------------- - -void Scom::add_row_rpn(Rpn * i_rpn) -{ - // The row gets parsed before the col name - // So collect the row RPNs and apply them when the col name gets added - - // Replace the Rpn "ANY" EQ with TRUE dg003a - Rpn any_rpn("ANY",iv_symbols); - Rpn true_rpn(iv_symbols); - true_rpn.push_op(TRUE_OP); - - // The column EXPR can have an lone "ANY" rpn - so add EQ. - if(any_rpn == (*i_rpn)) i_rpn->push_op(EQ); - any_rpn.push_op(EQ); - - if(any_rpn == (*i_rpn)) iv_row_rpn.push_back(true_rpn); // Replace col == ANY with TRUE - else - { - iv_row_rpn.push_back(*i_rpn); - } - delete i_rpn; -} - -//------------------------------------------------------------------------------------------------- - -void Scom::add_bit_range(uint32_t start, uint32_t end) -{ - // make sure they are added in order - dbg << "Add bit range " << dec << start << " to " << end << endl; - iv_range_list.push_back(RANGE(start,end)); -} - -//------------------------------------------------------------------------------------------------- -// Range gets parsed before the target symbol (k,n,p,c) - so save it -void Scom::add_target_range(uint32_t r1, uint32_t r2) -{ - if(r1 > r2) - { - uint32_t rt = r1; - r1 = r2; - r2 = rt; - } - iv_target_ranges.push_back(RANGE(r1,r2)); -} - -//------------------------------------------------------------------------------------------------- - -void Scom::make_target(const char * i_symbol) -{ - string s(i_symbol); - Rpn r(iv_symbols); - size_t rsize = iv_target_ranges.size(); - - if(rsize == 0) - { - yyerror("Target given w/o a range"); - } - // if more than one target - use list - else - { - for(RANGE_LIST::iterator iter = iv_target_ranges.begin(); iter != iv_target_ranges.end(); ++iter) - { - for(uint32_t v = iter->first; v <= iter->second; ++v) - { - r.push_int(v); - } - } - if(rsize > 1) r.push_op(LIST); // if more than one target - r.push_op(EQ); - } - - iv_row_rpn.push_back(r); - add_col(s); - iv_target_ranges.clear(); -} - -//------------------------------------------------------------------------------------------------- - -string Scom::list_one(RANGE range) -{ - ostringstream oss; - - uint32_t numcols = iv_col_vars.size() | (iv_when & SUBTYPE_MASK); // WHEN subtype goes in numcols - uint32_t bitlen = range.second + 1 - range.first; - if (bitlen) - { - iv_scom_length = bitlen; // don't overwrite iv_scom_length if bitlen == 0 - iv_scom_offset = range.first; // don't overwrite iv_scom_offset if bitlen == 0 - } - - uint32_t allrows = 0; - uint32_t numrows = 0; - - if(iv_cols_rpn.size()) allrows = iv_cols_rpn.front().size(); - if (allrows == 0) allrows = 1; - - // If there is a bit range we need to select only the rows that apply to this spyname - if(bitlen) - { - for(RANGE_LIST::iterator r = iv_range_list.begin(); r != iv_range_list.end(); ++r) - { - if((*r) == range) ++numrows; - } - } - else numrows = allrows; // else select all the rows - - oss << hex << setfill('0'); - oss << "------------"; - oss << " Scom Address: 0x" << setw(16) << iv_scom_addr_hex; - dbg << " Scom Address: 0x" << hex << setfill('0') << setw(16) << iv_scom_addr_hex << endl; - if(bitlen) - { - oss << '~' << dec << range.first; - if(range.first != range.second) oss << ':' << range.second; - oss << hex; - } - oss << ' ' << "------------" << endl - << "When= " << (iv_when & WHEN_MASK) << endl; - - oss << "0x" << setw(4) << iv_scom_length << "\t\t" << "Scom length" << endl - << "0x" << setw(4) << iv_scom_offset << "\t\t" << "Scom offset" << endl; - - //oss << "0x" << setw(8) << iv_symbols->get_spy_id(spyname) << '\t'; - - oss << "0x" << setw(4) << numcols << "\t\t" << "Number of columns" << endl - << "0x" << setw(4) << numrows << "\t\t" << "Number of rows" << endl; - - // If there is a bit range we need to select only the spyv rows that apply to this spyname - - if(bitlen) - { - RPN_LIST::iterator i = iv_scom_rpn.begin(); - for(RANGE_LIST::iterator r = iv_range_list.begin(); r != iv_range_list.end(); ++r,++i) - { - if ((*r) == range) - { - oss << i->listing("Length of rpn for spyv",Rpn::cv_empty_str,true); - } - } - } - else // get all rows - { - for(RPN_LIST::iterator i = iv_scom_rpn.begin(); i != iv_scom_rpn.end(); ++i) - { - oss << i->listing("Length of rpn for spyv",Rpn::cv_empty_str,true); - } - } - oss << endl; - - - // list the column names that are really CINI VARS - for(RPN_LIST::iterator i = iv_col_vars.begin(); i != iv_col_vars.end(); ++i) - { - oss << i->listing("",Rpn::cv_empty_str,true); - //Rpn col_rpn = *i; - //string desc = iv_symbols->find_name(rpn_id); - //if(desc.size() == 0) desc = "Variable not found!"; - - //oss << "0x" << setw(4) << iv_symbols->get_tag(*i) << "\t\t" << desc << endl; - } - oss << endl << endl; - - - - uint32_t usedrows = 0; - if(iv_cols_rpn.size() == 0) - { - oss << "ROW " << 1 << "\n0x00" << "\t\t" << "0 BYTES" << endl; - } - else - { - for(size_t n = 0; n < allrows; ++n) - { - Rpn rpn(iv_symbols); - if(bitlen) // only get rows that match the current bitrange - { - if(iv_range_list[n] != range) continue; - } - ++usedrows; - oss << "ROW " << usedrows << endl; - - // Build up the row Rpn for row n - for(COL_LIST::iterator i = iv_cols_rpn.begin(); i != iv_cols_rpn.end(); ++i) - { - rpn.append(i->at(n)); - } - oss << rpn.listing(NULL,Rpn::cv_empty_str,true) << endl; - } - } - - return oss.str(); -} - -//------------------------------------------------------------------------------------------------- - -string Scom::listing() -{ - ostringstream oss; - - set<RANGE> ranges; - ranges.insert(iv_range_list.begin(),iv_range_list.end()); - - //oss << list_one(RANGE(1,0)) << endl; - if(ranges.size()) - { - for(set<RANGE>::iterator r = ranges.begin(); r != ranges.end(); ++r) - { - oss << list_one(*r) << endl; - } - } - else - { - oss << list_one(RANGE(1,0)) << endl; - } - - return oss.str(); -} - -//------------------------------------------------------------------------------------------------- - -uint32_t Scom::bin_listing(BINSEQ & blist) -{ - set<RANGE> ranges; - uint32_t scom_count = 0; - uint32_t addr_num = 0; - - row_optimize(); // delete any rows that are unconditionally false. + merge rows - - //printf("bin_listing: iv_scom_rpn size = %u\n", iv_scom_rpn.size()); - - //Skip this scom if after row_optimize, there's no scom data to write - if (iv_scom_rpn.size()) - { - ranges.insert(iv_range_list.begin(),iv_range_list.end()); - - SCOM_ADDR::iterator i = iv_scom_addr.begin(); - - for(; i != iv_scom_addr.end(); ++i, ++addr_num) - { - dbg << "SCOM::bin_listing: SCOM[" << dec << scom_count << "] Address: " - << hex << *i << endl; - if(ranges.size()) - { - for(set<RANGE>::iterator r = ranges.begin(); r != ranges.end(); ++r) - { - ++scom_count; - //bin_list_one(blist,*i,*r); - // The following sequence will optimize the bytecode for this spy - // - Compile the spy into bytecode for a range of bits - // - Recreate the spy from the bytecode - // - Compile the recreated spy back into bytecode. - BINSEQ temp; - bin_list_one(temp,strtoull((*i).c_str(),NULL,16), addr_num, *r); - BINSEQ::const_iterator bi = temp.begin(); - Scom s(bi,iv_symbols); - s.bin_list_one(blist,strtoull((*i).c_str(),NULL,16), addr_num, RANGE(1,0)); - } - } - else - { - ++scom_count; - bin_list_one(blist,strtoull((*i).c_str(),NULL,16), addr_num, RANGE(1,0)); - } - } - } - - return scom_count; -} - -//------------------------------------------------------------------------------------------------- - -void Scom::bin_list_one(BINSEQ & blist,uint64_t i_addr, uint32_t i_addr_num, RANGE range) -{ - - uint32_t numaddrs = iv_scom_addr.size(); //Number of Scom addresses for this Scom - uint32_t numcols = iv_col_vars.size() | (iv_when & SUBTYPE_MASK); // WHEN subtype goes in numcols - -// No range support - uint32_t bitlen = range.second + 1 - range.first; - - if (bitlen) - { - iv_scom_length = bitlen; // don't overwrite iv_scom_length if bitlen == 0 - iv_scom_offset = range.first; // don't overwrite iv_scom_offset if bitlen == 0 - } - - uint32_t allrows = 0; - uint32_t numrows = 0; - - if(iv_cols_rpn.size()) allrows = iv_cols_rpn.front().size(); - if (allrows == 0) allrows = 1; - - // If there is a bit range we need to select only the rows that apply to this spyname - if(bitlen) - { - for(RANGE_LIST::iterator r = iv_range_list.begin(); r != iv_range_list.end(); ++r) - { - if((*r) == range) ++numrows; - } - } - else numrows = allrows; // else select all the rows - - // If every row rpn in a column is unconditionally true then remove the col. - if(iv_col_vars.size()) - { - vector< pair<RPN_LIST::iterator, COL_LIST::iterator> > deletes; - RPN_LIST::iterator cv = iv_col_vars.begin(); // -> column header Rpn - COL_LIST::iterator cr = iv_cols_rpn.begin(); // -> RPN list of row segments for the column - for(; cv != iv_col_vars.end(); ++cv,++cr) - { - bool remove_it = true; - for(RPN_LIST::const_iterator r = cr->begin(); r != cr->end(); ++r) - { - if(!(r->isTrue())) - { - remove_it = false; - break; - } - } - if(remove_it) - { - deletes.push_back( pair<RPN_LIST::iterator, COL_LIST::iterator>(cv,cr) ); - } - } - while(deletes.size()) - { - pair<RPN_LIST::iterator, COL_LIST::iterator> p = deletes.back(); - deletes.pop_back(); - dbg << "COL is unconditionally true. Removing column " << (p.first)->symbol_names() - << endl; - iv_col_vars.erase(p.first); - iv_cols_rpn.erase(p.second); - --numcols; - } - } - - Rpn::set16(blist,(uint16_t)iv_scom_length); - Rpn::set16(blist,(uint16_t)iv_scom_offset); - - // Just put the SCOM address in place of the spy id - //uint32_t id = iv_symbols->get_spy_id(spyname); - //Rpn::set32(blist,id); - // TODO - Probably need to get scom address id here - //Rpn::set32(blist,(uint32_t)iv_address); - - Rpn *l_scom_addr = new init::Rpn(i_addr,yyscomlist->get_symbols()); - l_scom_addr->bin_str(blist,numaddrs,i_addr_num,false); - delete l_scom_addr; - - - Rpn::set16(blist,(uint16_t)numcols); - Rpn::set16(blist,(uint16_t)numrows); - - // If there is a bit range we need to select only the spyv rows that apply to this spyname - if(bitlen) - { - RPN_LIST::iterator i = iv_scom_rpn.begin(); - for(RANGE_LIST::iterator r = iv_range_list.begin(); r != iv_range_list.end(); ++r,++i) - { - if ((*r) == range) - { - i->bin_str(blist,numaddrs,i_addr_num,true,true); //Add length to blist - } - } - } - else // get all rows - { - for(RPN_LIST::iterator i = iv_scom_rpn.begin(); i != iv_scom_rpn.end(); ++i) - { - i->bin_str(blist,numaddrs,i_addr_num,true,true); //Add length to blist - } - } - - // list the column names that are really CINI VARS - for(RPN_LIST::iterator i = iv_col_vars.begin(); i != iv_col_vars.end(); ++i) - { - i->bin_str(blist,numaddrs,i_addr_num,false); // false means don't prepend an RPN byte count to the binary rpn appended. - //uint16_t tag = iv_symbols->get_tag(*i); - //blist.push_back((uint8_t)(tag >> 8)); - //blist.push_back((uint8_t) tag); - } - - if(iv_cols_rpn.size() == 0) blist.push_back(0); - else - { - for(size_t n = 0; n < allrows; ++n) - { - Rpn rpn(iv_symbols); - if(bitlen) // only get rows that match the current bitrange - { - if(iv_range_list[n] != range) continue; - } - - // Build up the row Rpn for row n - for(COL_LIST::iterator i = iv_cols_rpn.begin(); i != iv_cols_rpn.end(); ++i) - { - rpn.append(i->at(n)); - } - rpn.bin_str(blist,numaddrs,i_addr_num,true); - } - } -} - -//------------------------------------------------------------------------------------------------- -// Delete any rows that are unconditionally false -// Merge rows that can be merged -// -void Scom::row_optimize() //dg003a -{ - size_t row = 0; - if (iv_cols_rpn.size()) row = iv_cols_rpn.front().size(); - if(row == 0) return; - - // Look for false rows - do - { - bool remove_me = false; - --row; - for(COL_LIST::iterator i = iv_cols_rpn.begin(); i != iv_cols_rpn.end(); ++i) - { - if (i->at(row).isFalse()) - { - remove_me = true; - break; - } - } - if(remove_me) - { - iv_scom_rpn.erase(iv_scom_rpn.begin() + row); //remove spyv - if (0 == iv_scom_rpn.size()) - { - iv_col_vars.clear(); - iv_cols_rpn.clear(); - if(iv_range_list.size()) - { - iv_range_list.clear(); - } - } - else - { - //Need to remove rpn row segment from each iv_cols_rpn rpn list - for(COL_LIST::iterator i = iv_cols_rpn.begin(); i != iv_cols_rpn.end(); ++i) - { - i->erase(i->begin() + row); - } - if(iv_range_list.size()) iv_range_list.erase(iv_range_list.begin() + row); - } - - dbg << "initScom: row_optimize: ROW is unconditionally false. Removing row " << row+1 << endl; - dbg << "initScom: row_optimize: iv_scom_rpn size " << iv_scom_rpn.size() << endl; - } - } while (row); - - // now look for rows to merge - // for now limit to spies with EXPR as the only column - // Because the interpreter looks down the rows until it finds one that's "true" then stops, the order - // of rows cant't be modified. This means only rows next to each other can be merged. - // This makes for very large Rpn strings - turn on later when we have better redundancy reduction in RPNs -#if defined(__LATER__) - Rpn r_expr("EXPR", iv_symbols); - row = iv_spyv_rpn.size(); - if ((row > 1) && (iv_col_vars.size() == 1) && (iv_col_vars.front() == r_expr)) - { - --row; - do - { - size_t row1 = row - 1; - - if (iv_spyv_rpn.at(row) == iv_spyv_rpn.at(row1)) - { - if (iv_range_list.size() == 0 || (iv_range_list.at(row) == iv_range_list.at(row1))) - { - // merge - Rpn * rp = new Rpn(iv_cols_rpn.back().at(row)); - iv_cols_rpn.back().at(row1).push_merge(rp, Rpn::OR); // this will delete rp - iv_spyv_rpn.erase(iv_spyv_rpn.begin() + row); - if (iv_range_list.size()) iv_range_list.erase(iv_range_list.begin() + row); - for (COL_LIST::iterator i = iv_cols_rpn.begin(); i != iv_cols_rpn.end(); ++i) - { - i->erase(i->begin() + row); - } - dbg << "ROW " << row+1 << " and " << row1+1 << " have been merged in " << get_key_name() << endl; - } - } - } while (--row); - } -#endif -} - - - -//------------------------------------------------------------------------------------------------- - -bool Scom::compare(Scom & that) -{ - bool result = false; //true; -// TODO -#if 0 - ostringstream oss; - oss << hex << setfill('0'); - // spyname(s) should have already been tested - oss << get_key_name() << endl; - if(iv_spy_type != that.iv_spy_type || - iv_when != that.iv_when || - iv_spy_length != that.iv_spy_length || - iv_spy_offset != that.iv_spy_offset || - iv_array_addr != that.iv_array_addr) - { - result = false; - oss << "type: " << setw(8) << iv_spy_type << ' ' << that.iv_spy_type << endl; - oss << "when: " << setw(8) << iv_when << ' ' << that.iv_when << endl; - oss << "len: " << setw(8) << iv_spy_length << ' ' << that.iv_spy_length << endl; - oss << "offset: " << setw(8) << iv_spy_offset << ' ' << that.iv_spy_offset << endl; - oss << "array: " << setw(8) << iv_array_addr << ' ' << that.iv_array_addr << endl; - } - // need to expand all Rpns to verify resolution of vars and lits - // when Rpn - string rpn1 = iv_when_rpn.listing("",iv_spy_names.front(),false); - string rpn2 = that.iv_when_rpn.listing("",iv_spy_names.front(),false); - if(rpn1 != rpn2) - { - result = false; - oss << "this when Rpn:" << endl << rpn1 << endl; - oss << "that when Rpn:" << endl << rpn2 << endl; - } - - // spyv Rpn - if(iv_spyv_rpn.size() != that.iv_spyv_rpn.size()) - { - result = false; - oss << "this spyv Rpn(s):" << endl; - for(RPN_LIST::iterator r1 = iv_spyv_rpn.begin(); r1 != iv_spyv_rpn.end(); ++r1) - oss << r1->listing("",iv_spy_names.front(),false) << endl; - oss << "that spyv Rpn(s):" << endl; - for(RPN_LIST::iterator r1 = that.iv_spyv_rpn.begin(); r1 != that.iv_spyv_rpn.end(); ++r1) - oss << r1->listing("",iv_spy_names.front(),false) << endl; - } - else - { - RPN_LIST::iterator r1 = iv_spyv_rpn.begin(); - RPN_LIST::iterator r2 = that.iv_spyv_rpn.begin(); - for(; r1 != iv_spyv_rpn.end(); ++r1, ++r2) - { - rpn1 = r1->listing("",iv_spy_names.front(),false); - rpn2 = r2->listing("",iv_spy_names.front(),false); - if(rpn1 != rpn2) - { - result = false; - oss << "this spyv Rpn:" << endl << rpn1 << endl; - oss << "that spyv Rpn:" << endl << rpn2 << endl; - } - } - } - - // column names - if(iv_col_vars.size() != that.iv_col_vars.size()) - { - result = false; - oss << "this col names:" << endl; - for(RPN_LIST::iterator i = iv_col_vars.begin(); i != iv_col_vars.end(); ++i) - { - oss << i->symbol_names() << endl; - } - oss << "that col names:" << endl; - for(RPN_LIST::iterator i = that.iv_col_vars.begin(); i != that.iv_col_vars.end(); ++i) - { - oss << i->symbol_names() << endl; - } - } - else - { - RPN_LIST::iterator i = iv_col_vars.begin(); - RPN_LIST::iterator j = that.iv_col_vars.begin(); - for(;i != iv_col_vars.end(); ++i, ++j) - { - //string s1 = iv_symbols->find_name(*i); - //string s2 = that.iv_symbols->find_name(*j); - if((*i) != (*j)) - { - result = false; - oss << "this col name: " << i->symbol_names() << endl; - oss << "that col name: " << j->symbol_names() << endl; - } - } - } - - // row Rpns - Rpn r1(iv_symbols); - Rpn r2(that.iv_symbols); - for(COL_LIST::iterator c = iv_cols_rpn.begin(); c != iv_cols_rpn.end(); ++c) - { - for(RPN_LIST::iterator r = c->begin(); r != c->end(); ++r) - { - r1.append(*r); - } - } - for(COL_LIST::iterator c = that.iv_cols_rpn.begin(); c != that.iv_cols_rpn.end(); ++c) - { - for(RPN_LIST::iterator r = c->begin(); r != c->end(); ++r) - { - r2.append(*r); - } - } - rpn1 = r1.listing("",iv_spy_names.front(),false); - rpn2 = r2.listing("",iv_spy_names.front(),false); - if(rpn1 != rpn2) - { - result = false; - oss << "this row/col rpn:" << endl; - oss << rpn1 << endl; - oss << "that row/col rpn:" << endl; - oss << rpn2 << endl; - } - - if(!result) cout << oss.str(); -#endif - return result; -} - - -//================================================================================================= -// SpyList Class definitions -//================================================================================================= - -ScomList::ScomList(const string & initfile, FILELIST & defines, ostream & stats, uint32_t i_ec) - : - iv_syntax_version(0), - iv_symbols(new Symbols(defines)), - iv_stats(stats), - iv_ec(i_ec) - -{ - yyscomlist = this; - - // What type of input? text(*.initfile) or binary(*.if) ? - size_t pos = initfile.rfind('.'); - string type; - if(pos != string::npos) - { - type = initfile.substr(pos+1); - } - - if(type.compare(0,8,"initfile") == 0) // source is text *.initfile - { - char line[100]; - string first_line; - yyin = fopen(initfile.c_str(), "r"); - if(!yyin) - { - string ers("ERROR: ScomList::ScomList: Could not open initfile: "); - ers.append(initfile); - throw invalid_argument(ers); - } - - // In Syntax version 1 the first or second line contains the CVS version - fgets(line,100,yyin); - first_line = line; - fgets(line,100,yyin); - first_line.append(line); - yyline = 3; - - dbg << "======================= Begin Parse ========================" << endl; - yyparse(); // Parse the initfile - dbg << "======================= End Parse ==========================" << endl; - - if(iv_syntax_version == 1) - { - // example pattern ..... $Id: galaxy.initfile,v 5.0 ...... - size_t pos = first_line.find("$Id:"); - if(pos != string::npos) - { - istringstream iss(first_line.substr(pos+4)); - string tok; - iss >> tok; // ex. galaxy.initfile,v - iss >> tok; // ex. 5.0 - iv_cvs_versions = tok; // just want the version number - eg '5.0' - } - } - - iv_stats << '*' << setw(20) << "lines:" << setw(6) << yyline-1 << endl; - iv_stats << '*' << setw(20) << "Scom statements:" << setw(6) << iv_scom_list.size() << endl; - // TODO num var/lits num lits found - } - else if(type.compare(0,2,"if") == 0) // source is binary *.if file - { -// TODO - No support for this currently -#if 0 - dbg << "======================= Begin Uncompiling ========================" << endl; - - BINSEQ bin_seq; - ifstream ifs(initfile.c_str(), ios_base::in | ios_base::binary); - if(!ifs) - { - string msg("ERROR: SpyList::Could not open "); - msg.append(initfile); - throw invalid_argument(msg); - } - while(1) - { - int ch = ifs.get(); - if (!(ifs.good())) break; - bin_seq.push_back(ch); - } - ifs.close(); - - // Turn this back into a list of spies - BINSEQ::const_iterator bli = bin_seq.begin(); - BINSEQ::const_iterator b; - - iv_syntax_version = Rpn::extract32(bli); - bli += 8; - if(iv_syntax_version == 1) - { - for(b = bli-8; (b != bli) && (*b); ++b) - { - iv_cvs_versions.push_back(*b); - } - } - else - { - // offset to CVS sub version section - b = bin_seq.begin() + Rpn::extract32(bli); - size_t size = Rpn::extract16(b); - while(size--) iv_cvs_versions.push_back(*b++); - } - - b = bin_seq.begin() + Rpn::extract32(bli); - iv_symbols->restore_var_bseq(b); - - b = bin_seq.begin() + Rpn::extract32(bli); - iv_symbols->restore_lit_bseq(b); - - size_t section_count = Rpn::extract32(bli); - if(section_count > LAST_WHEN_TYPE) - { - throw range_error("ERROR: SpyList::SpyList - Inalid # of sections"); - } - - for(size_t i = 0; i < section_count; ++i) - { - size_t spy_type = Rpn::extract32(bli); // type - size_t offset = Rpn::extract32(bli); // offset - size_t count = Rpn::extract32(bli); // Number of spies - - b = bin_seq.begin() + offset; - if(!(b < bin_seq.end())) - { - throw overflow_error("ERROR: SpyList::SpyList - iterator overflowed sequence"); - } - if(spy_type > LAST_WHEN_TYPE || spy_type == 0) - { - throw range_error("ERROR: SpyList::SpyList - when= type out of range"); - } - while(count--) - { - Scom * s = new Scom(b,iv_symbols); - insert(s); - s->set_when((SPY_WHEN)spy_type); - } - } -#endif - dbg << "======================= End Uncompiling ========================" << endl; - } - else - { - ostringstream ess; - ess << "ERROR: SpyList::SpyList Invalid file type: " << type; - ess << "\n source: " << initfile; - throw invalid_argument(ess.str()); - } -} - -//------------------------------------------------------------------------------------------------- - -ScomList::~ScomList() -{ - delete iv_symbols; -} - -//------------------------------------------------------------------------------------------------- - -void ScomList::clear() -{ - for(SCOM_LIST::iterator i = iv_scom_list.begin(); i != iv_scom_list.end(); ++i) delete i->second; - iv_scom_list.clear(); -} - -//------------------------------------------------------------------------------------------------- - -void ScomList::set_syntax_version(uint32_t v) -{ - if(v != 1 && v != 2) yyerror("ScomList:: set_syntax_version: Invalid Syntax Version"); - iv_syntax_version = v; -} - -//------------------------------------------------------------------------------------------------- - -void ScomList::compile(BINSEQ & bin_seq) -{ - uint32_t count_s = 0; - uint32_t section_count = 0; - size_t offset = 0; - - - BINSEQ blist_v; // vars - BINSEQ blist_i; // lits - BINSEQ blist_l; // when=L spies - BINSEQ blist_s; // when=S spies - BINSEQ blist_c; // when=C spies - BINSEQ blist_d; // when=D spies - - // Make the BINSEQs big enough to hopefully never have to resize - blist_v.reserve(0x00400); - blist_i.reserve(0x02000); - blist_l.reserve(0x30000); - blist_s.reserve(0x03000); - blist_c.reserve(0x03000); - blist_d.reserve(0x03000); - - - dbg << "======================== Begin compile ============================" << endl; - Rpn::set32(bin_seq,iv_syntax_version); // bytes[0:3] - - // bytes [4:12] - if(iv_syntax_version == 2) - { - const char * s = "SEE SUBV"; - for(; *s != 0; ++s) bin_seq.push_back(*s); - istringstream iss(iv_cvs_versions); - string vers; - while(iss >> vers) - { - stats << '*' << setw(20) << "Version:" << " " << vers << endl; - } - } - else if (iv_syntax_version == 1) - { - if(iv_cvs_versions.size()) - { - size_t len = iv_cvs_versions.size(); - if(len > 8) { iv_cvs_versions.erase(9); len = 8; } - for(string::const_iterator s = iv_cvs_versions.begin(); - s != iv_cvs_versions.end(); ++s) - { - bin_seq.push_back(*s); - } - while(len < 8) { bin_seq.push_back(0); ++len; } - stats << '*' << setw(20) << "Version:" << setw(6) << iv_cvs_versions << endl; - } - else - { - throw range_error("ERROR: ScomList::compile: No CVS version(s) specified"); - } - } - else // syntax version already validated to be 1 or 2 - so if we get here it was never set. - { - throw range_error("ERROR: ScomList::compile: No syntax version specified!"); - } - stats << '*' << setw(20) << "Syntax Version:" << setw(6) << iv_syntax_version << endl; - - - // Determine the number of scoms in each section - - for(SCOM_LIST::iterator i = iv_scom_list.begin(); i != iv_scom_list.end(); ++i) - { - // Filter out filtered spies dg003a - if(!(i->second->valid_when(dbg,iv_ec))) - { - continue; - } - - count_s += i->second->bin_listing(blist_s); - - } - if(count_s) ++section_count; - - // 28 bytes of File Header Data - offset = 28; - stats << '*' << setw(20) << "Sections:" << setw(6) << section_count << endl; - - // for verion 2 add offset to CVS versions section - if(iv_syntax_version == 2) - { - offset += 4; - Rpn::set32(bin_seq,offset); - offset += iv_cvs_versions.length() + 2; - } - // offset now points to start of Var Symbol Table - - iv_symbols->bin_vars(blist_v); // get Var table - iv_symbols->bin_lits(blist_i); // Get Lit table - - Rpn::set32(bin_seq,offset); // Offset to Variable Symbol Table - offset += blist_v.size(); // offset += var table byte size - Rpn::set32(bin_seq,offset); // Offset to Literal Symbol Table - offset += blist_i.size(); // offset += lit table byte size - - //if(count_s) //Need to write this either way - { - Rpn::set32(bin_seq,offset); // SCOM Section offset - Rpn::set32(bin_seq,count_s); // Number of SCOM's - } - - if(iv_syntax_version == 2) // Add Sub-version section - { - Rpn::set16(bin_seq,(uint16_t)iv_cvs_versions.length()); // Length of Sub version - bin_seq.insert(bin_seq.end(), iv_cvs_versions.begin(), iv_cvs_versions.end()); - } - - bin_seq.insert(bin_seq.end(), blist_v.begin(), blist_v.end()); // add var table section - bin_seq.insert(bin_seq.end(), blist_i.begin(), blist_i.end()); // add lit table section - - if(count_s) - { - bin_seq.insert(bin_seq.end(), blist_s.begin(), blist_s.end()); // add SCOM section - } - stats << '*' << setw(20) << "S scoms:" << setw(6) << count_s << endl; - dbg << "======================== End compile ============================" << endl; -} - -//------------------------------------------------------------------------------------------------- - -bool Scom::valid_when(ostream & msg, uint32_t i_ec) //dg002a dg003c -{ - bool result = true; - - // unconditional state was determined earlier - if( iv_when_rpn.isTrue()) // unconditionally true - Rpn is not needed. - iv_when_rpn.clear(); - else if( iv_when_rpn.isFalse()) //unconditionally false - result = false; - else if(i_ec != 0xffffffff) - { - if(iv_when_rpn.resolve_ec(i_ec) == false) result = false; - } -#if 0 - if(result == false) - { - msg << hex; - SPY_NAMES::iterator i = iv_spy_names.begin(); - // if more than one spyname, the first is just the stem of the name - skip it - if(iv_spy_names.size() > 1) ++i; - - for(; i != iv_spy_names.end(); ++i) - { - if(i_ec != 0xffffffff) - msg << "For EC " << i_ec << ": "; - - msg << "Removing spy " << *i << endl; - } - msg << iv_when_rpn.listing("WHEN RPN","",true) << endl; - } -#endif - return result; -} - -//------------------------------------------------------------------------------------------------- - -void ScomList::listing(BINSEQ & bin_seq,ostream & olist) -{ - dbg << "======================= Begin Listing ========================" << endl; - - BINSEQ::const_iterator bli = bin_seq.begin(); - BINSEQ::const_iterator b; - uint32_t syntax_version = Rpn::extract32(bli); - - string cvs_versions; - - olist << hex << setfill('0'); - olist << "--------------- FILE HEADER ------------------------\n\n"; - olist << fmt8(syntax_version) << "[Syntax Version]\n" - << "0x"; - bli += 8; - for(b = bli-8; b != bli; ++b) olist << setw(2) << (uint32_t)(*b); - olist << " ["; - for(b = bli-8; b != bli; ++b) if((*b) != 0) olist << (char)(*b); - olist << "]\t[CVS Version]\n"; - if(syntax_version == 2) - { - size_t offset = Rpn::extract32(bli); - olist << fmt8(offset) << "[Offset to Sub-Version Section]\n"; - } - - uint32_t var_table_offset = Rpn::extract32(bli); - uint32_t lit_table_offset = Rpn::extract32(bli); - - olist << fmt8(var_table_offset) << "[Offset to Attribute Symbol Table]\n"; - olist << fmt8(lit_table_offset) << "[Offset to Literal Symbol Table]\n"; - - - b = bin_seq.begin() + var_table_offset; - iv_symbols->restore_var_bseq(b); - - b = bin_seq.begin() + lit_table_offset; - iv_symbols->restore_lit_bseq(b); - - b = bli; // save - - size_t offset = Rpn::extract32(bli); // offset - size_t count = Rpn::extract32(bli); // Number of spies - - olist << fmt8(offset) << "[Scom Section Offset]\n"; - olist << fmt8(count) << "[Number of scoms]\n"; - - olist << endl; - - if(syntax_version == 2) - { - olist << "--------------- Sub Version Section ---------------\n\n"; - uint16_t len = Rpn::extract16(bli); - olist << "0x" << setw(4) << len << "\t\t" - << "Length of Sub Version Section\n\n"; - for(uint16_t i = 0; i < len; ++i) olist << (char)(*bli++); - olist << endl; - } - - if (yytarget.size()) - { - olist << "------------------- TARGET MAPPING ------------------------\n\n" - << endl; - std::map<string,string>::iterator i; - for (i = yytarget.begin(); i != yytarget.end(); i++) - { - olist << i->first << setfill(' ') << setw(30 - i->first.length()) - << " = " << i->second << endl; - } - } - - olist << iv_symbols->listing() << endl; - - if (count) - { - olist << "------------------- SCOM TABLES ------------------------\n\n" - << endl; - - bli = b; // restore - - olist << "------------ Scoms -----------\n\n"; - - b = bin_seq.begin() + offset; - if(!(b < bin_seq.end())) - { - throw overflow_error("ERROR: ScomList::listing: iterator overflowed sequence"); - } - - SCOM_LIST l_scom_list; - SCOM_LIST::const_iterator i; - pair<SCOM_LIST::const_iterator, SCOM_LIST::const_iterator> ret; - while (count --) - { - Scom * s = new Scom(b,iv_symbols); - olist << s->listing() << endl; - - uint64_t l_addr = s->get_address_hex(); - //cout << "ScomList::listing: iv_scom_address_hex 0x" << hex << l_addr << endl; - - //Check for duplicate scom statements - bool l_dup_scoms = false; - ret = l_scom_list.equal_range(l_addr); - if (ret.first != ret.second) - { - //cout << "ScomList::listing: Duplicate scom addresses found" << endl; - - uint32_t l_length = s->get_scom_length(); - - //If writing all bits - if (l_length == 0) - { - l_dup_scoms = true; - } - else - { - uint32_t l_start = s->get_scom_offset(); //start bit - uint32_t l_end = l_start + l_length - 1; //end bit - //cout << "ScomList::listing: offset " << dec << l_start - // << " end " << l_end << " length " << l_length << endl; - - //loop through all the matches and check for duplicate bits - for (i = ret.first; i != ret.second; ++i) - { - uint32_t l_length2 = i->second->get_scom_length(); - - //If writing all bits - if (l_length2 == 0) - { - l_dup_scoms = true; - break; - } - - uint32_t l_start2 = i->second->get_scom_offset(); //start bit - uint32_t l_end2 = l_start2 + l_length2 - 1; //end bit - //cout << "ScomList::listing: offset2 " << l_start2 - // << " end2 " << l_end2 << " length2 " << l_length2 << endl; - - // check for duplicate bits - if ((l_start <= l_end2) && (l_start2 <= l_end)) - { - // ranges overlap - l_dup_scoms = true; - break; - } - } - } - } - - if (false == l_dup_scoms) - { - l_scom_list.insert(pair<uint64_t,Scom *>(l_addr, s)); - //cout << "ScomList::listing: l_scom_list size " << l_scom_list.size() << endl; - } - else - { - ostringstream oss; - oss << "ScomList::listing: Duplicate scom statements found: " - "Address 0x" << hex << l_addr << endl; - throw invalid_argument(oss.str()); - } - } - - //Free memory - for (i = l_scom_list.begin(); i != l_scom_list.end(); ++i) - { - delete i->second; - } - l_scom_list.clear(); - } - - dbg << "======================= End Listing ========================" << endl; -} - -//------------------------------------------------------------------------------------------------- - -void ScomList::attr_listing(BINSEQ & bin_seq,ostream & olist) -{ - olist << iv_symbols->attr_listing(); -} - -//------------------------------------------------------------------------------------------------- - -string ScomList::fmt8(uint32_t val) -{ - ostringstream oss; - oss << setfill('0'); - oss << "0x" << hex << setw(8) << val << "\t " << '[' << dec << val << ']' << '\t'; - if(val < 1000) oss << '\t'; - return oss.str(); -} - - -//------------------------------------------------------------------------------------------------- - -void ScomList::insert(Scom * i_scom) -{ - uint64_t l_addr = i_scom->get_address(); - iv_scom_list.insert(pair<uint64_t, Scom *>(l_addr, i_scom)); -} - -//------------------------------------------------------------------------------------------------- - -bool ScomList::compare(ScomList & that) -{ - bool result = true; - dbg << "======================= Begin Compare ========================" << endl; - if(iv_scom_list.size() != that.iv_scom_list.size()) - { - cout << "E> Lists are not the same size" << endl; - result = false; - } - - // check each spy section - for(SCOM_LIST::iterator i = iv_scom_list.begin(); i != iv_scom_list.end(); ++i) - { - // The name checks spyname, arrayaddr (if array), bitrange(s) (if any) - uint64_t l_addr = i->second->get_address(); - SCOM_LIST::iterator j = that.iv_scom_list.find(l_addr); - if(j == that.iv_scom_list.end()) - { - cout << "E> " << l_addr << " not found in both lists!" << endl; - result = false; - continue; - } - if(i->second->compare(*(j->second)) == false) - { - cout << "E> Spy: " << l_addr << " does not match!" << endl; - result = false; - } - } - - // check for spies in that that are not in this - for(SCOM_LIST::iterator i = that.iv_scom_list.begin(); i != that.iv_scom_list.end(); ++i) - { - uint64_t l_addr = i->second->get_address(); - SCOM_LIST::iterator j = iv_scom_list.find(l_addr); - if(j == iv_scom_list.end()) - { - cout << "E> " << l_addr << " not found in both lists!" << endl; - result = false; - } - } - dbg << "======================= End Compare ========================" << endl; - return result; -} - -//------------------------------------------------------------------------------------------------- - -//------------------------------------------------------------------------------------------------- - -void Scom::set_scom_address(const string & i_scom_addr) -{ - - if(iv_scom_addr.size()) - { - yyerror("Scom::set_scom_address: SCOM Address already set!"); - } - else - { - iv_scom_addr.push_back(i_scom_addr); - // cout << "I>Scom::set_scom_address: " << i_scom_addr << " is the output string!" << endl; - } -} - -//------------------------------------------------------------------------------------------------- - - -void Scom::dup_scom_address(const string & i_scom_addr) -{ - // cout << "I>Scom::dup_scom_address: "<< i_scom_addr << " is the output string!" << endl; - - //If we have a range of values - size_t l_pos = i_scom_addr.find(".."); - if (l_pos != string::npos) - { - // Convert the range specified to decimal values and check for valid range - uint64_t l_num1 = strtoull((i_scom_addr.substr(0,l_pos)).c_str(), NULL, 16); - uint64_t l_num2 = strtoull((i_scom_addr.substr(l_pos + 2)).c_str(), NULL, 16); - // cout << "I>Scom:dup_scom_address: " << l_num1 << " - " << l_num2 << endl; - if (l_num1 >= l_num2) - { - std::ostringstream oss; - oss << "Scom::dup_scom_address: Invalid scom address range: " << i_scom_addr; - yyerror(oss.str().c_str()); - } - - for (uint64_t num = l_num1; num <= l_num2; num++) - { - // For each value within the range, create a hex string of the correct size - string l_scom_addr = dec2hexString(num, l_pos); - - if (iv_scom_addr.size() == 0) - { - // If there are no base address, create the duplicate addresses by pushing back - // each value within the range - iv_dup_scom_addr.push_back(l_scom_addr); - // cout << "I>Scom::dup_scom_address: iv_dup_scom_addr" << iv_dup_scom_addr.back() << endl; - } - else - { - // If there are base addresses, create the dupicate addresses by appending each - // value within the range to the base addresses. - for (size_t i = 0; i < iv_scom_addr.size(); i++) - { - iv_dup_scom_addr.push_back(iv_scom_addr.at(i) + l_scom_addr); - // cout << "I>Scom::dup_scom_address: iv_dup_scom_addr " << iv_dup_scom_addr.back() << endl; - } - } - } - } - // Else we have a single value - else - { - // If there are no base address, create the duplicate address by pushing back the specified - // value - if (iv_scom_addr.size() == 0) - { - iv_dup_scom_addr.push_back(i_scom_addr); - // cout << "I>Scom::dup_scom_address: iv_dup_scom_addr " << iv_dup_scom_addr.back() << endl; - } - else - { - // If there are base addresses, create the dupicate addresses by appending the - // specified value to the base addresses. - for (size_t i = 0; i < iv_scom_addr.size(); i++) - { - iv_dup_scom_addr.push_back(iv_scom_addr.at(i) + i_scom_addr); - // cout << "I>Scom::dup_scom_address: iv_dup_scom_addr " << iv_dup_scom_addr.back() << endl; - } - } - } -} - -//------------------------------------------------------------------------------------------------- - -void Scom::copy_dup_scom_address() -{ - // cout << "I>Scom::copy_dup_scom_address: iv_scom_addr size "<< iv_scom_addr.size() - // << " iv_dup_scom_addr size " << iv_dup_scom_addr.size() << endl; - - iv_scom_addr.clear(); - iv_scom_addr = iv_dup_scom_addr; - iv_dup_scom_addr.clear(); - - // cout << "I>Scom::copy_dup_scom_address: iv_scom_addr size "<< iv_scom_addr.size() - // << " iv_dup_scom_addr size " << iv_dup_scom_addr.size() << endl; -} - -//------------------------------------------------------------------------------------------------- - -void Scom::set_scom_suffix(const string & i_scom_addr) -{ - - if(iv_scom_addr.size() == 0) - { - std::ostringstream oss; - oss << "Scom::set_scom_suffix: No base scom address to append suffix " << i_scom_addr; - yyerror(oss.str().c_str()); - } - else - { - // cout << "I>Scom::set_scom_suffix: iv_scom_addr size " << iv_scom_addr.size() << endl; - for(size_t i = 0; i < iv_scom_addr.size(); ++i) - { - // cout << "I>Scom::set_scom_suffix: iv_scom_addr " << iv_scom_addr.at(i) << endl; - iv_scom_addr.at(i) = iv_scom_addr.at(i) + i_scom_addr; - // cout << "I>Scom::set_scom_suffix: iv_scom_addr appended " << iv_scom_addr.at(i) << endl; - } - } - - // cout << "I>Scom::set_scom_suffix: "<< i_scom_addr << " is the output string!" << endl; -} - -//------------------------------------------------------------------------------------------------- - -void Scom::set_scom_address_bin(const string & i_scom_addr) -{ - - if(iv_scom_addr_bin.size()) - { - yyerror("Scom::set_scom_address_bin: Binary SCOM Address already set!"); - } - else - { - iv_scom_addr_bin.push_back(i_scom_addr); - } - - // cout << "I>Scom::set_scom_address_bin: " << i_scom_addr << " is the output string!" << endl; -} - -//------------------------------------------------------------------------------------------------- - -void Scom::dup_scom_address_bin(const string & i_scom_addr) -{ - // cout << "I>Scom::dup_scom_address_bin: "<< i_scom_addr << " is the output string!" << endl; - - //If we have a range of values - size_t l_pos = i_scom_addr.find(".."); - if (l_pos != string::npos) - { - // Convert the range specified to decimal values and check for valid range - uint64_t l_num1 = strtoull((i_scom_addr.substr(0,l_pos)).c_str(), NULL, 2); - uint64_t l_num2 = strtoull((i_scom_addr.substr(l_pos + 2)).c_str(), NULL, 2); - // cout << "I>Scom:dup_scom_address_bin: " << l_num1 << " - " << l_num2 << endl; - if (l_num1 >= l_num2) - { - std::ostringstream oss; - oss << "Scom::dup_scom_address_bin: Invalid binary scom address range: " - << i_scom_addr; - yyerror(oss.str().c_str()); - } - - for (uint64_t num = l_num1; num <= l_num2; num++) - { - // For each value within the range, create a binary string of the correct size - string l_scom_addr = dec2binString(num, l_pos); - - if (iv_scom_addr_bin.size() == 0) - { - // If there are no base address, create the duplicate addresses by pushing back - // each value within the range - iv_dup_scom_addr_bin.push_back(l_scom_addr); - // cout << "I>Scom::dup_scom_address_bin: iv_dup_scom_addr_bin " << iv_dup_scom_addr_bin.back() << endl; - } - else - { - // If there are base addresses, create the dupicate addresses by appending each - // value within the range to the base addresses. - for (size_t i = 0; i < iv_scom_addr_bin.size(); i++) - { - iv_dup_scom_addr_bin.push_back(iv_scom_addr_bin.at(i) + l_scom_addr); - // cout << "I>Scom::dup_scom_address_bin: iv_dup_scom_addr_bin " << iv_dup_scom_addr_bin.back() << endl; - } - } - } - } - // Else we have a single value - else - { - // If there are no base address, create the duplicate address by pushing back the specified - // value - if (iv_scom_addr_bin.size() == 0) - { - iv_dup_scom_addr_bin.push_back(i_scom_addr); - // cout << "I>Scom::dup_scom_address_bin: iv_dup_scom_addr_bin " << iv_dup_scom_addr_bin.back() << endl; - } - else - { - // If there are base addresses, create the dupicate addresses by appending the - // specified value to the base addresses. - for (size_t i = 0; i < iv_scom_addr_bin.size(); i++) - { - iv_dup_scom_addr_bin.push_back(iv_scom_addr_bin.at(i) + i_scom_addr); - // cout << "I>Scom::dup_scom_address_bin: iv_dup_scom_addr_bin " << iv_dup_scom_addr_bin.back() << endl; - } - } - } -} - -//------------------------------------------------------------------------------------------------- - -void Scom::copy_dup_scom_address_bin() -{ - // cout << "I>Scom::copy_dup_scom_address_bin: iv_scom_addr_bin size "<< iv_scom_addr_bin.size() - // << " iv_dup_scom_addr_bin size " << iv_dup_scom_addr_bin.size() << endl; - - iv_scom_addr_bin.clear(); - iv_scom_addr_bin = iv_dup_scom_addr_bin; - iv_dup_scom_addr_bin.clear(); - - // cout << "I>Scom::copy_dup_scom_address_bin: iv_scom_addr_bin size "<< iv_scom_addr_bin.size() - // << " iv_dup_scom_addr_bin size " << iv_dup_scom_addr_bin.size() << endl; -} - -//------------------------------------------------------------------------------------------------- - -void Scom::set_scom_suffix_bin(const string & i_scom_addr) -{ - - if(iv_scom_addr_bin.size() == 0) - { - std::ostringstream oss; - oss << "Scom::set_scom_suffix_bin: No base binary scom address to append suffix " - << i_scom_addr; - yyerror(oss.str().c_str()); - } - else - { - for(size_t i = 0; i < iv_scom_addr_bin.size(); ++i) - { - iv_scom_addr_bin.at(i) = iv_scom_addr_bin.at(i) + i_scom_addr; - } - } - - // cout << "I>Scom::set_scom_suffix_bin: "<< i_scom_addr << " is the output string!" << endl; -} - -//------------------------------------------------------------------------------------------------- - -void Scom::append_scom_address_bin() -{ - for (size_t i = 0; i < iv_scom_addr_bin.size(); i++) - { - if (0 != (iv_scom_addr_bin.at(i).size() % 4)) - { - std::ostringstream oss; - oss << "Scom::append_scom_address_bin: Binary scom address " - << iv_scom_addr_bin.at(i) << " is a partial hex!"; - yyerror(oss.str().c_str()); - break; - } - else - { - // Duplicate the scom addresses - uint64_t l_num = strtoull(iv_scom_addr_bin.at(i).c_str(), NULL, 2); - string l_scom_addr = dec2hexString(l_num, iv_scom_addr_bin.at(i).size() / 4); - dup_scom_address(l_scom_addr); - } - } - - if (iv_dup_scom_addr.size()) - { - // Copy duplicate scom addresses to the base scom addresses - copy_dup_scom_address(); - iv_scom_addr_bin.clear(); - } -} - -//------------------------------------------------------------------------------------------------- -string Scom::dec2hexString(uint64_t i_num, size_t i_str_size) -{ - stringstream l_ss; - l_ss.width(i_str_size); // Set string width - l_ss.fill('0'); // Prefill with '0' - l_ss << hex << i_num; - - return l_ss.str(); -} - -//------------------------------------------------------------------------------------------------- -string Scom::dec2binString(uint64_t i_num, size_t i_str_size) -{ - size_t l_size = sizeof(i_num) * 8; - char l_buf[l_size]; - size_t l_idx = l_size; - - do - { - l_buf[--l_idx] = '0' + (i_num & 1); - i_num >>= 1; - } while (--i_str_size); - - return string(l_buf + l_idx, l_buf + l_size); -} - -string Scom::addr_listing() -{ - std::stringstream l_ss; - l_ss << "\t\t\tSCOM Addresses" << endl; - //l_ss << std::hex << std::setfill('0'); - - for (size_t i = 0; i < iv_scom_addr.size(); i++) - { - //l_ss << "0x" << std::setw(16) << op_id << "\t\t" << OP_TXT[op_id] << std::endl; - l_ss << iv_scom_addr.at(i) << endl; - } - return l_ss.str(); -} diff --git a/src/usr/hwpf/ifcompiler/initScom.H b/src/usr/hwpf/ifcompiler/initScom.H deleted file mode 100755 index 5b342d5ad..000000000 --- a/src/usr/hwpf/ifcompiler/initScom.H +++ /dev/null @@ -1,333 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/hwpf/ifcompiler/initScom.H $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2011,2014 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -#if !defined(INITSPY_H) -#define INITSPY_H - -// Change Log ************************************************************************************* -// -// Flag Track Userid Date Description -// ----- -------- -------- -------- ------------------------------------------------------------- -// D754106 dgilbert 06/14/10 Create -// dg002 SW039868 dgilbert 10/15/10 Add support to filter unneeded inits by EC -// dg003 SW047506 dgilbert 12/09/10 More filtering enhancements -// andrewg 05/24/11 Port over for VPL/PgP -// andrewg 09/19/11 Updates based on review -// mjjones 11/17/11 Output attribute listing -// camvanng 12/12/11 Support multiple address ranges within a SCOM address -// Use strtoull vs strtoul for 32-bit platforms -// camvanng 12/15/11 Support for multiple duplicate addresses setting different bits -// camvanng 01/20/12 Support for using a range of indexes for array attributes -// camvanng 02/14/12 Support binary and hex scom addresses -// camvanng 04/16/12 Support defines for SCOM address -// Support defines for bits, scom_data and attribute columns -// Delete obsolete code for defines support -// camvanng 06/27/12 Improve error and debug tracing -// End Change Log ********************************************************************************* -// $Id: initScom.H,v 1.9 2014/06/30 20:19:48 thi Exp $ -/** - * @file initSpy.H - * @brief Declairation of the initSpy Class. Represents the information parsed from an initfile spy - * statement. - */ - -#include <stdint.h> -#include <stdlib.h> -#include <string> -#include <vector> -#include <map> -#include <set> -#include <initRpn.H> -#include <initSymbols.H> - - -using namespace std; - -namespace init -{ - typedef vector<string> SCOM_ADDR; - typedef vector<Rpn> RPN_LIST; - typedef vector<RPN_LIST> COL_LIST; - typedef vector<uint32_t> VAR_LIST; - typedef pair<uint32_t,uint32_t> RANGE; - typedef vector<RANGE> RANGE_LIST; - - enum SCOM_WHEN - { - NONE = 0x00000000, - - // WHEN= types - LONG_SCAN = 0x00000001, - SCOM = 0x00000002, - DRAMINIT = 0x00000003, - CFAMINIT = 0x00000004, - LAST_WHEN_TYPE = CFAMINIT, - WHEN_MASK = 0x000000FF, - - // WHEN= sub types - SUBTYPE_MASK = 0x0000F000, - HOT_ADD_NODE = 0x00004000, - AFTER_HOT_ADD_NODE = 0x00006000, - HOT_ADD_GX = 0x00008000, - HOT_ADD_GX0 = 0x00007000, - HOT_ADD_GX1 = 0x00005000, - AFTER_HOT_ADD_GX = 0x0000A000, - AFTER_HOT_ADD_GX0 = 0x00003000, - AFTER_HOT_ADD_GX1 = 0x00002000, - }; - - const char when_char[] = { '@','L','S','D','C' }; - - class Scom - { - public: - - enum SPY_TYPE - { - NOTYPE, - ISPY, - ESPY, - ARRAY - }; - - - Scom(Symbols * i_symbols,uint32_t i_line = 0) : - iv_symbols(i_symbols), - iv_line(i_line), - iv_scom_length(0), - iv_scom_offset(0), - iv_when(NONE) {} - - // Build from binary sequence - Scom(BINSEQ::const_iterator & bli, Symbols * i_symbols); - - bool compare(Scom & that); - uint32_t get_when(void) { return(iv_when); } - void set_when(SCOM_WHEN i_when) { iv_when |= (uint32_t)i_when; } - void set_when(const string * when_str); - bool do_when(SCOM_WHEN i_when) { return ((uint32_t)i_when == (WHEN_MASK & iv_when)); } - void set_sub_when(SCOM_WHEN i_when) { iv_when |= i_when; } - void set_when_rpn(const Rpn * i_rpn) { iv_when_rpn = *i_rpn; delete i_rpn; } - uint32_t get_line() { return iv_line; } - void add_scom_rpn(const Rpn * i_rpn) { iv_scom_rpn.push_back(*i_rpn); delete i_rpn; } - - - - /** - * Is when statement valid for this spy - * @param stats: ostream to print debug information - * @param ec restriction - true if valid for this ec, 0xffffffff means ANY ec - * @return false if Rpn for when statement resolves to false, otherwise true - */ - bool valid_when(ostream & stats, uint32_t i_ec = 0xffffffff); - - void add_col(const string & i_colname); - - /** - * Add a row rpn to the current column - * @param pointer to Rpn object - * @pre add_col() - */ - void add_row_rpn(Rpn * i_rpn); - - void add_bit_range(uint32_t start, uint32_t end); - void add_target_range(uint32_t r1, uint32_t r2); - void make_target(const char * i_symbol); - - - uint64_t get_address(void) {return(strtoull(iv_scom_addr[0].c_str(),NULL,16));} - - /** - * @brief Get the SCOM address - * @return iv_scom_addr_hex the SCOM address - */ - uint64_t get_address_hex(void) {return iv_scom_addr_hex;} - - /** - * @brief Get the bit offset to start writing the SCOM data - * @return iv_scom_offset the starting bit within the SCOM to write the data - */ - uint32_t get_scom_offset(void) {return iv_scom_offset;} - - /** - * @brief Get the total number of bits to write - * @return iv_scom_length the number of bits to write - */ - uint32_t get_scom_length(void) {return iv_scom_length;} - - // string name(); - string listing(); - - /** - * Append binary listing of this Spy - * @param when [init::LONG_SCAN | init::SCOM] - * @param BINSEQ binary listing to append - * @returns uint32_t number of spies added - */ - uint32_t bin_listing(BINSEQ & blist); - - void set_scom_address(const string & i_scom_addr); - void dup_scom_address(const string & i_scom_addr); - void copy_dup_scom_address(); - void set_scom_suffix(const string & i_scom_addr); - - /** - * @brief Set the binary SCOM address - * @param i_scom_addr binary address string - */ - void set_scom_address_bin(const string & i_scom_addr); - - /** - * @brief Create duplicate binary SCOM addresses and append input address string - * @param i_scom_addr binary address string - */ - void dup_scom_address_bin(const string & i_scom_addr); - - /** - * @brief Copy duplicate binary SCOM addresses to main binary address vector - */ - void copy_dup_scom_address_bin(); - - /** - * @brief Append the input binary address string to the binary address - * @param i_scom_addr binary address string - */ - void set_scom_suffix_bin(const string & i_scom_addr); - - /** - * @brief Append the binary address to the hex address - */ - void append_scom_address_bin(); - - /** - * @brief Convert decimal to hex string - * @param i_num decimal number - * @param i_str_size string size - */ - string dec2hexString(uint64_t i_num, size_t i_str_size); - - /** - * @brief Convert decimal to bin string - * @param i_num decimal number - * @param i_str_size string size - */ - string dec2binString(uint64_t i_num, size_t i_str_size); - - /** - * @brief Return scom address strings - */ - string addr_listing(); - - private: // functions - - string list_one(RANGE range); - void bin_list_one(BINSEQ & blist,uint64_t i_addr, uint32_t i_addr_num, RANGE range); - - /** - * Optimize the row RPNs - * @note Remove any rows that resolve to unconditionally false. - */ - void row_optimize(); - - private: // data - - typedef map<string,SCOM_WHEN> WHEN_SUBTYPE_MAP; - - SCOM_ADDR iv_scom_addr; - SCOM_ADDR iv_dup_scom_addr; ///< contains the duplicate scom addresses - uint64_t iv_scom_addr_hex; - SCOM_ADDR iv_scom_addr_bin; ///< temp storage for binary scom addresses - SCOM_ADDR iv_dup_scom_addr_bin; ///< contains the duplicate binary scom addresses - uint32_t iv_scom_length; - uint32_t iv_scom_offset; - RPN_LIST iv_scom_rpn; ///< spyv - for each row - RPN_LIST iv_col_vars; ///< RPNs of column name for each column - COL_LIST iv_cols_rpn; ///< A list of row rpn segments one rpn list for each column - RPN_LIST iv_row_rpn; ///< row rpns for current column being parsed. - RANGE_LIST iv_range_list; ///< bit range list - RANGE_LIST iv_target_ranges; ///< target range for current target begin parsed. - Symbols * iv_symbols; - uint32_t iv_line; ///< line # in the initfile - uint32_t iv_when; - Rpn iv_when_rpn; - - - static WHEN_SUBTYPE_MAP cv_when_subtypes; - - }; - - - //================================================================================================= - // SpyList Class declarations - //================================================================================================= - // Container to track scoms - typedef multimap<uint64_t, init::Scom *> SCOM_LIST; - - class ScomList - { - public: - ScomList(const string & initfile, FILELIST & defines, ostream & stats, uint32_t i_ec = 0xFFFFFFFF); - ~ScomList(); - //size_t size() { return iv_spy_list.size(); } - //SPY_LIST::iterator begin() { return iv_spy_list.begin(); } - //SPY_LIST::iterator end() { return iv_spy_list.end(); } - void clear(); - void insert(Scom * i_scom); - - void compile(BINSEQ & bin_seq); - - void listing(BINSEQ & bin_seq, ostream & out); - void attr_listing(BINSEQ & bin_seq, ostream & out); - - /** - * Compare two spylists for equivalance - * @returns true if equal - * @note Both spylists should have been built from a binary sequence - * not directly from an initfile - */ - bool compare(ScomList & that); - - - - void set_cvs_versions(const string * s) { iv_cvs_versions = *s; } - void set_syntax_version(uint32_t v); - size_t get_syntax_version() { return iv_syntax_version; } - - Symbols * get_symbols() { return iv_symbols; } - - private: // functions - - string fmt8(uint32_t val); - - private: - - SCOM_LIST iv_scom_list; - string iv_cvs_versions; - uint32_t iv_syntax_version; - Symbols * iv_symbols; - ostream & iv_stats; - uint32_t iv_ec; - }; -}; -#endif diff --git a/src/usr/hwpf/ifcompiler/initSymbols.C b/src/usr/hwpf/ifcompiler/initSymbols.C deleted file mode 100755 index 5ffbd013e..000000000 --- a/src/usr/hwpf/ifcompiler/initSymbols.C +++ /dev/null @@ -1,1160 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/hwpf/ifcompiler/initSymbols.C $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2011,2014 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -// Change Log ************************************************************************************* -// -// Flag Track Userid Date Description -// ---- -------- -------- -------- ------------------------------------------------------------- -// D754106 dgilbert 06/14/10 Create -// dgilbert 10/22/10 Add spies_are_in() -// andrewg 09/19/11 Updates based on review -// camvanng 11/08/11 Added support for attribute enums -// andrewg 11/09/11 Multi-dimensional array and move to common fapi include -// mjjones 11/17/11 Output attribute listing -// camvanng 11/17/11 Support for system & target attributes -// camvanng 01/07/12 Support for writing an attribute to a SCOM register -// camvanng 04/10/12 Support fixed attribute enum value -// camvanng 04/16/12 Support defines for SCOM address -// Support defines for bits, scom_data and attribute columns -// Delete obsolete code for defines support -// camvanng 05/07/12 Support for associated target attributes -// camvanng 06/27/12 Improve error and debug tracing -// Add get_numeric_array_data() -// End Change Log ********************************************************************************* -// $Id: initSymbols.C,v 1.8 2014/06/30 20:27:49 thi Exp $ -/** - * @file initSymbols.C - * @brief Definition of the initSymbols class. Handles all symbols for initfiles - */ - -#include <initSymbols.H> -#include <initRpn.H> -#include <sstream> -#include <iomanip> -#include <iostream> -#include <fstream> -#include <stdexcept> -#include <stdlib.h> - -using namespace init; - -ostringstream errss; - -#define SYM_EXPR 0x10000000 -const string SYS_ATTR = "SYS."; - -// ------------------------------------------------------------------------------------------------ - -Symbols::Symbols(FILELIST & i_filenames) - : iv_used_var_count(1), iv_used_lit_count(1), iv_rpn_id(1) -{ - string fileline; - - for(FILELIST::iterator fn = i_filenames.begin(); fn != i_filenames.end(); ++fn) - { - printf("Parsing file %s\n",fn->c_str()); - uint32_t lineno = 0; - ifstream infs(fn->c_str()); - if(!infs) - { - errss.str(""); - errss << "ERROR! Symbols::Symbols: Could not open " - << *fn << endl; - throw invalid_argument(errss.str()); - } - while(getline(infs,fileline)) - { - ++lineno; - if(fileline.size() == 0) continue; - if(fileline[0] == '/') continue; - istringstream iss(fileline); - string def; - iss >> def; - //printf("def: %s\n",def.c_str()); - if(def == "enum") - { - // Make sure it's the AttributeId enum - iss >> def; - if(def == "AttributeId") - { - // We've now found the beginning of the attribute enum definition - // Read and skip the '{' on the next line - getline(infs,fileline); - getline(infs,fileline); - - while(fileline[0] != '}') - { - istringstream attr_stream(fileline); - string attr; - char tempChar = 0; - uint32_t attrId = 0; - - // Read the attribute name - attr_stream >> attr; - - // Read and ignore the '=' '0' 'x' characters - attr_stream >> tempChar; - attr_stream >> tempChar; - attr_stream >> tempChar; - - // Read the attribute ID - attr_stream >> hex >> attrId; - - // Store the value - iv_symbols[attr] = MAP_DATA(attrId,NOT_USED); - - getline(infs,fileline); - } - } - else - { - // Make sure it's an attribute enum - - string attribute_enum_name; - string find_enum = "_Enum"; - - // Check for _Enum in the name - size_t pos = def.find(find_enum); - if(pos != string::npos) - { - // We've now found the beginning of the attribute enum definition - // Read and skip the '{' on the next line - getline(infs,fileline); - getline(infs,fileline); - - // We're just parsing the enum in order so values start - // at 0 and increment by 1 after that unless they are - // explicitly assigned. - uint64_t value = 0; - - while(fileline[0] != '}') - { - istringstream attr_enum_stream(fileline); - string attr_enum; - string tmp; - - // Get the attribute enum name - attr_enum_stream >> attr_enum; - - // Strip off the "," at the end. - pos = attr_enum.find(','); - if(pos != string::npos) - { - attr_enum = attr_enum.substr(0,attr_enum.length()-1); - } - else - { - // Is a value for the enum specified? - attr_enum_stream >> tmp; - - if (!attr_enum_stream.eof()) - { - //Make sure it's an '=' - if ("=" != tmp) - { - printf ("ERROR: Unknown attribute enum! %s\n",attr_enum.c_str()); - exit(1); - } - else - { - attr_enum_stream >> tmp; - value = strtoull(tmp.c_str(), NULL, 0); - } - } - } - - //printf("Attribute Enum String:%s Value %u\n",attr_enum.c_str(), value); - - // Get a value for the string - iv_attr_enum[attr_enum] = value; - value++; - getline(infs,fileline); - } - } - } - } - else if(def == "typedef") - { - string type; - string attribute_name; - string find_type = "_Type"; - string find_array = "["; - uint32_t array = 0; - iss >> type; - iss >> attribute_name; - if(attribute_name == "*") - { - // It's a pointer type so read in the next string - iss >> attribute_name; - type = type + "*"; - } - //printf("typedef: type:%s attribute_name:%s\n",type.c_str(),attribute_name.c_str()); - - // Determine how many (if any) dimensions this array has - size_t pos = attribute_name.find(find_array); - while(pos != string::npos) - { - array++; - pos = attribute_name.find(find_array,pos+1); - } - - // Now strip off the _type in the name - pos = attribute_name.find(find_type); - if(pos != string::npos) - { - attribute_name = attribute_name.substr(0,pos); - } - else - { - printf ("ERROR: Unknown attribute type! %s\n",attribute_name.c_str()); - exit(1); - } - - iv_attr_type[attribute_name] = get_attr_type(type,array); - //printf("Attribute %s Type with array dimension %u for %s is %u\n",attribute_name.c_str(),array, - // type.c_str(),get_attr_type(type,array)); - } - } - infs.close(); - } - iv_rpn_map[Rpn::SYMBOL | INIT_EXPR_VAR] = RPN_DATA("EXPR",SYM_EXPR); - iv_rpn_map[Rpn::SYMBOL | INIT_ANY_LIT] = RPN_DATA("ANY",CINI_LIT_MASK); -} - -uint32_t Symbols::get_attr_type(const string &i_type, const uint32_t i_array) -{ - uint32_t l_type = 0; - - if (i_type == "uint8_t") - { - l_type = SYM_ATTR_UINT8_TYPE; - } - else if(i_type == "uint32_t") - { - l_type = SYM_ATTR_UINT32_TYPE; - } - else if(i_type == "uint64_t") - { - l_type = SYM_ATTR_UINT64_TYPE; - } - else - { - printf("Unknown data type: %s\n",i_type.c_str()); - exit(-1); - } - - if(i_array > MAX_ATTRIBUTE_ARRAY_DIMENSION) - { - printf("Array dimension size for %s %u exceeded maximum dimension of %u\n", - i_type.c_str(),i_array,MAX_ATTRIBUTE_ARRAY_DIMENSION); - exit(-1); - } - // See enum definition on why this works - l_type += (i_array*ATTR_DIMENSION_SIZE_MULT)+i_array; - - return(l_type); -} - -uint32_t Symbols::get_attr_type(const uint32_t i_rpn_id) -{ - string l_attr_name = find_name(i_rpn_id); - return(iv_attr_type[l_attr_name]); -} - -// ------------------------------------------------------------------------------------------------ - -uint32_t Symbols::use_symbol(string & i_symbol) -{ - uint32_t rpn_id = Rpn::SYMBOL | NOT_FOUND; - string l_symbol = i_symbol; - - if(i_symbol == "ANY") rpn_id = INIT_ANY_LIT | Rpn::SYMBOL; - else if(i_symbol == "EXPR") rpn_id = INIT_EXPR_VAR | Rpn::SYMBOL; - else - { - SYMBOL_MAP::iterator i = iv_symbols.find(i_symbol); - if(i != iv_symbols.end()) - { - if(i->second.second == NOT_USED) - { - rpn_id = Rpn::SYMBOL | iv_rpn_id++; - i->second.second = rpn_id; - iv_rpn_map[rpn_id] = RPN_DATA(i_symbol,i->second.first); - - //printf ("Symbols::use_symbol: Just added %s symbol, rpn_id:0x%8X to iv_rpn_map\n",i_symbol.c_str(),rpn_id); - - if(i->second.first & CINI_LIT_MASK) ++iv_used_lit_count; - else ++iv_used_var_count; - } - else - { - rpn_id = i->second.second; - } - } - else - { - //Strip off any prefix (i.e. "SYS." or "TGT<#>.") - size_t pos = i_symbol.find('.'); - if(pos != string::npos) - { - //Find the attribute without the prefix. - //If found, then add this system or assoc target attribute - //to our containers. - l_symbol = i_symbol.substr(pos+1); - SYMBOL_MAP::iterator i = iv_symbols.find(l_symbol); - if(i != iv_symbols.end()) - { - //Add the new attribute - - rpn_id = Rpn::SYMBOL | iv_rpn_id++; - uint32_t attrId = iv_symbols[l_symbol].first; - - iv_rpn_map[rpn_id] = RPN_DATA(i_symbol,attrId); - iv_symbols[i_symbol] = MAP_DATA(attrId, rpn_id); - iv_attr_type[i_symbol] = iv_attr_type[l_symbol]; - - ++iv_used_var_count; - - //printf ("Symbols::use_symbol: Just added %s symbol, rpn_id:0x%8X\n",i_symbol.c_str(),rpn_id); - } - else - { - rpn_id = add_undefined(i_symbol); - } - } - else - { - rpn_id = add_undefined(i_symbol); - } - } - } - - return rpn_id; -} - -// ------------------------------------------------------------------------------------------------ - -uint32_t Symbols::add_undefined(const string & i_symbol) -{ - uint32_t rpn_id = 0; - - SYMBOL_MAP::iterator i = iv_not_found.find(i_symbol); - if(i != iv_not_found.end()) - { - rpn_id = i->second.second; - } - else - { - rpn_id = Rpn::SYMBOL | iv_rpn_id++; - iv_not_found[i_symbol] = MAP_DATA(NOT_FOUND,rpn_id); - iv_rpn_map[rpn_id] = RPN_DATA(i_symbol,CINI_ID_NOT_FOUND); - } - return rpn_id; -} - -// ------------------------------------------------------------------------------------------------ - -uint16_t Symbols::get_tag(uint32_t i_rpn_id) -{ - uint16_t tag = NOT_FOUND; - - // Set up tag table if not already setup - if(iv_used_var.size() == 0) - { - iv_used_var.reserve(iv_used_var_count); // makes if faster - iv_used_lit.reserve(iv_used_lit_count); - - //To differentiate between system, target, and associated target attributes - //which have the same attribute id, save the attribute name also. - iv_used_var.push_back(RPN_DATA("EXPR",SYM_EXPR)); // EXPR var always first - iv_used_lit.push_back(iv_rpn_map[Rpn::SYMBOL|INIT_ANY_LIT].second); // ANY lit always first - - for(SYMBOL_MAP::iterator i = iv_symbols.begin(); i != iv_symbols.end(); ++i) - { - if(i->second.second != NOT_USED) - { - //printf("Symbols::get_tag adding rpn_id[0x%x]\n", i->second.second); - - if((i->second.first & CINI_LIT_MASK) == CINI_LIT_MASK) - { - iv_used_lit.push_back(i->second.first); - //printf("Symbols::get_tag added to iv_used_lit[0x%x]\n", iv_used_lit.back()); - } - else //VAR - { - iv_used_var.push_back(RPN_DATA(i->first, i->second.first)); - //printf("Symbols::get_tag added to iv_used_var[%s, 0x%x]\n", - // iv_used_var.back().first.c_str(), iv_used_var.back().second); - } - } - } - } - - do - { - string name = find_name(i_rpn_id); - if ("NOT_FOUND" == name) - { - //SYMBOL_MAP::iterator sm = iv_not_found.begin(); - //for(; sm != iv_not_found.end(); ++sm) - //{ - // if((sm->second).second == i_rpn_id) - // { - // break; - // } - //} - - //if(sm == iv_not_found.end()) - //{ - ostringstream err; - err << hex; - err << "ERROR! Symbols::get_tag() bad arg rpn_id = " << i_rpn_id << endl; - throw invalid_argument(err.str()); - //} - break; - } - - uint32_t offset = 0; - for(VAR_SYMBOL_USED::iterator i = iv_used_var.begin(); i != iv_used_var.end(); ++i,++offset) - { - if (name == (*i).first) - { - if (name.compare(0, ASSOC_TGT_ATTR.length(), ASSOC_TGT_ATTR) == 0) - { - tag = (uint16_t) (offset | IF_ASSOC_TGT_ATTR_TYPE); - } - else if (name.compare(0, SYS_ATTR.length(), SYS_ATTR) == 0) - { - tag = (uint16_t) (offset | IF_SYS_ATTR_TYPE); - } - else - { - tag = (uint16_t) (offset | IF_ATTR_TYPE); - } - - //printf ("get tag: %s tag 0x%x\n", name.c_str(), tag); - break; - } - } - - } while(0); - - return tag; -} - - - - -// ------------------------------------------------------------------------------------------------ - -string Symbols::find_name(uint32_t i_rpn_id) -{ - string name; - RPN_MAP::iterator rm = iv_rpn_map.find(i_rpn_id); - if(rm != iv_rpn_map.end()) - { - name = (rm->second).first; - } - else name = "NOT FOUND"; - return name; -} - -// ------------------------------------------------------------------------------------------------ - -uint32_t Symbols::find_numeric_lit(uint64_t i_data, int32_t byte_size) -{ - uint32_t offset = 0; - LIT_LIST::iterator i = iv_lits.begin(); - for(; i != iv_lits.end(); ++i,++offset) - { - if(i_data == i->first && (uint32_t)byte_size == i->second) - break; - } - if(i == iv_lits.end()) - { - iv_lits.push_back(LIT_DATA(i_data,byte_size)); - } - //printf("Symbols::find_numeric_lit: i_data:0x%llX byte_size:%d Tag:0x%X\n", - // i_data,byte_size, offset | Rpn::NUMBER); - return offset | Rpn::NUMBER; -} - -uint32_t Symbols::find_numeric_array_lit(uint64_t i_data, int32_t byte_size) -{ - uint32_t offset = 0; - LIT_LIST::iterator i = iv_lits.begin(); - for(; i != iv_lits.end(); ++i,++offset) - { - if(i_data == i->first && (uint32_t)byte_size == i->second) - break; - } - if(i == iv_lits.end()) - { - iv_lits.push_back(LIT_DATA(i_data,byte_size)); - } - //printf("Symbols::find_numeric_lit: i_data:0x%llX byte_size:%d Tag:0x%X\n", - // i_data,byte_size, offset | Rpn::NUMBER); - return offset | Rpn::ARRAY_INDEX; -} - -// ------------------------------------------------------------------------------------------------ - -uint16_t Symbols::get_numeric_tag(uint32_t i_rpn_id) -{ - uint32_t tag = NOT_FOUND; - uint32_t offset = i_rpn_id - Rpn::NUMBER; - string any("ANY"); - if(iv_used_lit.size() == 0) get_tag(use_symbol(any)); - if(offset < iv_lits.size()) - { - // numeric lits are numbered after enum lits, but with different TYPE - tag = (iv_used_lit.size() + offset) | IF_NUM_TYPE; - } - else - { - ostringstream err; - err << hex; - err << "ERROR! - Symbols::get_numeric_tag() invalid arg rpn_id = " << i_rpn_id << endl; - throw invalid_argument(err.str()); - } - return (uint16_t)tag; -} - -// ------------------------------------------------------------------------------------------------ - -uint16_t Symbols::get_numeric_array_tag(uint32_t i_rpn_id) -{ - uint32_t tag = NOT_FOUND; - uint32_t offset = i_rpn_id - Rpn::ARRAY_INDEX; - string any("ANY"); - if(iv_used_lit.size() == 0) get_tag(use_symbol(any)); - if(offset < iv_lits.size()) - { - // numeric lits are numbered after enum lits, but with different TYPE - tag = (iv_used_lit.size() + offset) | IF_NUM_TYPE; - } - else - { - ostringstream err; - err << hex; - err << "ERROR! - Symbols::get_numeric_array_tag() invalid arg rpn_id = " << i_rpn_id << endl; - throw invalid_argument(err.str()); - } - return (uint16_t)tag; -} - -// ------------------------------------------------------------------------------------------------ - -uint64_t Symbols::get_numeric_data(uint32_t i_rpn_id, uint32_t & o_size) -{ - uint64_t data = 0; - o_size = 0; - uint32_t offset = i_rpn_id - Rpn::NUMBER; - if(offset < iv_lits.size()) - { - LIT_DATA d = iv_lits[offset]; - data = d.first; - o_size = d.second; - } - else - { - ostringstream err; - err << hex; - err << "ERROR! - Symbols::get_numeric_data() invalid arg rpn_id = " << i_rpn_id << endl; - throw invalid_argument(err.str()); - } - return data; -} - -// ------------------------------------------------------------------------------------------------ - -uint64_t Symbols::get_numeric_array_data(uint32_t i_rpn_id, uint32_t & o_size) -{ - uint64_t data = 0; - o_size = 0; - uint32_t offset = i_rpn_id - Rpn::ARRAY_INDEX; - if(offset < iv_lits.size()) - { - LIT_DATA d = iv_lits[offset]; - data = d.first; - o_size = d.second; - } - else - { - ostringstream err; - err << hex; - err << "ERROR! - Symbols::get_numeric_array_data() invalid arg rpn_id = " << i_rpn_id << endl; - throw invalid_argument(err.str()); - } - return data; -} - -// ------------------------------------------------------------------------------------------------ -uint64_t Symbols::get_attr_enum_val(string & i_attr_enum) -{ - return iv_attr_enum[i_attr_enum]; -} - -// ------------------------------------------------------------------------------------------------ - -string Symbols::find_text(uint32_t i_cini_id) -{ - string name = "NOT FOUND"; - if(i_cini_id == CINI_LIT_MASK) name = "ANY"; - else if(i_cini_id == SYM_EXPR) name = "EXPR"; - else - { - //NOTE: if there are multiple elements of the same cini_id, then this function will return the - //first element found - for(SYMBOL_MAP::const_iterator i = iv_symbols.begin(); i != iv_symbols.end(); ++i) - { - //printf("SYMBOL:%s\n",i->first.c_str()); - if((i->second).first == i_cini_id) - { - name = i->first; - break; - } - } -// for(RPN_MAP::iterator i = iv_rpn_map.begin(); i != iv_rpn_map.end(); ++i) -// { -// if((i->second).second == i_cini_id) -// { -// name = (i->second).first; -// break; -// } -// } - } - return name; -} - - -// ------------------------------------------------------------------------------------------------ - -uint32_t Symbols::get_spy_id(const string & spyname) -{ - uint32_t id = NOT_FOUND; - string s = spyname; - translate_spyname(s); - SPY_MAP::iterator sm = iv_spymap.find(s); - if(sm != iv_spymap.end()) - { - id = sm->second; - } - else - { - size_t pos = s.find('-'); - if(pos == string::npos) s.insert(0,"SPY_"); - else - { - s[pos] = '_'; - s.insert(pos+1,"SPY_"); - s.insert(0,"ENUM_"); - } - iv_not_found[s] = MAP_DATA(0,0); - //cerr << "ERROR! Symbols::get_spy_id() Spyname not found " << '[' << s << ']' << endl; - } - return id; -} - -// ------------------------------------------------------------------------------------------------ - -uint32_t Symbols::use_enum(const string & enumname) -{ - uint32_t rpn_id = NOT_FOUND; - string s = enumname; - translate_spyname(s); - SPY_MAP::iterator sm = iv_enums.find(s); - if(sm != iv_enums.end()) - { - rpn_id = sm->second; - } - else - { - printf("Error!\n"); - exit(0); - } - return rpn_id; -} - -// ------------------------------------------------------------------------------------------------ - -uint32_t Symbols::get_spy_enum_id(uint32_t i_rpn_id, const string & spyname) -{ - //uint32_t id = NOT_FOUND; - string enumname = get_enum_name(i_rpn_id); - enumname.append("-"); - enumname.append(spyname); - return get_spy_id(enumname); -} - -// ------------------------------------------------------------------------------------------------ - -string Symbols::get_enum_name(uint32_t i_rpn_id) -{ - string name("SPY ENUM NOT FOUND"); - for(SPY_MAP::iterator i = iv_enums.begin(); i != iv_enums.end(); ++i) - { - if(i->second == i_rpn_id) - { - name = i->first; - break; - } - } - return name; -} - -// ------------------------------------------------------------------------------------------------ - -string Symbols::full_listing() -{ - uint32_t count = 0; - ostringstream oss; - oss << hex << setfill('0'); - - for(SYMBOL_MAP::iterator i = iv_symbols.begin(); i != iv_symbols.end(); ++i) - { - if(i->second.first < CINI_LIT_MASK) //VAR - { - ++count; - oss << "0x" << setw(8) << i->second.first << '\t' - << '[' << i->first << ']' << endl; - } - } - - ostringstream title; - title << "\n--------------- Attribute Symbol Table ---------------\n\n" - << "0x" << hex << setfill('0') << setw(8) << count << '\t' - << "Number of variables\n" << oss.str(); - - oss.str(""); - count = 0; - - for(SYMBOL_MAP::iterator i = iv_symbols.begin(); i != iv_symbols.end(); ++i) - { - if((i->second.first & CINI_LIT_MASK) == CINI_LIT_MASK) //LIT - { - ++count; - oss << "0x" << setw(8) << i->second.first << '\t' - << '[' << i->first << ']' << endl; - } - } - - title << "\n--------------- Literal Symbol Table -----------------\n\n" - << setw(8) << count << '\t' << "Number of enumerated literals\n" - << oss.str(); - - oss.str(""); - title << "\n-------------------- Spies and arrays ----------------------\n\n" - << "0x" << setw(8) << iv_spymap.size() << '\t' << "Number of spies and array symbols\n"; - - for(SPY_MAP::iterator i = iv_spymap.begin(); i != iv_spymap.end(); ++i) - { - oss << "0x" << setw(8) << i->second << '\t' << '[' << i->first << ']' << endl; - } - - title << oss.str(); - - return title.str(); -} - -// ------------------------------------------------------------------------------------------------ - -string Symbols::listing() -{ - uint32_t count = 0; - ostringstream oss; - - // Set up tag table if not already setup - string any = "ANY"; - get_tag(use_symbol(any)); - - oss << hex << setfill('0'); - - oss << "\n--------------- Attribute Symbol Table ---------------\n\n" - << "0x" << setw(4) << iv_used_var.size()-1 << '\t' << "Number of variables\n"; - - for(VAR_SYMBOL_USED::iterator i = iv_used_var.begin() + 1; i != iv_used_var.end(); ++i) - { - ++count; - uint32_t id = count; - - string name = (*i).first; - uint32_t attrId = (*i).second; - if(name.compare(0, ASSOC_TGT_ATTR.length(), ASSOC_TGT_ATTR) == 0) - { - id |= IF_ASSOC_TGT_ATTR_TYPE; - } - else if(name.compare(0, SYS_ATTR.length(), SYS_ATTR) == 0) - { - id |= IF_SYS_ATTR_TYPE; - } - else - { - id |= IF_ATTR_TYPE; - } - - oss << "Type:" << setw(2) << iv_attr_type[name] << " Value:0x" << setw(8) << attrId << '\t' << "ID 0X" << setw(4) << id - << '\t' << '[' << name << ']' << endl; - - //printf("ATTRIBUTE: %s Value:0x%02X\n",name,iv_attr_type[name]); - } - - oss << "\n--------------- Literal Symbol Table -----------------\n\n"; - - oss << "\n0x" << setw(4) << iv_lits.size() << '\t' << "Number of numeric literals\n"; - - count = 0; - for(LIT_LIST::iterator i = iv_lits.begin(); i != iv_lits.end(); ++i,++count) - { - oss << "0x" << setw(2) << i->second << endl - << "0x" << setw(2 * i->second) << i->first; - if(i->second < 6) oss << "\t\t"; - else oss<< '\t'; - oss << "ID 0x" << setw(4) << get_numeric_tag(count | Rpn::NUMBER) << endl; - } - - oss << not_found_listing(); - - return oss.str(); -} - -// ------------------------------------------------------------------------------------------------ - -string Symbols::attr_listing() -{ - ostringstream oss; - - // Set up tag table if not already setup - string any = "ANY"; - get_tag(use_symbol(any)); - - for(VAR_SYMBOL_USED::iterator i = iv_used_var.begin() + 1; i != iv_used_var.end(); ++i) - { - string name = (*i).first; - - //Strip off any prefix (i.e. "SYS." or "TGT<#>.") - size_t pos = name.find('.'); - if(pos != string::npos) - { - name = name.substr(pos+1); - } - - oss << name << endl; - } - - return oss.str(); -} - -// ------------------------------------------------------------------------------------------------ - -string Symbols::not_found_listing() -{ - ostringstream oss; - if(iv_not_found.size()) - { - oss << "\n------------- Symbols requested that were NOT FOUND ---------------\n\n"; - for(SYMBOL_MAP::iterator i = iv_not_found.begin(); i != iv_not_found.end(); ++i) - { - //if(i->first == "SPY_NOTFOUND" || (i->first).compare(0,13,"ENUM_NOTFOUND") == 0) continue; - oss << '[' << i->first << ']' << endl; - } - } - return oss.str(); -} - -// ------------------------------------------------------------------------------------------------ - -uint32_t Symbols::bin_vars(BINSEQ & blist) -{ - // Set up tag table if not already setup - string any = "ANY"; - get_tag(use_symbol(any)); - - uint32_t count = iv_used_var.size() - 1; // first VAR is 'EXPR' and is not stored - - Rpn::set16(blist,(uint16_t)count); - - for(VAR_SYMBOL_USED::iterator i = iv_used_var.begin() + 1; i != iv_used_var.end(); ++i) - { - // Write out the attribute type (i.e. uint8_t, uint16_t, ...) and it's attribute id number - - string name = (*i).first; - uint32_t attrId = (*i).second; - - Rpn::set8(blist,iv_attr_type[name]); - - Rpn::set32(blist,attrId); - //printf("Symbols::bin_vars: Just wrote out type:%u attrId:0x%x\n",iv_attr_type[name],attrId); - } - return count; -} - -//------------------------------------------------------------------------------------------------- - -uint32_t Symbols::bin_lits(BINSEQ & blist) -{ - // Set up tag table if not already setup - string any = "ANY"; - get_tag(use_symbol(any)); - - uint32_t count = iv_lits.size(); - uint32_t total = count; - - Rpn::set16(blist,(uint16_t)count); - - for(LIT_LIST::iterator i = iv_lits.begin(); i != iv_lits.end(); ++i) - { - uint32_t size = i->second; - uint64_t data = i->first; - blist.push_back( (uint8_t)size ); - uint32_t shift_count = size * 8; - while(shift_count) - { - shift_count -= 8; - blist.push_back( (uint8_t)(data >> shift_count) ); - } - } - total += count; - - return total; -} - -//------------------------------------------------------------------------------------------------- - -uint32_t Symbols::restore_var_bseq(BINSEQ::const_iterator & bli) -{ - uint32_t count = Rpn::extract16(bli); - - for(uint32_t i = 0; i < count; ++i) - { - uint8_t type = Rpn::extract8(bli); - uint32_t attrId = Rpn::extract32(bli); - - string name = find_text(attrId); - string used_var_name = iv_used_var.at(i+1).first; - - // Account for system & associated target attributes - if (name != used_var_name) - { - size_t pos = used_var_name.find(name); - if(pos != string::npos) - { - attrId = iv_symbols[used_var_name].first; - - } - else - { - ostringstream errs; - errs << "ERROR! Symbols::restore_var_bseq(). Invalid attribute id [" - << attrId << ']' << endl; - throw invalid_argument(errs.str()); - } - - } - - iv_attr_type[used_var_name] = type; - iv_used_var.at(i+1).second = attrId; - } - - return count; -} - -//------------------------------------------------------------------------------------------------- - -uint32_t Symbols::restore_lit_bseq(BINSEQ::const_iterator & bli) -{ - iv_used_lit.clear(); - iv_used_lit.push_back(iv_rpn_map[Rpn::SYMBOL|INIT_ANY_LIT].second); // ANY lit always first - - iv_lits.clear(); - uint32_t num_count = Rpn::extract16(bli); - - for(uint32_t i = 0; i < num_count; ++i) - { - uint8_t size = *bli++; - uint64_t data = 0; - switch (size) - { - case 1: data = *bli++; break; - case 2: data = Rpn::extract16(bli); break; - case 4: data = Rpn::extract32(bli); break; - case 8: data = Rpn::extract64(bli); break; - default: - { - ostringstream errs; - errs << "ERROR! Symbols::restore_lit_bseq(). Invalid literal data size [" - << size << ']' << endl; - throw invalid_argument(errs.str()); - } - break; - } - - iv_lits.push_back( LIT_DATA(data, size) ); - } - - return num_count; -} - -//------------------------------------------------------------------------------------------------- - -string Symbols::get_spyname(uint32_t spy_id) -{ - string name; - - for(SPY_MAP::const_iterator i = iv_spymap.begin(); i != iv_spymap.end(); ++i) - { - if (i->second == spy_id) - { - name = i->first; - break; - } - } - if(name.length() == 0) - { - ostringstream oss; - oss << hex << setfill('0'); - oss << "[0x" << setw(8) << spy_id << ']'; - name = oss.str(); - } - return name; -} -//------------------------------------------------------------------------------------------------- - -string Symbols::get_enumname(uint32_t spy_id) -{ - string name = get_spyname(spy_id); - size_t pos = name.find('-'); - if(pos != string::npos) - { - name = name.substr(0,pos); - } - return name; -} - -//------------------------------------------------------------------------------------------------- - -uint32_t Symbols::get_rpn_id(uint32_t bin_tag) -{ - uint32_t rpn_id = NOT_FOUND; - uint32_t type = bin_tag & IF_TYPE_MASK; - uint32_t offset = bin_tag & ~IF_TYPE_MASK; - switch(type) - { - case IF_ATTR_TYPE: - case IF_SYS_ATTR_TYPE: - case IF_ASSOC_TGT_ATTR_TYPE: - { - string name = iv_used_var[offset].first; - rpn_id = use_symbol(name); - } - break; - - case IF_NUM_TYPE: { - offset -= iv_used_lit.size(); - if(offset >= iv_lits.size()) - { - ostringstream erros; - erros << hex; - erros << "ERROR! Symbols::get_rpn_id() Invalid NUM_TYPE 0x" - << bin_tag; - throw range_error(erros.str()); - } - LIT_DATA d = iv_lits[offset]; - rpn_id = find_numeric_lit(d.first,d.second); - } - break; - - default: - { - ostringstream erros; - erros << hex - << "ERROR! Symbols::get_rpn_id() Invalid bin_tag = 0x" - << bin_tag << endl; - throw range_error(erros.str()); - } - break; - } - return rpn_id; -} -//------------------------------------------------------------------------------------------------- - -string Symbols::spies_are_in(Symbols & i_full_list, const set<string> & i_ignore_spies) -{ - ostringstream result; - result << hex; - - for(SPY_MAP::iterator i = iv_spymap.begin(); i != iv_spymap.end(); ++i) - { - // enums in the reduced file will soon no longer contain the spyname as part of the enum name <enum name>-<spy name> - // At that time we will just need to check the enum part of the name <enum name> in both the ignore file and the full list - // When initfile processing AND spyhunter both use only enum names for enum spies then we can simplify all this - string spyname = i->first; - size_t pos = spyname.find('-'); // check for enum - if so just use the spy part of the name - if(pos != string::npos) - { - spyname = spyname.substr(pos+1); - } - - if(i_ignore_spies.find(spyname) != i_ignore_spies.end()) //don't check this spy or any of it's enums - { - cout << "Will not check spy: " << i->first << endl; - continue; - } - - uint32_t hash = 0; - if(pos != string::npos) // old enum style name - check by hash - only check enumname - { - // just compare enum names based on hash - string enumname1 = (i->first).substr(0,pos); - string enumname2 = i_full_list.get_enumname(i->second); - if(enumname1 != enumname2) - { - result << "ERROR! Enum not found for spy " << i->first << '\n' - << " Enum: " << enumname1 << "!=" << enumname2 << endl; - } - } - else // check spyname by name or new-style enum by name - { - hash = i_full_list.get_spy_id(i->first); - if(hash != NOT_FOUND) - { - if(hash != i->second) - { - result << "ERROR! HASH not the same for spy " - << i->first << ' ' << hash << ' ' << i->second << endl; - } - // else cout << "Found " << i->first << ' ' << i->second << endl; - } - } - } - result << i_full_list.not_found_listing(); - - - return result.str(); -} - - - - - diff --git a/src/usr/hwpf/ifcompiler/initSymbols.H b/src/usr/hwpf/ifcompiler/initSymbols.H deleted file mode 100755 index f1653f2d3..000000000 --- a/src/usr/hwpf/ifcompiler/initSymbols.H +++ /dev/null @@ -1,295 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/hwpf/ifcompiler/initSymbols.H $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2011,2014 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -#if !defined(INITSYMBOLS_H) -#define INITSYMBOLS_H - -// Change Log ************************************************************************************* -// -// Flag Track Userid Date Description -// ---- -------- -------- -------- ------------------------------------------------------------- -// D754106 dgilbert 06/14/10 Create -// andrewg 09/19/11 Updates based on review -// camvanng 11/08/11 Added support for attribute enums -// andrewg 11/09/11 Multi-dimensional array and move to common fapi include -// mjjones 11/17/11 Output attribute listing -// camvanng 11/17/11 Support for system & target attributes -// camvanng 01/07/12 Support for writing an attribute to a SCOM register -// camvanng 04/16/12 Support defines for SCOM address -// Support defines for bits, scom_data and attribute columns -// Delete obsolete code for defines support -// camvanng 05/07/12 Support for associated target attributes -// camvanng 06/27/12 Add get_numeric_array_data() -// End Change Log ********************************************************************************* -// $Id: initSymbols.H,v 1.7 2014/06/30 20:28:09 thi Exp $ -/** - * @file initSymbols.H - * @brief Definition of the initSymbols class. Handles all symbols for initfiles - */ - -// Definitions: -// cini_id is the 32 bit symbol tag value of a CINI initfile literal or variable as defined in ciniIfSymbols.H -// rpn_id is an internal representation used by the Rpn class for all numbers, symbols, Spy enums, etc. that is not an operator -// bin_id is the 16 bit tag used to represet number, symbols, enums, etc. in the compiled initfile. - - -#include <stdint.h> -#include <string> -#include <vector> -#include <map> -#include <set> -#include <initRpn.H> -#include <fapiHwpInitFileInclude.H> // Requires file from hwpf - -using namespace std; - - -namespace init -{ - typedef set<string> FILELIST; - const string ASSOC_TGT_ATTR = "TGT"; - - class Symbols - { - public: - - enum - { - CINI_LIT_MASK = 0xA0000000, - INIT_ANY_LIT = 0x07FFFFFE, - INIT_EXPR_VAR = 0x07FFFFFF, - }; - - - - enum - { - NOT_FOUND = 0x00000000, - NOT_USED = 0x00000000, - CINI_ID_NOT_FOUND = 0x80000000, - }; - - /** - * Build symbol map for list of files - * @param List of files to open to build Symbols - */ - Symbols(FILELIST & i_filenames); - - /** - * Add a Symbol to the "used" symbol table if not already there - * @param string Symbols name - * @returns Symbols Rpn id - * @post marks the id as 'USED' - * - */ - uint32_t use_symbol(string & i_symbol); - - /** - * Lookup the tag id from the rpn_id provided by use_symbol() - * @returns tag id - * @param rpn_id - * @pre all the symbols have been marked used (no new symbols) - * @post tag table built if not already built. - * @note tag bits 0btttxxxxx xxxxxxxx - * ttt == 0b010 -> Numeric constant - * ttt == 0b100 -> Target attribute - * ttt == 0b101 -> System attribute - * ttt == 0b110 -> Associated target attribute - * xxxxx xxxxxxxx assigned tag offset - */ - uint16_t get_tag(uint32_t i_rpn_id); - - /** - * Find the symbol name associated with an rpn_id - * @param uint32_t rpn_id - * @returns string Symbol name | "" if not found - */ - string find_name(uint32_t i_rpn_id); - - /** - * Find the tag for the numeric lit - * @param data - * @param number of significant bytes in the data [1-8] - * @returns Rpn id - */ - uint32_t find_numeric_lit(uint64_t i_data, int32_t byte_size); - - /** - * Find the tag for the numeric array lit - * @param data - * @param number of significant bytes in the data [1-8] - * @returns Rpn id - */ - uint32_t find_numeric_array_lit(uint64_t i_data, int32_t byte_size); - - /** - * Convert a numeric literal Rpn tag to an initfile tag - * @param Rpn id returned by find_numeric_lit - * @return tag - * @pre Must not be called until find_numeric_lit() has been called for all numbers - * in the initfile. - */ - uint16_t get_numeric_tag(uint32_t i_rpn_id); - - /** - * Convert a numeric array literal Rpn tag to an initfile tag - * @param Rpn id returned by find_numeric_lit - * @return tag - * @pre Must not be called until find_numeric_array_lit() has been called for all numbers - * in the initfile. - */ - uint16_t get_numeric_array_tag(uint32_t i_rpn_id); - - /** - * Get the literal data value from the Rpn id returned by find_numeric_lit() - * @param uint32_t Rpn id - * @param uint32_t for returned byte size - * @returns uint64_t data - */ - uint64_t get_numeric_data(uint32_t i_rpn_id, uint32_t & o_size); - - /** - * Get the literal data value from the Rpn id returned by find_numeric_array_lit() - * @param uint32_t Rpn id - * @param uint32_t for returned byte size - * @returns uint64_t data - */ - uint64_t get_numeric_array_data(uint32_t i_rpn_id, uint32_t & o_size); - - /** - * Get the attribute enum value for the attr enum - * @param string attribute enum name - * @returns uint64_t value - */ - uint64_t get_attr_enum_val(string & i_attr_enum); - - - /** - * Store enum name & return rpn_id - */ - uint32_t use_enum(const string & enumname); - uint32_t get_spy_enum_id(uint32_t i_rpn_id, const string & spyname); - string get_enum_name(uint32_t i_rpn_id); - - string get_enumname(uint32_t spy_id); - string get_spyname(uint32_t spy_id); - - /** - * Return spy id - */ - uint32_t get_spy_id(const string & spyname); - - - string listing(); ///< listing of used vars & lits - string attr_listing(); ///< listing of used HWPF attributes - uint32_t bin_vars(BINSEQ & blist); ///< binary byte output of used vars. ret # vars - uint32_t bin_lits(BINSEQ & blist); ///< binary byte sequence of used lits ret # lits - - string full_listing(); ///< listing of all vars & lits (debug) - string not_found_listing(); ///< listing of all vars searched for, but not found - - /** - * Get the rpn_id from an initfile binary tag - */ - uint32_t get_rpn_id(uint32_t bin_tag); - - - /** - * Restore used symbol lists from binary sequence - * @returns number of symbols - */ - uint32_t restore_var_bseq(BINSEQ::const_iterator & bli); - uint32_t restore_lit_bseq(BINSEQ::const_iterator & bli); - - /** - * Test that all spies in this object are a subset of the object provided - * @param Symbols object to compare against - * @return string will all error messages. Empty string indicates success. - */ - string spies_are_in(Symbols & i_full_list, const set<string> & i_ignore_spies); - - static void translate_spyname(string & s) - { - for(string::iterator i = s.begin(); i != s.end(); ++i) - if((*i) == '.' || (*i) == '#' || - (*i) == '=' || (*i) == '&' || - (*i) == '<' || (*i) == '>' || - (*i) == '!' || (*i) == '*' || - (*i) == '/' || (*i) == '%' || - (*i) == '$') *i = '_'; - else *i = toupper(*i); - } - - /** - * @brief Get the attribute type - * @param[in] i_rpn_id RPN id of the attribute - * @return uint32_t Attribute type - */ - uint32_t get_attr_type(const uint32_t i_rpn_id); - - private: // functions - - string find_text(uint32_t i_cini_id); - uint32_t add_undefined(const string & s); - uint32_t get_attr_type(const string &i_type, const uint32_t i_array); - - private: //data - - // map | symbol name | (cini_id, usage flags) | - typedef pair<uint32_t,uint32_t> MAP_DATA; //cini_id & corresponding rpn_id/NOT_USED - typedef map<string,MAP_DATA > SYMBOL_MAP; //attr name & corresponding cini_id, rpn_id/NOT_USED pair - typedef map<string,uint32_t> SPY_MAP; - typedef map<string,uint32_t> SYMBOL_ATTR_TYPE; //attr name & corresponding type - typedef map<string,uint64_t> SYMBOL_ATTR_ENUM; //enum name & corresponding value - - typedef pair<string,uint32_t> RPN_DATA; //attribute name & corresponding cini_id - typedef map<uint32_t,RPN_DATA> RPN_MAP; //rpn_id & corresponding attr name, cini_id pair - - typedef vector<RPN_DATA> VAR_SYMBOL_USED; - typedef vector<uint32_t> SYMBOL_USED; - - typedef pair<uint64_t,uint32_t> LIT_DATA; //numeric literal & corresponding size - typedef vector<LIT_DATA> LIT_LIST; ///< List of numeric literals and their size - - SYMBOL_MAP iv_symbols; ///< From ciniIfSymbols.H all vars and enumerated lits - SYMBOL_ATTR_TYPE iv_attr_type; ///< List of attributes and their type - SYMBOL_ATTR_ENUM iv_attr_enum; ///< List of attribute enums and their value - SYMBOL_MAP iv_not_found; ///< List of symbols not found - RPN_MAP iv_rpn_map; ///< Map rpn_id to symbol name/cini_id of used Symbols - VAR_SYMBOL_USED iv_used_var; ///< List of used attributes and their ids ordered by name - SYMBOL_USED iv_used_lit; ///< List of cini_ids of used enum lits ordered by name - - LIT_LIST iv_lits; ///< Numeric literals - - SPY_MAP iv_spymap; ///< Spies & arrays & enum spies - SPY_MAP iv_enums; ///< Spy enums - - uint32_t iv_used_var_count; - uint32_t iv_used_lit_count; - uint32_t iv_rpn_id; ///< Current rpn offset assignment - }; -}; - - -#endif |