summaryrefslogtreecommitdiffstats
path: root/src/usr/hwpf/ifcompiler/initRpn.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/hwpf/ifcompiler/initRpn.C')
-rwxr-xr-xsrc/usr/hwpf/ifcompiler/initRpn.C1396
1 files changed, 0 insertions, 1396 deletions
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));
-}
-
-
-//-------------------------------------------------------------------------------------------------
-
-
OpenPOWER on IntegriCloud