+/* Tally, and optionally record, the specified match or literal. */
+static inline void
+xpress_declare_item(struct xpress_compressor *c, u32 mc_item_data,
+ struct xpress_item **next_chosen_item)
+{
+ unsigned len = mc_item_data & MC_LEN_MASK;
+ unsigned offset_data = mc_item_data >> MC_OFFSET_SHIFT;
+
+ if (len == 1)
+ xpress_declare_literal(c, offset_data, next_chosen_item);
+ else
+ xpress_declare_match(c, len, offset_data, next_chosen_item);
+}
+
+static inline void
+xpress_record_item_list(struct xpress_compressor *c,
+ struct xpress_mc_pos_data *cur_optimum_ptr,
+ struct xpress_item **next_chosen_item)
+{
+ struct xpress_mc_pos_data *end_optimum_ptr;
+ u32 saved_item;
+ u32 item;
+
+ /* The list is currently in reverse order (last item to first item).
+ * Reverse it. */
+ end_optimum_ptr = cur_optimum_ptr;
+ saved_item = cur_optimum_ptr->mc_item_data;
+ do {
+ item = saved_item;
+ cur_optimum_ptr -= item & MC_LEN_MASK;
+ saved_item = cur_optimum_ptr->mc_item_data;
+ cur_optimum_ptr->mc_item_data = item;
+ } while (cur_optimum_ptr != c->optimum);
+
+ /* Walk the list of items from beginning to end, tallying and recording
+ * each item. */
+ do {
+ xpress_declare_item(c, cur_optimum_ptr->mc_item_data, next_chosen_item);
+ cur_optimum_ptr += (cur_optimum_ptr->mc_item_data) & MC_LEN_MASK;
+ } while (cur_optimum_ptr != end_optimum_ptr);
+}
+
+static inline void
+xpress_tally_item_list(struct xpress_compressor *c,
+ struct xpress_mc_pos_data *cur_optimum_ptr)
+{
+ /* Since we're just tallying the items, we don't need to reverse the
+ * list. Processing the items in reverse order is fine. */
+ do {
+ xpress_declare_item(c, cur_optimum_ptr->mc_item_data, NULL);
+ cur_optimum_ptr -= (cur_optimum_ptr->mc_item_data & MC_LEN_MASK);
+ } while (cur_optimum_ptr != c->optimum);
+}
+
+/* Tally, and optionally (if next_chosen_item != NULL) record, in order, all
+ * items in the current list of items found by the match-chooser. */
+static void
+xpress_declare_item_list(struct xpress_compressor *c,
+ struct xpress_mc_pos_data *cur_optimum_ptr,
+ struct xpress_item **next_chosen_item)
+{
+ if (next_chosen_item)
+ xpress_record_item_list(c, cur_optimum_ptr, next_chosen_item);
+ else
+ xpress_tally_item_list(c, cur_optimum_ptr);