diff --git a/src/rose/program_runtime.c b/src/rose/program_runtime.c index 97101e64..7f5150e0 100644 --- a/src/rose/program_runtime.c +++ b/src/rose/program_runtime.c @@ -2813,6 +2813,10 @@ hwlmcb_rv_t roseRunProgram_l(const struct RoseEngine *t, const char *pc_base = getByOffset(t, programOffset); const char *pc = pc_base; + // If this program has an effect, work_done will be set to one (which may + // allow the program to squash groups). + int work_done = 0; + struct RoseContext *tctxt = &scratch->tctxt; assert(*(const u8 *)pc != ROSE_INSTR_END); @@ -2893,6 +2897,7 @@ hwlmcb_rv_t roseRunProgram_l(const struct RoseEngine *t, INVALID_EKEY) == HWLM_TERMINATE_MATCHING) { return HWLM_TERMINATE_MATCHING; } + work_done = 1; } L_PROGRAM_NEXT_INSTRUCTION @@ -2902,6 +2907,7 @@ hwlmcb_rv_t roseRunProgram_l(const struct RoseEngine *t, ri->ekey) == HWLM_TERMINATE_MATCHING) { return HWLM_TERMINATE_MATCHING; } + work_done = 1; } L_PROGRAM_NEXT_INSTRUCTION @@ -2912,6 +2918,7 @@ hwlmcb_rv_t roseRunProgram_l(const struct RoseEngine *t, INVALID_EKEY) == HWLM_TERMINATE_MATCHING) { return HWLM_TERMINATE_MATCHING; } + work_done = 1; } L_PROGRAM_NEXT_INSTRUCTION @@ -2939,6 +2946,7 @@ hwlmcb_rv_t roseRunProgram_l(const struct RoseEngine *t, ekey) == HWLM_TERMINATE_MATCHING) { return HWLM_TERMINATE_MATCHING; } + work_done = 1; } L_PROGRAM_NEXT_INSTRUCTION @@ -2969,6 +2977,16 @@ hwlmcb_rv_t roseRunProgram_l(const struct RoseEngine *t, } L_PROGRAM_NEXT_INSTRUCTION + L_PROGRAM_CASE(SQUASH_GROUPS) { + assert(popcount64(ri->groups) == 63); // Squash only one group. + if (work_done) { + tctxt->groups &= ri->groups; + DEBUG_PRINTF("squash groups 0x%llx -> 0x%llx\n", ri->groups, + tctxt->groups); + } + } + L_PROGRAM_NEXT_INSTRUCTION + L_PROGRAM_CASE(CHECK_LONG_LIT) { const char nocase = 0; if (!roseCheckLongLiteral(t, scratch, end, ri->lit_offset, @@ -3017,6 +3035,12 @@ hwlmcb_rv_t roseRunProgram_l(const struct RoseEngine *t, } L_PROGRAM_NEXT_INSTRUCTION + L_PROGRAM_CASE(CLEAR_WORK_DONE) { + DEBUG_PRINTF("clear work_done flag\n"); + work_done = 0; + } + L_PROGRAM_NEXT_INSTRUCTION + L_PROGRAM_CASE(SET_LOGICAL) { DEBUG_PRINTF("set logical value of lkey %u, offset_adjust=%d\n", ri->lkey, ri->offset_adjust); @@ -3054,6 +3078,7 @@ hwlmcb_rv_t roseRunProgram_l(const struct RoseEngine *t, == HWLM_TERMINATE_MATCHING) { return HWLM_TERMINATE_MATCHING; } + work_done = 1; } L_PROGRAM_NEXT_INSTRUCTION