Logo Search packages:      
Sourcecode: fauhdlc version File versions

void ast::GenCode::visit ( WaitStat node  )  [private, virtual]

Visit a WaitStat

Parameters:
node WaitStat node that gets visited.

Reimplemented from ast::TopDownVisitor.

Definition at line 821 of file GenCode.cpp.

References ast::AstNode::accept(), intermediate::CodeContainer::addCode(), assignExpression, ast::Expression::baseType, ast::ConditionedStat::condition, container, ast::RegisterSet::getDestination(), intermediate::LabelFactory::getLabel(), intermediate::ImmediateOperand::getOne(), intermediate::RegisterFactory::getRegister(), intermediate::RegisterFactory::getSimTime(), ast::RegisterSet::getValue(), isTarget, ast::WaitStat::sensitivities, sourceRegs, and ast::WaitStat::timeout.

{
      this->sourceRegs = RegisterSet(*this->container);
      this->assignExpression = false;
      this->isTarget = false;

      Label *loopLbl = NULL;
      Label *exitWait = NULL;
      Register *resumeAt = NULL;

      // semantics of a wait:
      // time := now() + timeout
      // loop
      //      trigger(self, time)
      //      trigger_sig(self, signal_list)
      //      suspend()
      //      time1 := now()
      //      exit if time1 >= time -- timeout
      //      if !condition goto loop -- condition met
      // end loop


      // time := now() + timeout
      if (node.timeout != NULL) {
            node.timeout->accept(*this);
            Operand *timeout = 
                  this->sourceRegs.getValue(node.timeout->baseType);

            assert(timeout != NULL);
            // TODO
            // now := now();
            Register *now = RegisterFactory::getSimTime();
            resumeAt = RegisterFactory::getRegister(OP_TYPE_INTEGER);
            Add *cra = new Add(now, timeout, resumeAt);
            this->container->addCode(cra);
      }

      // loop ...
      if (node.condition != NULL) {
            loopLbl = LabelFactory::getLabel("wait_until_loop");
            this->container->addCode(loopLbl);
            exitWait = LabelFactory::getLabel("wait_done");
      }

      // trigger(self, time)
      if (node.timeout != NULL) {
            WakeAt *wa = new WakeAt(resumeAt);
            this->container->addCode(wa);
      }

      // trigger_sig(self, signal_list)
      // sensitivities must have been set by WaitConditions visitor.
      assert(node.sensitivities != NULL);
      for (std::list<Name*>::iterator i = node.sensitivities->begin();
            i != node.sensitivities->end(); i++) {

            // FIXME use WakeOn as assign operation for 
            //       composite signals!
            this->sourceRegs = RegisterSet(*this->container);
            (*i)->accept(*this);
            Operand *sigPtr = 
                  this->sourceRegs.getDestination((*i)->baseType);
            WakeOn *wo = new WakeOn(sigPtr);
            this->container->addCode(wo);
      }

      //suspend
      Suspend *suspend = new Suspend();
      this->container->addCode(suspend);

      // exit if now() >= time -- timeout
      if ((node.timeout != NULL) && (node.condition != NULL)) {
            Register *now = RegisterFactory::getSimTime();
            Jbe *exitTimout = new Jbe(resumeAt, now, exitWait);
            this->container->addCode(exitTimout);
      }

      // if !condition goto loop
      if (node.condition != NULL) {
            this->sourceRegs = RegisterSet(*this->container);
            node.condition->accept(*this);
            Operand *cond = this->sourceRegs.getValue(BASE_TYPE_INTEGER);
            Jne *goLoop = 
                  new Jne(cond, ImmediateOperand::getOne(), loopLbl);
            this->container->addCode(goLoop);
            this->sourceRegs = RegisterSet(*this->container);

            this->container->addCode(exitWait);
      }
}


Generated by  Doxygen 1.6.0   Back to index