+ unsigned i = 0;
+ unsigned len = 3;
+ struct xpress_mc_pos_data *optimum_ptr = &optimum[len];
+
+ if (matches[num_matches - 1].len < 0xf + XPRESS_MIN_MATCH_LEN) {
+ do {
+ u32 offset = matches[i].offset;
+ u32 offset_bsr = bsr32(offset);
+ unsigned len_hdr = len - XPRESS_MIN_MATCH_LEN;
+ unsigned sym = XPRESS_NUM_CHARS +
+ ((offset_bsr << 4) | len_hdr);
+ do {
+ optimum_ptr->prev.link = 0;
+ optimum_ptr->prev.match_offset = offset;
+ optimum_ptr->cost = offset_bsr + c->costs[sym];
+ sym++;
+ optimum_ptr++;
+ } while (++len <= matches[i].len);
+ } while (++i != num_matches);
+ } else {
+ do {
+ u32 offset = matches[i].offset;
+ u32 offset_bsr = bsr32(offset);
+ do {
+ u32 adjusted_len = len - XPRESS_MIN_MATCH_LEN;
+ unsigned len_hdr = min(adjusted_len, 0xf);
+ unsigned sym = XPRESS_NUM_CHARS +
+ ((offset_bsr << 4) | len_hdr);
+ u32 cost = offset_bsr + c->costs[sym];
+ if (adjusted_len >= 0xf) {
+ cost += 8;
+ if (adjusted_len - 0xf >= 0xff)
+ cost += 16;
+ }
+
+ optimum_ptr->prev.link = 0;
+ optimum_ptr->prev.match_offset = offset;
+ optimum_ptr->cost = cost;
+ optimum_ptr++;
+ } while (++len <= matches[i].len);
+ } while (++i != num_matches);
+ }
+ }
+
+ end_pos = matches[num_matches - 1].len;
+ cur_pos = 1;
+ do {
+ u32 cost;
+ u32 longest_len;
+
+ num_matches = xpress_get_matches(c, &matches);
+
+ if (num_matches) {
+ longest_len = matches[num_matches - 1].len;
+ if (longest_len >= c->params.nice_match_length) {
+ /* Take the long match immediately. */
+ match = xpress_match_chooser_reverse_list(c, cur_pos);
+
+ optimum[cur_pos].next.match_offset =
+ matches[num_matches - 1].offset;
+ optimum[cur_pos].next.link = cur_pos + longest_len;
+ c->optimum_end_idx = cur_pos + longest_len;
+
+ xpress_skip_bytes(c, longest_len - 1);
+
+ return match;
+ }
+ } else {
+ longest_len = 1;
+ }
+
+ while (end_pos < cur_pos + longest_len)
+ optimum[++end_pos].cost = MC_INFINITE_COST;
+
+ /* Consider coding a literal. */
+ cost = optimum[cur_pos].cost + xpress_prev_literal_cost(c);
+ if (cost < optimum[cur_pos + 1].cost) {
+ optimum[cur_pos + 1].cost = cost;
+ optimum[cur_pos + 1].prev.link = cur_pos;
+ }
+
+ if (num_matches) {
+ /* Consider coding a match. Cost evaluation is
+ * hand-inlined so that we can do some performance
+ * hacks. */
+ unsigned i = 0;
+ unsigned len = 3;
+ struct xpress_mc_pos_data *optimum_ptr = &optimum[cur_pos + 3];
+ u32 cur_cost = optimum[cur_pos].cost;
+
+ if (matches[num_matches - 1].len < 0xf + XPRESS_MIN_MATCH_LEN) {
+ do {
+ u32 offset = matches[i].offset;
+ u32 offset_bsr = bsr32(offset);
+ unsigned len_hdr = len - XPRESS_MIN_MATCH_LEN;
+ unsigned sym = XPRESS_NUM_CHARS +
+ ((offset_bsr << 4) | len_hdr);
+
+ u32 base_cost = cur_cost + offset_bsr;
+ do {
+ cost = base_cost + c->costs[sym];
+ if (cost < optimum_ptr->cost) {
+ optimum_ptr->prev.link = cur_pos;
+ optimum_ptr->prev.match_offset = offset;
+ optimum_ptr->cost = cost;
+ }
+ sym++;
+ optimum_ptr++;
+ } while (++len <= matches[i].len);
+ } while (++i != num_matches);
+ } else {
+ do {
+ u32 offset = matches[i].offset;
+ u32 offset_bsr = bsr32(offset);
+
+ u32 base_cost = cur_cost + offset_bsr;
+ do {
+ u32 adjusted_len = len - XPRESS_MIN_MATCH_LEN;
+ unsigned len_hdr = min(adjusted_len, 0xf);
+ unsigned sym = XPRESS_NUM_CHARS +
+ ((offset_bsr << 4) | len_hdr);
+
+ cost = base_cost + c->costs[sym];
+ if (adjusted_len >= 0xf) {
+ cost += 8;
+ if (adjusted_len - 0xf >= 0xff)
+ cost += 16;
+ }
+
+ if (cost < optimum_ptr->cost) {
+ optimum_ptr->prev.link = cur_pos;
+ optimum_ptr->prev.match_offset = offset;
+ optimum_ptr->cost = cost;
+ }
+ optimum_ptr++;
+ } while (++len <= matches[i].len);
+ } while (++i != num_matches);