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(), ' '); }
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; }