1c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// Copyright 2014 Google Inc. All Rights Reserved.
2c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//
3c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// Use of this source code is governed by a BSD-style license
4c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// that can be found in the COPYING file in the root of the source
5c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// tree. An additional intellectual property rights grant can be found
6c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// in the file PATENTS. All contributing project authors may
7c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// be found in the AUTHORS file in the root of the source tree.
8c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// -----------------------------------------------------------------------------
9c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//
10c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// MIPS version of lossless functions
11c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//
12c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// Author(s):  Djordje Pesut    (djordje.pesut@imgtec.com)
13c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//             Jovan Zelincevic (jovan.zelincevic@imgtec.com)
14c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
15c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#include "./dsp.h"
16c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#include "./lossless.h"
17c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
18c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#if defined(WEBP_USE_MIPS32)
19c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
20c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#include <assert.h>
21c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#include <math.h>
22c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#include <stdlib.h>
23c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#include <string.h>
24c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
25c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#define APPROX_LOG_WITH_CORRECTION_MAX  65536
26c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#define APPROX_LOG_MAX                   4096
27c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#define LOG_2_RECIPROCAL 1.44269504088896338700465094007086
28c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
29c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdochstatic float FastSLog2Slow(uint32_t v) {
30c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  assert(v >= LOG_LOOKUP_IDX_MAX);
31c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
32c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    uint32_t log_cnt, y, correction;
33c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    const int c24 = 24;
34c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    const float v_f = (float)v;
35c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    uint32_t temp;
36c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
37c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    // Xf = 256 = 2^8
38c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    // log_cnt is index of leading one in upper 24 bits
39c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    __asm__ volatile(
40c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      "clz      %[log_cnt], %[v]                      \n\t"
41c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      "addiu    %[y],       $zero,        1           \n\t"
42c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      "subu     %[log_cnt], %[c24],       %[log_cnt]  \n\t"
43c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      "sllv     %[y],       %[y],         %[log_cnt]  \n\t"
44c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      "srlv     %[temp],    %[v],         %[log_cnt]  \n\t"
45c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      : [log_cnt]"=&r"(log_cnt), [y]"=&r"(y),
46c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch        [temp]"=r"(temp)
47c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      : [c24]"r"(c24), [v]"r"(v)
48c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    );
49c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
50c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    // vf = (2^log_cnt) * Xf; where y = 2^log_cnt and Xf < 256
51c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    // Xf = floor(Xf) * (1 + (v % y) / v)
52c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    // log2(Xf) = log2(floor(Xf)) + log2(1 + (v % y) / v)
53c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    // The correction factor: log(1 + d) ~ d; for very small d values, so
54c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    // log2(1 + (v % y) / v) ~ LOG_2_RECIPROCAL * (v % y)/v
55c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    // LOG_2_RECIPROCAL ~ 23/16
56c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
57c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    // (v % y) = (v % 2^log_cnt) = v & (2^log_cnt - 1)
58c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    correction = (23 * (v & (y - 1))) >> 4;
59c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    return v_f * (kLog2Table[temp] + log_cnt) + correction;
60c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  } else {
61c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    return (float)(LOG_2_RECIPROCAL * v * log((double)v));
62c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  }
63c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch}
64c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
65c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdochstatic float FastLog2Slow(uint32_t v) {
66c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  assert(v >= LOG_LOOKUP_IDX_MAX);
67c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
68c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    uint32_t log_cnt, y;
69c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    const int c24 = 24;
70c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    double log_2;
71c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    uint32_t temp;
72c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
73c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    __asm__ volatile(
74c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      "clz      %[log_cnt], %[v]                      \n\t"
75c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      "addiu    %[y],       $zero,        1           \n\t"
76c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      "subu     %[log_cnt], %[c24],       %[log_cnt]  \n\t"
77c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      "sllv     %[y],       %[y],         %[log_cnt]  \n\t"
78c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      "srlv     %[temp],    %[v],         %[log_cnt]  \n\t"
79c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      : [log_cnt]"=&r"(log_cnt), [y]"=&r"(y),
80c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch        [temp]"=r"(temp)
81c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      : [c24]"r"(c24), [v]"r"(v)
82c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    );
83c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
84c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    log_2 = kLog2Table[temp] + log_cnt;
85c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    if (v >= APPROX_LOG_MAX) {
86c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      // Since the division is still expensive, add this correction factor only
87c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      // for large values of 'v'.
88c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
89c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      const uint32_t correction = (23 * (v & (y - 1))) >> 4;
90c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      log_2 += (double)correction / v;
91c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    }
92c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    return (float)log_2;
93c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  } else {
94c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    return (float)(LOG_2_RECIPROCAL * log((double)v));
95c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  }
96c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch}
97c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
98c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// C version of this function:
99c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//   int i = 0;
100c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//   int64_t cost = 0;
101c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//   const uint32_t* pop = &population[4];
102c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//   const uint32_t* LoopEnd = &population[length];
103c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//   while (pop != LoopEnd) {
104c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//     ++i;
105c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//     cost += i * *pop;
106c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//     cost += i * *(pop + 1);
107c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//     pop += 2;
108c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//   }
109c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//   return (double)cost;
110c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdochstatic double ExtraCost(const uint32_t* const population, int length) {
111c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  int i, temp0, temp1;
112c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  const uint32_t* pop = &population[4];
113c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  const uint32_t* const LoopEnd = &population[length];
114c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
115c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  __asm__ volatile(
116c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "mult   $zero,    $zero                  \n\t"
117c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "xor    %[i],     %[i],       %[i]       \n\t"
118c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "beq    %[pop],   %[LoopEnd], 2f         \n\t"
119c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  "1:                                        \n\t"
120c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "lw     %[temp0], 0(%[pop])              \n\t"
121c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "lw     %[temp1], 4(%[pop])              \n\t"
122c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addiu  %[i],     %[i],       1          \n\t"
123c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addiu  %[pop],   %[pop],     8          \n\t"
124c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "madd   %[i],     %[temp0]               \n\t"
125c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "madd   %[i],     %[temp1]               \n\t"
126c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "bne    %[pop],   %[LoopEnd], 1b         \n\t"
127c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  "2:                                        \n\t"
128c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "mfhi   %[temp0]                         \n\t"
129c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "mflo   %[temp1]                         \n\t"
130c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
131c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      [i]"=&r"(i), [pop]"+r"(pop)
132c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    : [LoopEnd]"r"(LoopEnd)
133c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    : "memory", "hi", "lo"
134c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  );
135c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
136c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  return (double)((int64_t)temp0 << 32 | temp1);
137c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch}
138c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
139c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// C version of this function:
140c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//   int i = 0;
141c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//   int64_t cost = 0;
142c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//   const uint32_t* pX = &X[4];
143c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//   const uint32_t* pY = &Y[4];
144c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//   const uint32_t* LoopEnd = &X[length];
145c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//   while (pX != LoopEnd) {
146c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//     const uint32_t xy0 = *pX + *pY;
147c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//     const uint32_t xy1 = *(pX + 1) + *(pY + 1);
148c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//     ++i;
149c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//     cost += i * xy0;
150c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//     cost += i * xy1;
151c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//     pX += 2;
152c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//     pY += 2;
153c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//   }
154c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//   return (double)cost;
155c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdochstatic double ExtraCostCombined(const uint32_t* const X,
156c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch                                const uint32_t* const Y, int length) {
157c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  int i, temp0, temp1, temp2, temp3;
158c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  const uint32_t* pX = &X[4];
159c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  const uint32_t* pY = &Y[4];
160c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  const uint32_t* const LoopEnd = &X[length];
161c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
162c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  __asm__ volatile(
163c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "mult   $zero,    $zero                  \n\t"
164c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "xor    %[i],     %[i],       %[i]       \n\t"
165c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "beq    %[pX],    %[LoopEnd], 2f         \n\t"
166c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  "1:                                        \n\t"
167c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "lw     %[temp0], 0(%[pX])               \n\t"
168c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "lw     %[temp1], 0(%[pY])               \n\t"
169c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "lw     %[temp2], 4(%[pX])               \n\t"
170c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "lw     %[temp3], 4(%[pY])               \n\t"
171c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addiu  %[i],     %[i],       1          \n\t"
172c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addu   %[temp0], %[temp0],   %[temp1]   \n\t"
173c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addu   %[temp2], %[temp2],   %[temp3]   \n\t"
174c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addiu  %[pX],    %[pX],      8          \n\t"
175c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addiu  %[pY],    %[pY],      8          \n\t"
176c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "madd   %[i],     %[temp0]               \n\t"
177c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "madd   %[i],     %[temp2]               \n\t"
178c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "bne    %[pX],    %[LoopEnd], 1b         \n\t"
179c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  "2:                                        \n\t"
180c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "mfhi   %[temp0]                         \n\t"
181c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "mflo   %[temp1]                         \n\t"
182c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),
183c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),
184c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      [i]"=&r"(i), [pX]"+r"(pX), [pY]"+r"(pY)
185c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    : [LoopEnd]"r"(LoopEnd)
186c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    : "memory", "hi", "lo"
187c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  );
188c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
189c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  return (double)((int64_t)temp0 << 32 | temp1);
190c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch}
191c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
192c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#define HUFFMAN_COST_PASS                                 \
193c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  __asm__ volatile(                                       \
194c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "sll   %[temp1],  %[temp0],    3           \n\t"      \
195c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addiu %[temp3],  %[streak],   -3          \n\t"      \
196c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addu  %[temp2],  %[pstreaks], %[temp1]    \n\t"      \
197c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "blez  %[temp3],  1f                       \n\t"      \
198c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "srl   %[temp1],  %[temp1],    1           \n\t"      \
199c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addu  %[temp3],  %[pcnts],    %[temp1]    \n\t"      \
200c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "lw    %[temp0],  4(%[temp2])              \n\t"      \
201c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "lw    %[temp1],  0(%[temp3])              \n\t"      \
202c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addu  %[temp0],  %[temp0],    %[streak]   \n\t"      \
203c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addiu %[temp1],  %[temp1],    1           \n\t"      \
204c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "sw    %[temp0],  4(%[temp2])              \n\t"      \
205c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "sw    %[temp1],  0(%[temp3])              \n\t"      \
206c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "b     2f                                  \n\t"      \
207c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  "1:                                          \n\t"      \
208c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "lw    %[temp0],  0(%[temp2])              \n\t"      \
209c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addu  %[temp0],  %[temp0],    %[streak]   \n\t"      \
210c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "sw    %[temp0],  0(%[temp2])              \n\t"      \
211c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  "2:                                          \n\t"      \
212c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    : [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),           \
213c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      [temp3]"=&r"(temp3), [temp0]"+r"(temp0)             \
214c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    : [pstreaks]"r"(pstreaks), [pcnts]"r"(pcnts),         \
215c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      [streak]"r"(streak)                                 \
216c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    : "memory"                                            \
217c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  );
218c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
219c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// Returns the various RLE counts
220c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdochstatic VP8LStreaks HuffmanCostCount(const uint32_t* population, int length) {
221c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  int i;
222c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  int streak = 0;
223c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  VP8LStreaks stats;
224c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  int* const pstreaks = &stats.streaks[0][0];
225c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  int* const pcnts = &stats.counts[0];
226c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  int temp0, temp1, temp2, temp3;
227c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  memset(&stats, 0, sizeof(stats));
228c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  for (i = 0; i < length - 1; ++i) {
229c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ++streak;
230c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    if (population[i] == population[i + 1]) {
231c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      continue;
232c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    }
233c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    temp0 = (population[i] != 0);
234c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    HUFFMAN_COST_PASS
235c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    streak = 0;
236c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  }
237c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  ++streak;
238c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  temp0 = (population[i] != 0);
239c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  HUFFMAN_COST_PASS
240c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
241c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  return stats;
242c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch}
243c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
244c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdochstatic VP8LStreaks HuffmanCostCombinedCount(const uint32_t* X,
245c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch                                            const uint32_t* Y, int length) {
246c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  int i;
247c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  int streak = 0;
248c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  VP8LStreaks stats;
249c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  int* const pstreaks = &stats.streaks[0][0];
250c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  int* const pcnts = &stats.counts[0];
251c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  int temp0, temp1, temp2, temp3;
252c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  memset(&stats, 0, sizeof(stats));
253c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  for (i = 0; i < length - 1; ++i) {
254c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    const uint32_t xy = X[i] + Y[i];
255c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    const uint32_t xy_next = X[i + 1] + Y[i + 1];
256c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ++streak;
257c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    if (xy == xy_next) {
258c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      continue;
259c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    }
260c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    temp0 = (xy != 0);
261c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    HUFFMAN_COST_PASS
262c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    streak = 0;
263c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  }
264c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  {
265c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    const uint32_t xy = X[i] + Y[i];
266c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ++streak;
267c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    temp0 = (xy != 0);
268c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    HUFFMAN_COST_PASS
269c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  }
270c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
271c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  return stats;
272c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch}
273c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
274c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#define ASM_START                                       \
275c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  __asm__ volatile(                                     \
276c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ".set   push                            \n\t"       \
277c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ".set   at                              \n\t"       \
278c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ".set   macro                           \n\t"       \
279c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  "1:                                       \n\t"
280c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
281c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// P2 = P0 + P1
282c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// A..D - offsets
283c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// E - temp variable to tell macro
284c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//     if pointer should be incremented
285c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// literal_ and successive histograms could be unaligned
286c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// so we must use ulw and usw
287c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#define ADD_TO_OUT(A, B, C, D, E, P0, P1, P2)           \
288c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "ulw    %[temp0], "#A"(%["#P0"])        \n\t"       \
289c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "ulw    %[temp1], "#B"(%["#P0"])        \n\t"       \
290c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "ulw    %[temp2], "#C"(%["#P0"])        \n\t"       \
291c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "ulw    %[temp3], "#D"(%["#P0"])        \n\t"       \
292c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "ulw    %[temp4], "#A"(%["#P1"])        \n\t"       \
293c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "ulw    %[temp5], "#B"(%["#P1"])        \n\t"       \
294c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "ulw    %[temp6], "#C"(%["#P1"])        \n\t"       \
295c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "ulw    %[temp7], "#D"(%["#P1"])        \n\t"       \
296c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addu   %[temp4], %[temp4],   %[temp0]  \n\t"       \
297c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addu   %[temp5], %[temp5],   %[temp1]  \n\t"       \
298c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addu   %[temp6], %[temp6],   %[temp2]  \n\t"       \
299c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addu   %[temp7], %[temp7],   %[temp3]  \n\t"       \
300c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addiu  %["#P0"],  %["#P0"],  16        \n\t"       \
301c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  ".if "#E" == 1                            \n\t"       \
302c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addiu  %["#P1"],  %["#P1"],  16        \n\t"       \
303c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  ".endif                                   \n\t"       \
304c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "usw    %[temp4], "#A"(%["#P2"])        \n\t"       \
305c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "usw    %[temp5], "#B"(%["#P2"])        \n\t"       \
306c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "usw    %[temp6], "#C"(%["#P2"])        \n\t"       \
307c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "usw    %[temp7], "#D"(%["#P2"])        \n\t"       \
308c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "addiu  %["#P2"], %["#P2"],   16        \n\t"       \
309c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    "bne    %["#P0"], %[LoopEnd], 1b        \n\t"       \
310c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ".set   pop                             \n\t"       \
311c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
312c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#define ASM_END_COMMON_0                                \
313c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),         \
314c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),         \
315c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),         \
316c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      [temp6]"=&r"(temp6), [temp7]"=&r"(temp7),         \
317c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      [pa]"+r"(pa), [pout]"+r"(pout)
318c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
319c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#define ASM_END_COMMON_1                                \
320c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    : [LoopEnd]"r"(LoopEnd)                             \
321c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    : "memory", "at"                                    \
322c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  );
323c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
324c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#define ASM_END_0                                       \
325c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ASM_END_COMMON_0                                    \
326c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch      , [pb]"+r"(pb)                                    \
327c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ASM_END_COMMON_1
328c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
329c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#define ASM_END_1                                       \
330c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ASM_END_COMMON_0                                    \
331c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ASM_END_COMMON_1
332c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
333c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#define ADD_VECTOR(A, B, OUT, SIZE, EXTRA_SIZE)  do {   \
334c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  const uint32_t* pa = (const uint32_t*)(A);            \
335c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  const uint32_t* pb = (const uint32_t*)(B);            \
336c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  uint32_t* pout = (uint32_t*)(OUT);                    \
337c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  const uint32_t* const LoopEnd = pa + (SIZE);          \
338c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  assert((SIZE) % 4 == 0);                              \
339c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  ASM_START                                             \
340c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  ADD_TO_OUT(0, 4, 8, 12, 1, pa, pb, pout)              \
341c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  ASM_END_0                                             \
342c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  if ((EXTRA_SIZE) > 0) {                               \
343c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    const int last = (EXTRA_SIZE);                      \
344c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    int i;                                              \
345c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    for (i = 0; i < last; ++i) pout[i] = pa[i] + pb[i]; \
346c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  }                                                     \
347c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch} while (0)
348c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
349c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#define ADD_VECTOR_EQ(A, OUT, SIZE, EXTRA_SIZE)  do {   \
350c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  const uint32_t* pa = (const uint32_t*)(A);            \
351c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  uint32_t* pout = (uint32_t*)(OUT);                    \
352c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  const uint32_t* const LoopEnd = pa + (SIZE);          \
353c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  assert((SIZE) % 4 == 0);                              \
354c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  ASM_START                                             \
355c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  ADD_TO_OUT(0, 4, 8, 12, 0, pa, pout, pout)            \
356c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  ASM_END_1                                             \
357c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  if ((EXTRA_SIZE) > 0) {                               \
358c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    const int last = (EXTRA_SIZE);                      \
359c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    int i;                                              \
360c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    for (i = 0; i < last; ++i) pout[i] += pa[i];        \
361c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  }                                                     \
362c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch} while (0)
363c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
364c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdochstatic void HistogramAdd(const VP8LHistogram* const a,
365c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch                         const VP8LHistogram* const b,
366c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch                         VP8LHistogram* const out) {
367c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
368c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  const int extra_cache_size = VP8LHistogramNumCodes(a->palette_code_bits_)
369c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch                             - (NUM_LITERAL_CODES + NUM_LENGTH_CODES);
370c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  assert(a->palette_code_bits_ == b->palette_code_bits_);
371c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
372c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  if (b != out) {
373c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ADD_VECTOR(a->literal_, b->literal_, out->literal_,
374c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch               NUM_LITERAL_CODES + NUM_LENGTH_CODES, extra_cache_size);
375c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ADD_VECTOR(a->distance_, b->distance_, out->distance_,
376c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch               NUM_DISTANCE_CODES, 0);
377c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ADD_VECTOR(a->red_, b->red_, out->red_, NUM_LITERAL_CODES, 0);
378c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ADD_VECTOR(a->blue_, b->blue_, out->blue_, NUM_LITERAL_CODES, 0);
379c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ADD_VECTOR(a->alpha_, b->alpha_, out->alpha_, NUM_LITERAL_CODES, 0);
380c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  } else {
381c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ADD_VECTOR_EQ(a->literal_, out->literal_,
382c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch                  NUM_LITERAL_CODES + NUM_LENGTH_CODES, extra_cache_size);
383c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ADD_VECTOR_EQ(a->distance_, out->distance_, NUM_DISTANCE_CODES, 0);
384c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ADD_VECTOR_EQ(a->red_, out->red_, NUM_LITERAL_CODES, 0);
385c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ADD_VECTOR_EQ(a->blue_, out->blue_, NUM_LITERAL_CODES, 0);
386c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch    ADD_VECTOR_EQ(a->alpha_, out->alpha_, NUM_LITERAL_CODES, 0);
387c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  }
388c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch}
389c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
390c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#undef ADD_VECTOR_EQ
391c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#undef ADD_VECTOR
392c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#undef ASM_END_1
393c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#undef ASM_END_0
394c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#undef ASM_END_COMMON_1
395c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#undef ASM_END_COMMON_0
396c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#undef ADD_TO_OUT
397c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#undef ASM_START
398c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
399c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#endif  // WEBP_USE_MIPS32
400c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
401c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch//------------------------------------------------------------------------------
402c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch// Entry point
403c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
404c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdochextern void VP8LDspInitMIPS32(void);
405c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch
406c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdochvoid VP8LDspInitMIPS32(void) {
407c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#if defined(WEBP_USE_MIPS32)
408c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  VP8LFastSLog2Slow = FastSLog2Slow;
409c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  VP8LFastLog2Slow = FastLog2Slow;
410c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  VP8LExtraCost = ExtraCost;
411c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  VP8LExtraCostCombined = ExtraCostCombined;
412c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  VP8LHuffmanCostCount = HuffmanCostCount;
413c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  VP8LHuffmanCostCombinedCount = HuffmanCostCombinedCount;
414c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch  VP8LHistogramAdd = HistogramAdd;
415c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch#endif  // WEBP_USE_MIPS32
416c1942b189965ab0a2086aa6de64d966e9e16fe6bBen Murdoch}
417