diff options
Diffstat (limited to 'src/usr/hwpf/ifcompiler/initRpn.C')
-rwxr-xr-x | src/usr/hwpf/ifcompiler/initRpn.C | 146 |
1 files changed, 139 insertions, 7 deletions
diff --git a/src/usr/hwpf/ifcompiler/initRpn.C b/src/usr/hwpf/ifcompiler/initRpn.C index 2c8c0dc90..50b197e7d 100755 --- a/src/usr/hwpf/ifcompiler/initRpn.C +++ b/src/usr/hwpf/ifcompiler/initRpn.C @@ -24,6 +24,7 @@ // 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 // End Change Log ********************************************************************************* /** @@ -40,6 +41,8 @@ #include <stdexcept> #include <fapiHwpInitFileInclude.H> // Requires file from hwpf +extern void yyerror(const char * s); + using namespace init; const char * OP_TXT[] = @@ -71,7 +74,7 @@ std::string Rpn::cv_empty_str; //------------------------------------------------------------------------------------------------- Rpn::Rpn(uint32_t i_uint,Symbols * symbols) : iv_symbols(symbols) -{ push_int(i_uint);} +{ push_int(i_uint); } //------------------------------------------------------------------------------------------------- @@ -205,13 +208,77 @@ 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_array_val = atoi(l_idx.c_str()); + uint32_t l_num_idx = 0; + std::vector<string> l_idxstr; - uint32_t rpn_id = iv_symbols->find_numeric_array_lit(l_array_val,4); - iv_rpnstack.push_back(rpn_id); + // 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 << "Invalid attribute array index range: " << l_idxstr.at(i); + yyerror(oss.str().c_str()); + } - // printf("Array Index: %s decimal:%u rpn_id:0x%8X\n",l_idx.c_str(),l_array_val,rpn_id); + 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 << "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()); } //------------------------------------------------------------------------------------------------- @@ -284,11 +351,13 @@ Rpn * Rpn::push_merge(Rpn * i_rpn, IfRpnOp op) 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; @@ -304,11 +373,13 @@ Rpn * Rpn::push_merge(Rpn * i_rpn, IfRpnOp op) 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; @@ -327,6 +398,7 @@ Rpn * Rpn::push_merge(Rpn * i_rpn, IfRpnOp op) 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; @@ -334,6 +406,7 @@ Rpn * Rpn::push_merge(Rpn * i_rpn, IfRpnOp op) 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; @@ -467,6 +540,10 @@ Rpn * Rpn::push_merge(Rpn * i_rpn, IfRpnOp op) //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; @@ -479,6 +556,10 @@ Rpn * Rpn::push_merge(Rpn * i_rpn, IfRpnOp op) 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; } @@ -492,6 +573,7 @@ void Rpn::bin_read(BINSEQ::const_iterator & bli, Symbols * symbols) if(symbols) iv_symbols = symbols; iv_rpnstack.clear(); + iv_array_idx_range.clear(); while(size) { @@ -568,6 +650,10 @@ BINSEQ::const_iterator Rpn::bin_read_one_op(BINSEQ::const_iterator & bli, Symbol 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)); + } } //------------------------------------------------------------------------------------------------- @@ -692,11 +778,13 @@ std::string Rpn::listing(const char * i_desc, const std::string & spyname, bool //------------------------------------------------------------------------------------------------- -void Rpn::bin_str(BINSEQ & o_blist, bool i_prepend_count) // binary version to write to file +// 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) { 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) { @@ -713,24 +801,68 @@ void Rpn::bin_str(BINSEQ & o_blist, bool i_prepend_count) // binary version to ++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 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: |