Logo Search packages:      
Sourcecode: fauhdlc version File versions

void ast::GenCode::processArrayAssoc ( ElementAssociation node,
TypeDeclaration aType 
) [private]

process an array aggregate association.

Parameters:
node ElementAssociation to process.
aType type of the aggregate.

Definition at line 1487 of file GenCode.cpp.

References ast::AstNode::accept(), ast::ElementAssociation::actual, destRegs, doAssignment(), ast::RangeSet::empty(), ast::RangeSet::getLowerBound(), ast::RegisterSet::isSignal, ast::RangeSet::minus(), ast::ElementAssociation::range, sourceRegs, ast::RegisterSet::subscribe(), and ast::Expression::type.

Referenced by processArrayAggregate().

{
      if (node.range == NULL) {
            // error occured beforehand, reported already.
            return;
      }

      // lrm 7.3.2: reinterpeted:
      // a <= (1 to 3 | 5 => '1', others => '0')
      // means that each array element of a, that falls in the choices
      // 1 to 3 | 5 gets '1' assigned, and each element that falls in 
      // the choices others gets '0' assigned.
      //
      // In particular, this means to do a subscript for each element of a,
      // and put the result of the actual in there.
      //
      // One possible approach is to iterate over each element of the ranges
      // and assign the first result to the first element of a and reuse 
      // that space as a cache for the remaining elements of a choice.

      // empty Range? -> do nothing. (might happen in case of "Others" 
      // referring to an empty Range).
      RangeSet rs = *node.range;
      if (rs.empty()) {
            return;
      }

      // subscribe to first element of choices, and let the actual do the
      // assignment in the first place.
      RegisterSet dRegs = this->destRegs;
      // FIXME think about slices?
      this->destRegs = RegisterSet(this->destRegs);

      assert(node.actual != NULL);
      std::list<Operand *> indices = std::list<Operand *>();
      universal_integer i = rs.getLowerBound();
      ImmediateOperand *idx = new ImmediateOperand(i);
      indices.push_back(idx);

      this->destRegs.subscribe(aType, indices);

      // determine value of actual (and also assign it to the first 
      // destination offset)
      node.actual->accept(*this);
      bool ret = rs.minus(i, i);
      assert(ret);
      // prepare to handle remaining elements. use the evaluated element
      // that was just assigned as source.
      // FIXME this only works for variables, not for signals!
      this->sourceRegs = this->destRegs;
      assert(! this->sourceRegs.isSignal);

      while (! rs.empty()) {
            // determine new destination index for the next element
            indices.clear();
            i = rs.getLowerBound();
            indices.push_back(new ImmediateOperand(i));

            this->destRegs = RegisterSet(dRegs);
            this->destRegs.subscribe(aType, indices);
            // assign it
            this->doAssignment(*node.actual->type);

            // remove the next index from the set.
            ret = rs.minus(i, i);
            assert(ret);
      }

      this->destRegs = dRegs;
}


Generated by  Doxygen 1.6.0   Back to index