diff --git a/lang/m2/comp/casestat.C b/lang/m2/comp/casestat.C index 8cf73a0c6..5d0cbaa2d 100644 --- a/lang/m2/comp/casestat.C +++ b/lang/m2/comp/casestat.C @@ -201,7 +201,7 @@ CaseCode(nd, exitlabel, end_reached) rval |= LblWalkNode((label) pnode->nd_LEFT->nd_lab, pnode->nd_LEFT->nd_RIGHT, exitlabel, end_reached); - C_bra(sh->sh_break); + c_bra(sh->sh_break); } } else { @@ -313,7 +313,7 @@ AddOneCase(sh, lnode, rnode, lbl) C_zgt(cont); } C_asp(int_size); - C_bra(lbl); + c_bra(lbl); C_df_ilb(cont); ce->ce_label = 0; } diff --git a/lang/m2/comp/code.c b/lang/m2/comp/code.c index c36010678..5e6128d99 100644 --- a/lang/m2/comp/code.c +++ b/lang/m2/comp/code.c @@ -164,7 +164,7 @@ CodeExpr(nd, ds, true_label, false_label) */ CodeValue(ds, tp); C_zne(true_label); - C_bra(false_label); + c_bra(false_label); } } @@ -911,7 +911,7 @@ CodeOper(expr, true_label, false_label) } if (true_label != NO_LABEL) { compare(expr->nd_symb, true_label); - C_bra(false_label); + c_bra(false_label); break; } truthvalue(expr->nd_symb); @@ -923,30 +923,56 @@ CodeOper(expr, true_label, false_label) INN instruction expects the bit number on top of the stack */ - label l_toolarge = NO_LABEL; + label l_toolarge = NO_LABEL, l_cont = NO_LABEL; + t_type *ltp = leftop->nd_type; - CodePExpr(rightop); - CodePExpr(leftop); - C_loc(rightop->nd_type->set_low); - C_sbu(word_size); - if (needs_rangecheck(ElementType(rightop->nd_type), leftop->nd_type)) { - l_toolarge = ++text_label; - C_dup(word_size); - C_loc(rightop->nd_type->tp_size*8); - C_cmu(word_size); - C_zge(l_toolarge); + if (leftop->nd_symb == COERCION) { + /* Could be coercion to word_type. */ + ltp = leftop->nd_RIGHT->nd_type; + } + if (leftop->nd_class == Value) { + if (! in_range(leftop->nd_INT, ElementType(rightop->nd_type))) { + if (true_label != NO_LABEL) { + c_bra(false_label); + } + else c_loc(0); + break; + } + CodePExpr(rightop); + C_loc(rightop->nd_type->set_low-leftop->nd_INT); + } + else { + CodePExpr(rightop); + CodePExpr(leftop); + C_loc(rightop->nd_type->set_low); + C_sbu(word_size); + if (needs_rangecheck(ElementType(rightop->nd_type), ltp)) { + l_toolarge = ++text_label; + C_dup(word_size); + C_loc(rightop->nd_type->tp_size*8); + C_cmu(word_size); + C_zge(l_toolarge); + } } C_inn(rightop->nd_type->tp_size); if (true_label != NO_LABEL) { C_zne(true_label); - C_bra(false_label); + c_bra(false_label); + } + else { + l_cont = ++text_label; + c_bra(l_cont); } if (l_toolarge != NO_LABEL) { + def_ilb(l_toolarge); C_asp(word_size+rightop->nd_type->tp_size); if (true_label != NO_LABEL) { - C_bra(false_label); + c_bra(false_label); } - c_loc(0); + else c_loc(0); + } + if (l_cont != NO_LABEL) { + def_ilb(l_cont); } break; } @@ -973,7 +999,7 @@ CodeOper(expr, true_label, false_label) if (l_end != NO_LABEL) { def_ilb(true_label); c_loc(1); - C_bra(l_end); + c_bra(l_end); def_ilb(false_label); c_loc(0); def_ilb(l_end); @@ -1107,7 +1133,7 @@ CodeEl(nd, tp, null_set) if (eltype->tp_fund == T_SUBRANGE) { C_loc(eltype->sub_ub); } - else C_loc((arith) (eltype->enm_ncst - 1)); + else C_loc(eltype->enm_ncst - 1); Operands(nd); CAL("LtoUset", 5 * (int) word_size); /* library routine to fill set */ @@ -1201,6 +1227,12 @@ DoHIGH(df) } #ifdef SQUEEZE +c_bra(l) + label l; +{ + C_bra((label) l); +} + c_loc(n) { C_loc((arith) n); diff --git a/lang/m2/comp/walk.c b/lang/m2/comp/walk.c index cdf468d7a..4b2d1d3bb 100644 --- a/lang/m2/comp/walk.c +++ b/lang/m2/comp/walk.c @@ -384,7 +384,7 @@ WalkProcedure(procedure) #else cd_init = ++text_label; cd_body = ++text_label; - C_bra(cd_init); + c_bra(cd_init); def_ilb(cd_body); #endif @@ -399,7 +399,7 @@ WalkProcedure(procedure) C_asp(-func_res_size); } #ifndef USE_INSERT - C_bra(RETURN_LABEL); + c_bra(RETURN_LABEL); #endif } @@ -458,7 +458,7 @@ WalkProcedure(procedure) #ifdef USE_INSERT C_endpart(partno); #else - C_bra(cd_body); + c_bra(cd_body); #endif DO_DEBUG(options['X'], PrNode(procedure->prc_body, 0)); def_ilb(RETURN_LABEL); /* label at end */ @@ -660,7 +660,7 @@ WalkStat(nd, exit_label, end_reached) if (right->nd_RIGHT) { /* ELSE part */ label l2 = ++text_label; - C_bra(l2); + c_bra(l2); end_reached = end_r | LblWalkNode(l1, right->nd_RIGHT, exit_label, end_reached); l1 = l2; } @@ -678,7 +678,7 @@ WalkStat(nd, exit_label, end_reached) exit = ++text_label, dummy = ++text_label; - C_bra(dummy); + c_bra(dummy); end_reached |= LblWalkNode(loop, right, exit_label, end_reached); def_ilb(dummy); ExpectBool(&(nd->nd_LEFT), loop, exit); @@ -702,7 +702,7 @@ WalkStat(nd, exit_label, end_reached) end_reached &= REACH_FLAG; } else end_reached = 0; - C_bra(loop); + c_bra(loop); def_ilb(exit); break; } @@ -794,7 +794,7 @@ WalkStat(nd, exit_label, end_reached) end_reached |= WalkNode(right->nd_RIGHT, exit_label, end_reached); loopid->nd_def->df_flags &= ~D_FORLOOP; } - C_bra(l1); + c_bra(l1); def_ilb(l2); FreeInt(tmp); } @@ -842,7 +842,7 @@ WalkStat(nd, exit_label, end_reached) assert(exit_label != 0); if (end_reached & REACH_FLAG) end_reached = EXIT_FLAG; - C_bra(exit_label); + c_bra(exit_label); break; case RETURN: @@ -862,7 +862,7 @@ WalkStat(nd, exit_label, end_reached) } else CodePExpr(right); } - C_bra(RETURN_LABEL); + c_bra(RETURN_LABEL); break; default: diff --git a/lang/m2/comp/walk.h b/lang/m2/comp/walk.h index 0aa7e7598..80f978ef2 100644 --- a/lang/m2/comp/walk.h +++ b/lang/m2/comp/walk.h @@ -25,4 +25,5 @@ extern label data_label; #define c_loc(x) C_loc((arith) (x)) #define c_lae_dlb(x) C_lae_dlb(x,(arith) 0) #define CAL(nm, sz) (C_cal(nm), C_asp((arith)(sz))) +#define c_bra(x) C_bra((label) (x)) #endif