Exemple #1
0
static void emit_stmt_case(ivl_scope_t scope, ivl_statement_t stmt)
{
      char *case_type;
      unsigned idx, default_case, count = ivl_stmt_case_count(stmt);
      switch(ivl_statement_type(stmt)) {
	case IVL_ST_CASE:
	case IVL_ST_CASER:
	    case_type = "case";
	    break;
	case IVL_ST_CASEX:
	    case_type = "casex";
	    break;
	case IVL_ST_CASEZ:
	    case_type = "casez";
	    break;
	default:
	    assert(0);
      }
      fprintf(vlog_out, "%*c%s (", get_indent(), ' ', case_type);
      emit_expr(scope, ivl_stmt_cond_expr(stmt), 0);
      fprintf(vlog_out, ")");
      emit_stmt_file_line(stmt);
      fprintf(vlog_out, "\n");
      indent += indent_incr;
      default_case = count;
      for (idx = 0; idx < count; idx += 1) {
	    ivl_expr_t expr = ivl_stmt_case_expr(stmt, idx);
	      /* This is the default case so emit it last. */
	    if (expr == 0) {
		  assert(default_case == count);
		  default_case = idx;
		  continue;
	    }
	    fprintf(vlog_out, "%*c", get_indent(), ' ');
	    emit_expr(scope, expr, 0);
	    fprintf(vlog_out, ":");
	    single_indent = 1;
	    emit_stmt(scope, ivl_stmt_case_stmt(stmt, idx));
      }
      if (default_case < count) {
	    fprintf(vlog_out, "%*cdefault:", get_indent(), ' ');
	    single_indent = 1;
	    emit_stmt(scope, ivl_stmt_case_stmt(stmt, default_case));
      }
      assert(indent >= indent_incr);
      indent -= indent_incr;
      fprintf(vlog_out, "%*cendcase\n", get_indent(), ' ');
}
Exemple #2
0
void clsAnalysis::AnalyzeStatement(clsStatement * pStatement, clsBasicBlock * pBasicBlock, clsEvent * pEvent)
{
  ivl_statement_t                   ivl_Statement;
  vector<clsLValue *>::iterator     it_pLValue;
  vector<clsBasicBlock *>::iterator it_pBasicBlock;
  unsigned int                      iNumberOfParameters;
  unsigned int                      iNumberOfStatements;
  unsigned int                      iIndex;
  
  ivl_Statement = pStatement->m_ivl_Statement;
  it_pBasicBlock = pBasicBlock->m_pSuccessors.begin();
  
  switch (pStatement->m_Type)
  {
  default:
    _DebugPrint("/* Unrecognized statement of type %u is encountered. */\n", ivl_statement_type(ivl_Statement) );
    _Assert(0 && "Frontend Error: Unrecognized statement is encountered.");
    break;
  case CMODELGEN_STATEMENT_NOP:
    break;
  case CMODELGEN_STATEMENT_WAIT:
    if (it_pBasicBlock != pBasicBlock->m_pSuccessors.end() && *it_pBasicBlock != NULL)
    {
      AnalyzeBasicBlock(*it_pBasicBlock, pEvent);
    }
    break;
  case CMODELGEN_STATEMENT_CASE:
  case CMODELGEN_STATEMENT_CASEZ:
  case CMODELGEN_STATEMENT_CASEX:
    AnalyzeExpression(pStatement->m_pExpressions[0], pEvent);
    iNumberOfStatements = ivl_stmt_case_count(ivl_Statement);
    for(iIndex = 0; iIndex < iNumberOfStatements; ++iIndex)
    {
      AnalyzeExpression(pStatement->m_pExpressions[iIndex + 1], pEvent);
      if (it_pBasicBlock != pBasicBlock->m_pSuccessors.end() && *it_pBasicBlock != NULL)
      {
        AnalyzeBasicBlock(*it_pBasicBlock, pEvent);
      }
      if (it_pBasicBlock != pBasicBlock->m_pSuccessors.end() )
      {
        ++it_pBasicBlock;
      }
    }
    if (it_pBasicBlock != pBasicBlock->m_pSuccessors.end() && *it_pBasicBlock != NULL)
    {
      AnalyzeBasicBlock(*it_pBasicBlock, pEvent);
    }
    break;
  case CMODELGEN_STATEMENT_COND:
    AnalyzeExpression(pStatement->m_pExpressions[0], pEvent);
    if (0 != ivl_stmt_cond_true(ivl_Statement) )
    {
      if (it_pBasicBlock != pBasicBlock->m_pSuccessors.end() && *it_pBasicBlock != NULL)
      {
        AnalyzeBasicBlock(*it_pBasicBlock, pEvent);
      }
      if (it_pBasicBlock != pBasicBlock->m_pSuccessors.end() )
      {
        ++it_pBasicBlock;
      }
    }
    if (0 != ivl_stmt_cond_false(ivl_Statement) )
    {
      if (it_pBasicBlock != pBasicBlock->m_pSuccessors.end() && *it_pBasicBlock != NULL)
      {
        AnalyzeBasicBlock(*it_pBasicBlock, pEvent);
      }
      if (it_pBasicBlock != pBasicBlock->m_pSuccessors.end() )
      {
        ++it_pBasicBlock;
      }
    }
    if (it_pBasicBlock != pBasicBlock->m_pSuccessors.end() && *it_pBasicBlock != NULL)
    {
      AnalyzeBasicBlock(*it_pBasicBlock, pEvent);
    }
    break;
  case CMODELGEN_STATEMENT_REPEAT:
  case CMODELGEN_STATEMENT_WHILE:
    AnalyzeExpression(pStatement->m_pExpressions[0], pEvent);
    if (it_pBasicBlock != pBasicBlock->m_pSuccessors.end() && *it_pBasicBlock != NULL)
    {
      AnalyzeBasicBlock(*it_pBasicBlock, pEvent);
    }
    if (it_pBasicBlock != pBasicBlock->m_pSuccessors.end() && *it_pBasicBlock != NULL)
    {
      AnalyzeBasicBlock(*it_pBasicBlock, pEvent);
    }
    break;
  case CMODELGEN_STATEMENT_NB_ASSIGN:
    iIndex = 0;
    for (it_pLValue  = pStatement->m_pLValues.begin();
         it_pLValue != pStatement->m_pLValues.end();
         ++it_pLValue)
    {
      AnalyzeNBLValue(*it_pLValue, pEvent);
      ++iIndex;
    }
    AnalyzeExpression(pStatement->m_pExpressions[0], pEvent);
    break;
  case CMODELGEN_STATEMENT_ASSIGN:
    iIndex = 0;
    for (it_pLValue  = pStatement->m_pLValues.begin();
         it_pLValue != pStatement->m_pLValues.end();
         ++it_pLValue)
    {
      AnalyzeLValue(*it_pLValue, pEvent);
      ++iIndex;
    }
    AnalyzeExpression(pStatement->m_pExpressions[0], pEvent);
    break;
  case CMODELGEN_STATEMENT_STASK:
    iNumberOfParameters = ivl_stmt_parm_count(ivl_Statement);
    for(iIndex = 0; iIndex < iNumberOfParameters; ++iIndex)
    {
      AnalyzeExpression(pStatement->m_pExpressions[iIndex], pEvent);
    }
    break;
  case CMODELGEN_STATEMENT_UTASK:
    break;
  case CMODELGEN_STATEMENT_DISABLE:
    break;
  case CMODELGEN_STATEMENT_ALLOC:
    break;
  case CMODELGEN_STATEMENT_FREE:
    break;
  }
}
static int show_stmt_case_r(ivl_statement_t net, ivl_scope_t sscope)
{
      ivl_expr_t exp = ivl_stmt_cond_expr(net);
      int cond = draw_eval_real(exp);
      unsigned count = ivl_stmt_case_count(net);

      unsigned local_base = local_count;

      unsigned idx, default_case;

      local_count += count + 1;


	/* First draw the branch table.  All the non-default cases
	   generate a branch out of here, to the code that implements
	   the case. The default will fall through all the tests. */
      default_case = count;

      for (idx = 0 ;  idx < count ;  idx += 1) {
	    ivl_expr_t cex = ivl_stmt_case_expr(net, idx);
	    int cvec;

	    if (cex == 0) {
		  default_case = idx;
		  continue;
	    }

	    cvec = draw_eval_real(cex);

	    fprintf(vvp_out, "    %%cmp/wr %d, %d;\n", cond, cvec);
	    fprintf(vvp_out, "    %%jmp/1 T_%d.%d, 4;\n",
		    thread_count, local_base+idx);

	      /* Done with the guard expression value. */
	    clr_word(cvec);
      }

	/* Done with the case expression. */
      clr_word(cond);

	/* Emit code for the case default. The above jump table will
	   fall through to this statement. */
      if (default_case < count) {
	    ivl_statement_t cst = ivl_stmt_case_stmt(net, default_case);
	    show_statement(cst, sscope);
      }

	/* Jump to the out of the case. */
      fprintf(vvp_out, "    %%jmp T_%d.%d;\n", thread_count,
	      local_base+count);

      for (idx = 0 ;  idx < count ;  idx += 1) {
	    ivl_statement_t cst = ivl_stmt_case_stmt(net, idx);

	    if (idx == default_case)
		  continue;

	    fprintf(vvp_out, "T_%d.%d ;\n", thread_count, local_base+idx);
	    clear_expression_lookaside();
	    show_statement(cst, sscope);

	    fprintf(vvp_out, "    %%jmp T_%d.%d;\n", thread_count,
		    local_base+count);

      }


	/* The out of the case. */
      fprintf(vvp_out, "T_%d.%d ;\n",  thread_count, local_base+count);

      return 0;
}
static int show_stmt_case(ivl_statement_t net, ivl_scope_t sscope)
{
      ivl_expr_t exp = ivl_stmt_cond_expr(net);
      struct vector_info cond = draw_eval_expr(exp, 0);
      unsigned count = ivl_stmt_case_count(net);

      unsigned local_base = local_count;

      unsigned idx, default_case;

      local_count += count + 1;

	/* First draw the branch table.  All the non-default cases
	   generate a branch out of here, to the code that implements
	   the case. The default will fall through all the tests. */
      default_case = count;

      for (idx = 0 ;  idx < count ;  idx += 1) {
	    ivl_expr_t cex = ivl_stmt_case_expr(net, idx);
	    struct vector_info cvec;

	    if (cex == 0) {
		  default_case = idx;
		  continue;
	    }

	      /* Is the guard expression something I can pass to a
		 %cmpi/u instruction? If so, use that instead. */

	    if ((ivl_statement_type(net) == IVL_ST_CASE)
		&& (ivl_expr_type(cex) == IVL_EX_NUMBER)
		&& (! number_is_unknown(cex))
		&& number_is_immediate(cex, 16)) {

		  unsigned long imm = get_number_immediate(cex);

		  fprintf(vvp_out, "    %%cmpi/u %u, %lu, %u;\n",
			  cond.base, imm, cond.wid);
		  fprintf(vvp_out, "    %%jmp/1 T_%d.%d, 6;\n",
			  thread_count, local_base+idx);

		  continue;
	    }

	      /* Oh well, do this case the hard way. */

	    cvec = draw_eval_expr_wid(cex, cond.wid, 0);
	    assert(cvec.wid == cond.wid);

	    switch (ivl_statement_type(net)) {

		case IVL_ST_CASE:
		  fprintf(vvp_out, "    %%cmp/u %u, %u, %u;\n",
			  cond.base, cvec.base, cond.wid);
		  fprintf(vvp_out, "    %%jmp/1 T_%d.%d, 6;\n",
			  thread_count, local_base+idx);
		  break;

		case IVL_ST_CASEX:
		  fprintf(vvp_out, "    %%cmp/x %u, %u, %u;\n",
			  cond.base, cvec.base, cond.wid);
		  fprintf(vvp_out, "    %%jmp/1 T_%d.%d, 4;\n",
			  thread_count, local_base+idx);
		  break;

		case IVL_ST_CASEZ:
		  fprintf(vvp_out, "    %%cmp/z %u, %u, %u;\n",
			  cond.base, cvec.base, cond.wid);
		  fprintf(vvp_out, "    %%jmp/1 T_%d.%d, 4;\n",
			  thread_count, local_base+idx);
		  break;

		default:
		  assert(0);
	    }
	    
	      /* Done with the case expression */
	    clr_vector(cvec);
      }

	/* Done with the condition expression */
      clr_vector(cond);

	/* Emit code for the default case. */
      if (default_case < count) {
	    ivl_statement_t cst = ivl_stmt_case_stmt(net, default_case);
	    show_statement(cst, sscope);
      }

	/* Jump to the out of the case. */
      fprintf(vvp_out, "    %%jmp T_%d.%d;\n", thread_count,
	      local_base+count);

      for (idx = 0 ;  idx < count ;  idx += 1) {
	    ivl_statement_t cst = ivl_stmt_case_stmt(net, idx);

	    if (idx == default_case)
		  continue;

	    fprintf(vvp_out, "T_%d.%d ;\n", thread_count, local_base+idx);
	    clear_expression_lookaside();
	    show_statement(cst, sscope);

	    fprintf(vvp_out, "    %%jmp T_%d.%d;\n", thread_count,
		    local_base+count);

      }


	/* The out of the case. */
      fprintf(vvp_out, "T_%d.%d ;\n",  thread_count, local_base+count);
      clear_expression_lookaside();

      return 0;
}