Logo Search packages:      
Sourcecode: fauhdlc version File versions

GCRegisterSet.hpp

/* $Id: GCRegisterSet.hpp 4323 2009-01-27 13:48:12Z potyra $
 *
 * RegisterSet defines a means to address signals, drivers, values, and to
 * apply operations on these.
 *
 * Copyright (C) 2008-2009 FAUmachine Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */

#ifndef __GC_REGISTER_SET_HPP_INCLUDED
#define __GC_REGISTER_SET_HPP_INCLUDED

#include "intermediate/operands/Register.hpp"
#include "frontend/ast/Types.hpp"
#include "frontend/ast/TypeDeclaration.hpp"
#include "intermediate/container/CodeContainer.hpp"
#include <iostream>

namespace ast {

//! register set used to propagate values from/to expressions
00024 class RegisterSet {
public:
      //! c'tor to initialize members with NULL
      /** This c'tor will do nothing but initializing the members
       *  with NULL.
       */
00030       RegisterSet(
            intermediate::CodeContainer &container
            ) :   value(NULL),
                  composite(NULL),
                  sliceBegin(NULL),
                  sliceEnd(NULL),
                  cc(&container),
                  isSignal(false) {
      }

      //! copy c'tor, adjust reference counts.
00041       RegisterSet(
            const RegisterSet &other
            ) :   value(other.value),
                  composite(other.composite),
                  sliceBegin(other.sliceBegin),
                  sliceEnd(other.sliceEnd),
                  cc(other.cc),
                  lowerBounds(other.lowerBounds),
                  upperBounds(other.upperBounds),
                  isSignal(other.isSignal) {}

      //! d'tor, free references.
00053       ~RegisterSet() {
            util::MiscUtil::terminate(this->value);
            util::MiscUtil::terminate(this->composite);
            util::MiscUtil::terminate(this->sliceBegin);
            util::MiscUtil::terminate(this->sliceEnd);
      }

      //! assignment operator
      /** @param other RegisterSet to assign to this RegisterSet.
       *  @return nothing, chained assignment is ugly and should be
       *  avoided.
       */
      void
00066       operator =(const RegisterSet &other) {
            util::MiscUtil::terminate(this->value);
            util::MiscUtil::terminate(this->composite);
            util::MiscUtil::terminate(this->sliceBegin);
            util::MiscUtil::terminate(this->sliceEnd);

            if (other.value != NULL) {
                  this->value = other.value;
            }
            if (other.composite != NULL) {
                  this->composite = other.composite;
            }
            if (other.sliceBegin != NULL) {
                  this->sliceBegin = other.sliceBegin;
            }
            if (other.sliceEnd != NULL) {
                  this->sliceEnd = other.sliceEnd;
            }

            this->isSignal = other.isSignal;
            this->cc = other.cc;
            this->lowerBounds = other.lowerBounds;
            this->upperBounds = other.upperBounds;
      }

      //! retrieve an Operand containing the real/integer value.
      /** @param bt base type.
       *  @return operand with an integral or real value. Reference count
       *          is already increased.
       */
      intermediate::Operand *getValue(enum BaseType bt);

      /** retrieve an Operand with which a variable or Signal can be 
       *  modified. For a variable, this will be an indirect operand.
       *  For a signal or driver, it will be a pointer to the signal
       *  or driver instance, which can be passed as is to update, connect,
       *  or getsig.
       *
       *  value (immediate) -> error
       *  variable: -> IndirectOperand(pointer to data instance)
       *  signal: -> pointer to signal instance.
       *  driver: -> error
       *
       *  @param bt base type.
       *  @return operand which can be used in an Update or Mov Opcode to
       *          update the signal or respectively the variable.
       *          Reference count is already increased.
       */
      intermediate::Operand *getDestination(enum BaseType bt);

      /** retrieve a pointer to the storage location.
       *  This method is useful to perform offset calculations, which need
       *  to be based on pointers.
       *  Since the intermediate only has handles to pointers of signals and
       *  drivers, which will be created during run-time - out of scope of 
       *  the intermediate code - arrays or records are stored as arrays
       *  of pointers to actual signals. getPointer will contain the pointer
       *  to the elements in a composite type, so that aoffset/roffset can
       *  add offsets to that pointers which in turn must be dereferenced to
       *  obtain the pointer to the signal or driver.
       *  
       *  value (immediate) -> error
       *  variable -> pointer to variable.
       *  signal -> pointer to pointer to signal instance.
       *  driver -> pointer to pointer to driver instance.
       *
       *  @return pointer to storage location.
       */
      intermediate::Operand *getPointer(void);

      /** set the pointer to the storage location.
       *  value (immediate) -> error
       *  variable -> pointer to variable
       *  signal -> pointer to pointer to signal
       *  driver -> pointer to pointer to driver
       *
       *  @param ptr Operand with above semantics.
       */
      void setPointer(intermediate::Operand *ptr);

      /** set the value.
       *  value (immediate) -> value
       *  variable (indirect) -> value (or error?)
       *  signal -> error
       *  driver -> error
       */
      void setValue(intermediate::Operand *val);

      /** treat RegisterSet contents as an array, and subscribe to it
       *  with the indices.
       *  @param arrayType array type that the array should refer to.
       *  @param indices list of relative indices of the array.
       */
      void 
      subscribe(
            TypeDeclaration *arrayType,
            std::list<intermediate::Operand *> indices);

      /** denote, that the current content refers to an unconstraint 
       *  array, and has the lower/upper bounds.
       *  @param lb lower bounds of the unconstraint array.
       *  @param ub upper bounds of the unconstraint array.
       */
      void
      setUnconstraintBounds(
            std::list<intermediate::Operand *> lb,
            std::list<intermediate::Operand *> ub);

      /** does the RegisterSet refer to an unconstraint array? */
      bool isUnconstraint(void) const;


      /** store the current applicable lower/upper bounds of an
       *  unconstraint array in lb/ub.
       *  @param lb: list to store lower bounds in.
       *  @param ub: list to store upper bounds in.
       */
      void 
      getConstraints(
            std::list<intermediate::Operand *> &lb,
            std::list<intermediate::Operand *> &ub) const;

private:
      /** operand that contains an integer/real value. Don't read this
       *  operand directly, use getValue() instead. */
00191       intermediate::Operand *value;

      /** Operand referring to the (base) address of a composite type,
       *  or to the address of a variable, signal or driver.
       *  To obtain the value, use getValue().
       */
00197       intermediate::Operand *composite;
public: /* FIXME should be private as well */
      //! register containing the low bound of a slice (integer)
      /** currently ignored in almost all cases FIXME */
00201       intermediate::Operand *sliceBegin;
      //! register containing the high bound of a slice (integer)
      /** currently ignored in almost all cases FIXME */
00204       intermediate::Operand *sliceEnd;

private:
      //! current code container.
00208       intermediate::CodeContainer *cc;
      //! lower bounds of an unconstraint array.
00210       std::list<intermediate::Operand *> lowerBounds;
      //! upper bounds of an unconstraint array.
00212       std::list<intermediate::Operand *> upperBounds;
public:
      //! does the composite value refer to a signal/driver?
00215       bool isSignal;
};

}; /* namespace ast */

#endif /* __GC_REGISTER_SET_HPP_INCLUDED */

Generated by  Doxygen 1.6.0   Back to index