}
}
PROGRAM_NEXT_INSTRUCTION
+
+ PROGRAM_CASE(CLEAR_WORK_DONE) {
+ DEBUG_PRINTF("clear work_done flag\n");
+ work_done = 0;
+ }
+ PROGRAM_NEXT_INSTRUCTION
}
}
bool is_anchored_program) {
assert(!lit_ids.empty());
+ // If we have multiple literals and any of them squash groups, we will have
+ // to add a CLEAR_WORK_DONE instruction to each literal program block to
+ // clear the work_done flags so that it's only set if a state has been
+ // switched on for that literal.
+
+ // Note that we add it to every lit program, as they may be
+ // reordered/uniquified by assembleProgramBlocks() above.
+ const bool needs_clear_work = lit_ids.size() > 1 &&
+ any_of_in(lit_ids, [&](u32 lit_id) {
+ return build.literal_info.at(lit_id).squash_group;
+ });
+
vector<RoseProgram> blocks;
const vector<RoseEdge> no_edges;
}
auto prog = buildLiteralProgram(build, bc, prog_build, lit_id,
*edges_ptr, is_anchored_program);
+ if (needs_clear_work) {
+ RoseProgram clear_block;
+ clear_block.add_before_end(make_unique<RoseInstrClearWorkDone>());
+ prog.add_block(move(clear_block));
+ }
blocks.push_back(move(prog));
}
}
PROGRAM_NEXT_INSTRUCTION
+ PROGRAM_CASE(CLEAR_WORK_DONE) {}
+ PROGRAM_NEXT_INSTRUCTION
+
default:
os << " UNKNOWN (code " << int{code} << ")" << endl;
os << " <stopping>" << endl;
RoseInstrSuffixesEod::~RoseInstrSuffixesEod() = default;
RoseInstrMatcherEod::~RoseInstrMatcherEod() = default;
RoseInstrEnd::~RoseInstrEnd() = default;
+RoseInstrClearWorkDone::~RoseInstrClearWorkDone() = default;
using OffsetMap = RoseInstruction::OffsetMap;
}
};
+class RoseInstrClearWorkDone
+ : public RoseInstrBaseTrivial<ROSE_INSTR_CLEAR_WORK_DONE,
+ ROSE_STRUCT_CLEAR_WORK_DONE,
+ RoseInstrClearWorkDone> {
+public:
+ ~RoseInstrClearWorkDone() override;
+};
+
class RoseInstrEnd
: public RoseInstrBaseTrivial<ROSE_INSTR_END, ROSE_STRUCT_END,
RoseInstrEnd> {
*/
ROSE_INSTR_CHECK_MED_LIT_NOCASE,
- LAST_ROSE_INSTRUCTION = ROSE_INSTR_CHECK_MED_LIT_NOCASE //!< Sentinel.
+ /**
+ * \brief Clear the "work done" flag used by the SQUASH_GROUPS instruction.
+ */
+ ROSE_INSTR_CLEAR_WORK_DONE,
+
+ LAST_ROSE_INSTRUCTION = ROSE_INSTR_CLEAR_WORK_DONE //!< Sentinel.
};
struct ROSE_STRUCT_END {
u32 fail_jump; //!< Jump forward this many bytes on failure.
};
+struct ROSE_STRUCT_CLEAR_WORK_DONE {
+ u8 code; //!< From enum RoseInstructionCode.
+};
+
#endif // ROSE_ROSE_PROGRAM_H