17c8da7ce66017295a65ec028084b90800be377f8James Zern// Copyright 2014 Google Inc. All Rights Reserved.
27c8da7ce66017295a65ec028084b90800be377f8James Zern//
37c8da7ce66017295a65ec028084b90800be377f8James Zern// Use of this source code is governed by a BSD-style license
47c8da7ce66017295a65ec028084b90800be377f8James Zern// that can be found in the COPYING file in the root of the source
57c8da7ce66017295a65ec028084b90800be377f8James Zern// tree. An additional intellectual property rights grant can be found
67c8da7ce66017295a65ec028084b90800be377f8James Zern// in the file PATENTS. All contributing project authors may
77c8da7ce66017295a65ec028084b90800be377f8James Zern// be found in the AUTHORS file in the root of the source tree.
87c8da7ce66017295a65ec028084b90800be377f8James Zern// -----------------------------------------------------------------------------
97c8da7ce66017295a65ec028084b90800be377f8James Zern//
107c8da7ce66017295a65ec028084b90800be377f8James Zern// MIPS version of rescaling functions
117c8da7ce66017295a65ec028084b90800be377f8James Zern//
127c8da7ce66017295a65ec028084b90800be377f8James Zern// Author(s): Djordje Pesut (djordje.pesut@imgtec.com)
137c8da7ce66017295a65ec028084b90800be377f8James Zern
14a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern#include "src/dsp/dsp.h"
157c8da7ce66017295a65ec028084b90800be377f8James Zern
16a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern#if defined(WEBP_USE_MIPS32) && !defined(WEBP_REDUCE_SIZE)
177c8da7ce66017295a65ec028084b90800be377f8James Zern
187c8da7ce66017295a65ec028084b90800be377f8James Zern#include <assert.h>
19a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern#include "src/utils/rescaler_utils.h"
207c8da7ce66017295a65ec028084b90800be377f8James Zern
217c8da7ce66017295a65ec028084b90800be377f8James Zern//------------------------------------------------------------------------------
227c8da7ce66017295a65ec028084b90800be377f8James Zern// Row import
237c8da7ce66017295a65ec028084b90800be377f8James Zern
24a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zernstatic void ImportRowShrink_MIPS32(WebPRescaler* const wrk,
25a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern                                   const uint8_t* src) {
267c8da7ce66017295a65ec028084b90800be377f8James Zern  const int x_stride = wrk->num_channels;
277c8da7ce66017295a65ec028084b90800be377f8James Zern  const int x_out_max = wrk->dst_width * wrk->num_channels;
287c8da7ce66017295a65ec028084b90800be377f8James Zern  const int fx_scale = wrk->fx_scale;
297c8da7ce66017295a65ec028084b90800be377f8James Zern  const int x_add = wrk->x_add;
307c8da7ce66017295a65ec028084b90800be377f8James Zern  const int x_sub = wrk->x_sub;
317c8da7ce66017295a65ec028084b90800be377f8James Zern  const int x_stride1 = x_stride << 2;
327c8da7ce66017295a65ec028084b90800be377f8James Zern  int channel;
337c8da7ce66017295a65ec028084b90800be377f8James Zern  assert(!wrk->x_expand);
347c8da7ce66017295a65ec028084b90800be377f8James Zern  assert(!WebPRescalerInputDone(wrk));
357c8da7ce66017295a65ec028084b90800be377f8James Zern
367c8da7ce66017295a65ec028084b90800be377f8James Zern  for (channel = 0; channel < x_stride; ++channel) {
377c8da7ce66017295a65ec028084b90800be377f8James Zern    const uint8_t* src1 = src + channel;
387c8da7ce66017295a65ec028084b90800be377f8James Zern    rescaler_t* frow = wrk->frow + channel;
397c8da7ce66017295a65ec028084b90800be377f8James Zern    int temp1, temp2, temp3;
407c8da7ce66017295a65ec028084b90800be377f8James Zern    int base, frac, sum;
417c8da7ce66017295a65ec028084b90800be377f8James Zern    int accum, accum1;
427c8da7ce66017295a65ec028084b90800be377f8James Zern    int loop_c = x_out_max - channel;
437c8da7ce66017295a65ec028084b90800be377f8James Zern
447c8da7ce66017295a65ec028084b90800be377f8James Zern    __asm__ volatile (
457c8da7ce66017295a65ec028084b90800be377f8James Zern      "li     %[temp1],   0x8000                    \n\t"
467c8da7ce66017295a65ec028084b90800be377f8James Zern      "li     %[temp2],   0x10000                   \n\t"
477c8da7ce66017295a65ec028084b90800be377f8James Zern      "li     %[sum],     0                         \n\t"
487c8da7ce66017295a65ec028084b90800be377f8James Zern      "li     %[accum],   0                         \n\t"
497c8da7ce66017295a65ec028084b90800be377f8James Zern    "1:                                             \n\t"
507c8da7ce66017295a65ec028084b90800be377f8James Zern      "addu   %[accum],   %[accum],   %[x_add]      \n\t"
517c8da7ce66017295a65ec028084b90800be377f8James Zern      "li     %[base],    0                         \n\t"
527c8da7ce66017295a65ec028084b90800be377f8James Zern      "blez   %[accum],   3f                        \n\t"
537c8da7ce66017295a65ec028084b90800be377f8James Zern    "2:                                             \n\t"
547c8da7ce66017295a65ec028084b90800be377f8James Zern      "lbu    %[base],    0(%[src1])                \n\t"
557c8da7ce66017295a65ec028084b90800be377f8James Zern      "subu   %[accum],   %[accum],   %[x_sub]      \n\t"
567c8da7ce66017295a65ec028084b90800be377f8James Zern      "addu   %[src1],    %[src1],    %[x_stride]   \n\t"
577c8da7ce66017295a65ec028084b90800be377f8James Zern      "addu   %[sum],     %[sum],     %[base]       \n\t"
587c8da7ce66017295a65ec028084b90800be377f8James Zern      "bgtz   %[accum],   2b                        \n\t"
597c8da7ce66017295a65ec028084b90800be377f8James Zern    "3:                                             \n\t"
607c8da7ce66017295a65ec028084b90800be377f8James Zern      "negu   %[accum1],  %[accum]                  \n\t"
617c8da7ce66017295a65ec028084b90800be377f8James Zern      "mul    %[frac],    %[base],    %[accum1]     \n\t"
627c8da7ce66017295a65ec028084b90800be377f8James Zern      "mul    %[temp3],   %[sum],     %[x_sub]      \n\t"
637c8da7ce66017295a65ec028084b90800be377f8James Zern      "subu   %[loop_c],  %[loop_c],  %[x_stride]   \n\t"
647c8da7ce66017295a65ec028084b90800be377f8James Zern      "mult   %[temp1],   %[temp2]                  \n\t"
657c8da7ce66017295a65ec028084b90800be377f8James Zern      "maddu  %[frac],    %[fx_scale]               \n\t"
667c8da7ce66017295a65ec028084b90800be377f8James Zern      "mfhi   %[sum]                                \n\t"
677c8da7ce66017295a65ec028084b90800be377f8James Zern      "subu   %[temp3],   %[temp3],   %[frac]       \n\t"
687c8da7ce66017295a65ec028084b90800be377f8James Zern      "sw     %[temp3],   0(%[frow])                \n\t"
697c8da7ce66017295a65ec028084b90800be377f8James Zern      "addu   %[frow],    %[frow],    %[x_stride1]  \n\t"
707c8da7ce66017295a65ec028084b90800be377f8James Zern      "bgtz   %[loop_c],  1b                        \n\t"
717c8da7ce66017295a65ec028084b90800be377f8James Zern      : [accum]"=&r"(accum), [src1]"+r"(src1), [temp3]"=&r"(temp3),
727c8da7ce66017295a65ec028084b90800be377f8James Zern        [sum]"=&r"(sum), [base]"=&r"(base), [frac]"=&r"(frac),
737c8da7ce66017295a65ec028084b90800be377f8James Zern        [frow]"+r"(frow), [accum1]"=&r"(accum1),
747c8da7ce66017295a65ec028084b90800be377f8James Zern        [temp2]"=&r"(temp2), [temp1]"=&r"(temp1)
757c8da7ce66017295a65ec028084b90800be377f8James Zern      : [x_stride]"r"(x_stride), [fx_scale]"r"(fx_scale),
767c8da7ce66017295a65ec028084b90800be377f8James Zern        [x_sub]"r"(x_sub), [x_add]"r"(x_add),
777c8da7ce66017295a65ec028084b90800be377f8James Zern        [loop_c]"r"(loop_c), [x_stride1]"r"(x_stride1)
787c8da7ce66017295a65ec028084b90800be377f8James Zern      : "memory", "hi", "lo"
797c8da7ce66017295a65ec028084b90800be377f8James Zern    );
807c8da7ce66017295a65ec028084b90800be377f8James Zern    assert(accum == 0);
817c8da7ce66017295a65ec028084b90800be377f8James Zern  }
827c8da7ce66017295a65ec028084b90800be377f8James Zern}
837c8da7ce66017295a65ec028084b90800be377f8James Zern
84a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zernstatic void ImportRowExpand_MIPS32(WebPRescaler* const wrk,
85a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern                                   const uint8_t* src) {
867c8da7ce66017295a65ec028084b90800be377f8James Zern  const int x_stride = wrk->num_channels;
877c8da7ce66017295a65ec028084b90800be377f8James Zern  const int x_out_max = wrk->dst_width * wrk->num_channels;
887c8da7ce66017295a65ec028084b90800be377f8James Zern  const int x_add = wrk->x_add;
897c8da7ce66017295a65ec028084b90800be377f8James Zern  const int x_sub = wrk->x_sub;
907c8da7ce66017295a65ec028084b90800be377f8James Zern  const int src_width = wrk->src_width;
917c8da7ce66017295a65ec028084b90800be377f8James Zern  const int x_stride1 = x_stride << 2;
927c8da7ce66017295a65ec028084b90800be377f8James Zern  int channel;
937c8da7ce66017295a65ec028084b90800be377f8James Zern  assert(wrk->x_expand);
947c8da7ce66017295a65ec028084b90800be377f8James Zern  assert(!WebPRescalerInputDone(wrk));
957c8da7ce66017295a65ec028084b90800be377f8James Zern
967c8da7ce66017295a65ec028084b90800be377f8James Zern  for (channel = 0; channel < x_stride; ++channel) {
977c8da7ce66017295a65ec028084b90800be377f8James Zern    const uint8_t* src1 = src + channel;
987c8da7ce66017295a65ec028084b90800be377f8James Zern    rescaler_t* frow = wrk->frow + channel;
997c8da7ce66017295a65ec028084b90800be377f8James Zern    int temp1, temp2, temp3, temp4;
1007c8da7ce66017295a65ec028084b90800be377f8James Zern    int frac;
1017c8da7ce66017295a65ec028084b90800be377f8James Zern    int accum;
1027c8da7ce66017295a65ec028084b90800be377f8James Zern    int x_out = channel;
1037c8da7ce66017295a65ec028084b90800be377f8James Zern
1047c8da7ce66017295a65ec028084b90800be377f8James Zern    __asm__ volatile (
1057c8da7ce66017295a65ec028084b90800be377f8James Zern      "addiu  %[temp3],   %[src_width], -1            \n\t"
1067c8da7ce66017295a65ec028084b90800be377f8James Zern      "lbu    %[temp2],   0(%[src1])                  \n\t"
1077c8da7ce66017295a65ec028084b90800be377f8James Zern      "addu   %[src1],    %[src1],      %[x_stride]   \n\t"
1087c8da7ce66017295a65ec028084b90800be377f8James Zern      "bgtz   %[temp3],   0f                          \n\t"
1097c8da7ce66017295a65ec028084b90800be377f8James Zern      "addiu  %[temp1],   %[temp2],     0             \n\t"
1107c8da7ce66017295a65ec028084b90800be377f8James Zern      "b      3f                                      \n\t"
1117c8da7ce66017295a65ec028084b90800be377f8James Zern    "0:                                               \n\t"
1127c8da7ce66017295a65ec028084b90800be377f8James Zern      "lbu    %[temp1],   0(%[src1])                  \n\t"
1137c8da7ce66017295a65ec028084b90800be377f8James Zern    "3:                                               \n\t"
1147c8da7ce66017295a65ec028084b90800be377f8James Zern      "addiu  %[accum],   %[x_add],     0             \n\t"
1157c8da7ce66017295a65ec028084b90800be377f8James Zern    "1:                                               \n\t"
1167c8da7ce66017295a65ec028084b90800be377f8James Zern      "subu   %[temp3],   %[temp2],     %[temp1]      \n\t"
1177c8da7ce66017295a65ec028084b90800be377f8James Zern      "mul    %[temp3],   %[temp3],     %[accum]      \n\t"
1187c8da7ce66017295a65ec028084b90800be377f8James Zern      "mul    %[temp4],   %[temp1],     %[x_add]      \n\t"
1197c8da7ce66017295a65ec028084b90800be377f8James Zern      "addu   %[temp3],   %[temp4],     %[temp3]      \n\t"
1207c8da7ce66017295a65ec028084b90800be377f8James Zern      "sw     %[temp3],   0(%[frow])                  \n\t"
1217c8da7ce66017295a65ec028084b90800be377f8James Zern      "addu   %[frow],    %[frow],      %[x_stride1]  \n\t"
1227c8da7ce66017295a65ec028084b90800be377f8James Zern      "addu   %[x_out],   %[x_out],     %[x_stride]   \n\t"
1237c8da7ce66017295a65ec028084b90800be377f8James Zern      "subu   %[temp3],   %[x_out],     %[x_out_max]  \n\t"
1247c8da7ce66017295a65ec028084b90800be377f8James Zern      "bgez   %[temp3],   2f                          \n\t"
1257c8da7ce66017295a65ec028084b90800be377f8James Zern      "subu   %[accum],   %[accum],     %[x_sub]      \n\t"
1267c8da7ce66017295a65ec028084b90800be377f8James Zern      "bgez   %[accum],   4f                          \n\t"
1277c8da7ce66017295a65ec028084b90800be377f8James Zern      "addiu  %[temp2],   %[temp1],     0             \n\t"
1287c8da7ce66017295a65ec028084b90800be377f8James Zern      "addu   %[src1],    %[src1],      %[x_stride]   \n\t"
1297c8da7ce66017295a65ec028084b90800be377f8James Zern      "lbu    %[temp1],   0(%[src1])                  \n\t"
1307c8da7ce66017295a65ec028084b90800be377f8James Zern      "addu   %[accum],   %[accum],     %[x_add]      \n\t"
1317c8da7ce66017295a65ec028084b90800be377f8James Zern    "4:                                               \n\t"
1327c8da7ce66017295a65ec028084b90800be377f8James Zern      "b      1b                                      \n\t"
1337c8da7ce66017295a65ec028084b90800be377f8James Zern    "2:                                               \n\t"
1347c8da7ce66017295a65ec028084b90800be377f8James Zern      : [src1]"+r"(src1), [accum]"=&r"(accum), [temp1]"=&r"(temp1),
1357c8da7ce66017295a65ec028084b90800be377f8James Zern        [temp2]"=&r"(temp2), [temp3]"=&r"(temp3), [temp4]"=&r"(temp4),
1367c8da7ce66017295a65ec028084b90800be377f8James Zern        [x_out]"+r"(x_out), [frac]"=&r"(frac), [frow]"+r"(frow)
1377c8da7ce66017295a65ec028084b90800be377f8James Zern      : [x_stride]"r"(x_stride), [x_add]"r"(x_add), [x_sub]"r"(x_sub),
1387c8da7ce66017295a65ec028084b90800be377f8James Zern        [x_stride1]"r"(x_stride1), [src_width]"r"(src_width),
1397c8da7ce66017295a65ec028084b90800be377f8James Zern        [x_out_max]"r"(x_out_max)
1407c8da7ce66017295a65ec028084b90800be377f8James Zern      : "memory", "hi", "lo"
1417c8da7ce66017295a65ec028084b90800be377f8James Zern    );
1427c8da7ce66017295a65ec028084b90800be377f8James Zern    assert(wrk->x_sub == 0 /* <- special case for src_width=1 */ || accum == 0);
1437c8da7ce66017295a65ec028084b90800be377f8James Zern  }
1447c8da7ce66017295a65ec028084b90800be377f8James Zern}
1457c8da7ce66017295a65ec028084b90800be377f8James Zern
1467c8da7ce66017295a65ec028084b90800be377f8James Zern//------------------------------------------------------------------------------
1477c8da7ce66017295a65ec028084b90800be377f8James Zern// Row export
1487c8da7ce66017295a65ec028084b90800be377f8James Zern
149a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zernstatic void ExportRowExpand_MIPS32(WebPRescaler* const wrk) {
1507c8da7ce66017295a65ec028084b90800be377f8James Zern  uint8_t* dst = wrk->dst;
1517c8da7ce66017295a65ec028084b90800be377f8James Zern  rescaler_t* irow = wrk->irow;
1527c8da7ce66017295a65ec028084b90800be377f8James Zern  const int x_out_max = wrk->dst_width * wrk->num_channels;
1537c8da7ce66017295a65ec028084b90800be377f8James Zern  const rescaler_t* frow = wrk->frow;
1547c8da7ce66017295a65ec028084b90800be377f8James Zern  int temp0, temp1, temp3, temp4, temp5, loop_end;
1557c8da7ce66017295a65ec028084b90800be377f8James Zern  const int temp2 = (int)wrk->fy_scale;
1567c8da7ce66017295a65ec028084b90800be377f8James Zern  const int temp6 = x_out_max << 2;
1577c8da7ce66017295a65ec028084b90800be377f8James Zern  assert(!WebPRescalerOutputDone(wrk));
1587c8da7ce66017295a65ec028084b90800be377f8James Zern  assert(wrk->y_accum <= 0);
1597c8da7ce66017295a65ec028084b90800be377f8James Zern  assert(wrk->y_expand);
1607c8da7ce66017295a65ec028084b90800be377f8James Zern  assert(wrk->y_sub != 0);
1617c8da7ce66017295a65ec028084b90800be377f8James Zern  if (wrk->y_accum == 0) {
1627c8da7ce66017295a65ec028084b90800be377f8James Zern    __asm__ volatile (
1637c8da7ce66017295a65ec028084b90800be377f8James Zern      "li       %[temp3],    0x10000                    \n\t"
1647c8da7ce66017295a65ec028084b90800be377f8James Zern      "li       %[temp4],    0x8000                     \n\t"
1657c8da7ce66017295a65ec028084b90800be377f8James Zern      "addu     %[loop_end], %[frow],     %[temp6]      \n\t"
1667c8da7ce66017295a65ec028084b90800be377f8James Zern    "1:                                                 \n\t"
1677c8da7ce66017295a65ec028084b90800be377f8James Zern      "lw       %[temp0],    0(%[frow])                 \n\t"
1687c8da7ce66017295a65ec028084b90800be377f8James Zern      "addiu    %[dst],      %[dst],      1             \n\t"
1697c8da7ce66017295a65ec028084b90800be377f8James Zern      "addiu    %[frow],     %[frow],     4             \n\t"
1707c8da7ce66017295a65ec028084b90800be377f8James Zern      "mult     %[temp3],    %[temp4]                   \n\t"
1717c8da7ce66017295a65ec028084b90800be377f8James Zern      "maddu    %[temp0],    %[temp2]                   \n\t"
1727c8da7ce66017295a65ec028084b90800be377f8James Zern      "mfhi     %[temp5]                                \n\t"
1737c8da7ce66017295a65ec028084b90800be377f8James Zern      "sb       %[temp5],    -1(%[dst])                 \n\t"
1747c8da7ce66017295a65ec028084b90800be377f8James Zern      "bne      %[frow],     %[loop_end], 1b            \n\t"
1757c8da7ce66017295a65ec028084b90800be377f8James Zern      : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp3]"=&r"(temp3),
1767c8da7ce66017295a65ec028084b90800be377f8James Zern        [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [frow]"+r"(frow),
1777c8da7ce66017295a65ec028084b90800be377f8James Zern        [dst]"+r"(dst), [loop_end]"=&r"(loop_end)
1787c8da7ce66017295a65ec028084b90800be377f8James Zern      : [temp2]"r"(temp2), [temp6]"r"(temp6)
1797c8da7ce66017295a65ec028084b90800be377f8James Zern      : "memory", "hi", "lo"
1807c8da7ce66017295a65ec028084b90800be377f8James Zern    );
1817c8da7ce66017295a65ec028084b90800be377f8James Zern  } else {
1827c8da7ce66017295a65ec028084b90800be377f8James Zern    const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub);
1837c8da7ce66017295a65ec028084b90800be377f8James Zern    const uint32_t A = (uint32_t)(WEBP_RESCALER_ONE - B);
1847c8da7ce66017295a65ec028084b90800be377f8James Zern    __asm__ volatile (
1857c8da7ce66017295a65ec028084b90800be377f8James Zern      "li       %[temp3],    0x10000                    \n\t"
1867c8da7ce66017295a65ec028084b90800be377f8James Zern      "li       %[temp4],    0x8000                     \n\t"
1877c8da7ce66017295a65ec028084b90800be377f8James Zern      "addu     %[loop_end], %[frow],     %[temp6]      \n\t"
1887c8da7ce66017295a65ec028084b90800be377f8James Zern    "1:                                                 \n\t"
1897c8da7ce66017295a65ec028084b90800be377f8James Zern      "lw       %[temp0],    0(%[frow])                 \n\t"
1907c8da7ce66017295a65ec028084b90800be377f8James Zern      "lw       %[temp1],    0(%[irow])                 \n\t"
1917c8da7ce66017295a65ec028084b90800be377f8James Zern      "addiu    %[dst],      %[dst],      1             \n\t"
1927c8da7ce66017295a65ec028084b90800be377f8James Zern      "mult     %[temp3],    %[temp4]                   \n\t"
1937c8da7ce66017295a65ec028084b90800be377f8James Zern      "maddu    %[A],        %[temp0]                   \n\t"
1947c8da7ce66017295a65ec028084b90800be377f8James Zern      "maddu    %[B],        %[temp1]                   \n\t"
1957c8da7ce66017295a65ec028084b90800be377f8James Zern      "addiu    %[frow],     %[frow],     4             \n\t"
1967c8da7ce66017295a65ec028084b90800be377f8James Zern      "addiu    %[irow],     %[irow],     4             \n\t"
1977c8da7ce66017295a65ec028084b90800be377f8James Zern      "mfhi     %[temp5]                                \n\t"
1987c8da7ce66017295a65ec028084b90800be377f8James Zern      "mult     %[temp3],    %[temp4]                   \n\t"
1997c8da7ce66017295a65ec028084b90800be377f8James Zern      "maddu    %[temp5],    %[temp2]                   \n\t"
2007c8da7ce66017295a65ec028084b90800be377f8James Zern      "mfhi     %[temp5]                                \n\t"
2017c8da7ce66017295a65ec028084b90800be377f8James Zern      "sb       %[temp5],    -1(%[dst])                 \n\t"
2027c8da7ce66017295a65ec028084b90800be377f8James Zern      "bne      %[frow],     %[loop_end], 1b            \n\t"
2037c8da7ce66017295a65ec028084b90800be377f8James Zern      : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp3]"=&r"(temp3),
2047c8da7ce66017295a65ec028084b90800be377f8James Zern        [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [frow]"+r"(frow),
2057c8da7ce66017295a65ec028084b90800be377f8James Zern        [irow]"+r"(irow), [dst]"+r"(dst), [loop_end]"=&r"(loop_end)
2067c8da7ce66017295a65ec028084b90800be377f8James Zern      : [temp2]"r"(temp2), [temp6]"r"(temp6), [A]"r"(A), [B]"r"(B)
2077c8da7ce66017295a65ec028084b90800be377f8James Zern      : "memory", "hi", "lo"
2087c8da7ce66017295a65ec028084b90800be377f8James Zern    );
2097c8da7ce66017295a65ec028084b90800be377f8James Zern  }
2107c8da7ce66017295a65ec028084b90800be377f8James Zern}
2117c8da7ce66017295a65ec028084b90800be377f8James Zern
212a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zernstatic void ExportRowShrink_MIPS32(WebPRescaler* const wrk) {
2137c8da7ce66017295a65ec028084b90800be377f8James Zern  const int x_out_max = wrk->dst_width * wrk->num_channels;
2147c8da7ce66017295a65ec028084b90800be377f8James Zern  uint8_t* dst = wrk->dst;
2157c8da7ce66017295a65ec028084b90800be377f8James Zern  rescaler_t* irow = wrk->irow;
2167c8da7ce66017295a65ec028084b90800be377f8James Zern  const rescaler_t* frow = wrk->frow;
2177c8da7ce66017295a65ec028084b90800be377f8James Zern  const int yscale = wrk->fy_scale * (-wrk->y_accum);
2187c8da7ce66017295a65ec028084b90800be377f8James Zern  int temp0, temp1, temp3, temp4, temp5, loop_end;
2197c8da7ce66017295a65ec028084b90800be377f8James Zern  const int temp2 = (int)wrk->fxy_scale;
2207c8da7ce66017295a65ec028084b90800be377f8James Zern  const int temp6 = x_out_max << 2;
2217c8da7ce66017295a65ec028084b90800be377f8James Zern
2227c8da7ce66017295a65ec028084b90800be377f8James Zern  assert(!WebPRescalerOutputDone(wrk));
2237c8da7ce66017295a65ec028084b90800be377f8James Zern  assert(wrk->y_accum <= 0);
2247c8da7ce66017295a65ec028084b90800be377f8James Zern  assert(!wrk->y_expand);
2257c8da7ce66017295a65ec028084b90800be377f8James Zern  assert(wrk->fxy_scale != 0);
2267c8da7ce66017295a65ec028084b90800be377f8James Zern  if (yscale) {
2277c8da7ce66017295a65ec028084b90800be377f8James Zern    __asm__ volatile (
2287c8da7ce66017295a65ec028084b90800be377f8James Zern      "li       %[temp3],    0x10000                    \n\t"
2297c8da7ce66017295a65ec028084b90800be377f8James Zern      "li       %[temp4],    0x8000                     \n\t"
2307c8da7ce66017295a65ec028084b90800be377f8James Zern      "addu     %[loop_end], %[frow],     %[temp6]      \n\t"
2317c8da7ce66017295a65ec028084b90800be377f8James Zern    "1:                                                 \n\t"
2327c8da7ce66017295a65ec028084b90800be377f8James Zern      "lw       %[temp0],    0(%[frow])                 \n\t"
2337c8da7ce66017295a65ec028084b90800be377f8James Zern      "mult     %[temp3],    %[temp4]                   \n\t"
2347c8da7ce66017295a65ec028084b90800be377f8James Zern      "addiu    %[frow],     %[frow],     4             \n\t"
2357c8da7ce66017295a65ec028084b90800be377f8James Zern      "maddu    %[temp0],    %[yscale]                  \n\t"
2367c8da7ce66017295a65ec028084b90800be377f8James Zern      "mfhi     %[temp1]                                \n\t"
2377c8da7ce66017295a65ec028084b90800be377f8James Zern      "lw       %[temp0],    0(%[irow])                 \n\t"
2387c8da7ce66017295a65ec028084b90800be377f8James Zern      "addiu    %[dst],      %[dst],      1             \n\t"
2397c8da7ce66017295a65ec028084b90800be377f8James Zern      "addiu    %[irow],     %[irow],     4             \n\t"
2407c8da7ce66017295a65ec028084b90800be377f8James Zern      "subu     %[temp0],    %[temp0],    %[temp1]      \n\t"
2417c8da7ce66017295a65ec028084b90800be377f8James Zern      "mult     %[temp3],    %[temp4]                   \n\t"
2427c8da7ce66017295a65ec028084b90800be377f8James Zern      "maddu    %[temp0],    %[temp2]                   \n\t"
2437c8da7ce66017295a65ec028084b90800be377f8James Zern      "mfhi     %[temp5]                                \n\t"
2447c8da7ce66017295a65ec028084b90800be377f8James Zern      "sw       %[temp1],    -4(%[irow])                \n\t"
2457c8da7ce66017295a65ec028084b90800be377f8James Zern      "sb       %[temp5],    -1(%[dst])                 \n\t"
2467c8da7ce66017295a65ec028084b90800be377f8James Zern      "bne      %[frow],     %[loop_end], 1b            \n\t"
2477c8da7ce66017295a65ec028084b90800be377f8James Zern      : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp3]"=&r"(temp3),
2487c8da7ce66017295a65ec028084b90800be377f8James Zern        [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [frow]"+r"(frow),
2497c8da7ce66017295a65ec028084b90800be377f8James Zern        [irow]"+r"(irow), [dst]"+r"(dst), [loop_end]"=&r"(loop_end)
2507c8da7ce66017295a65ec028084b90800be377f8James Zern      : [temp2]"r"(temp2), [yscale]"r"(yscale), [temp6]"r"(temp6)
2517c8da7ce66017295a65ec028084b90800be377f8James Zern      : "memory", "hi", "lo"
2527c8da7ce66017295a65ec028084b90800be377f8James Zern    );
2537c8da7ce66017295a65ec028084b90800be377f8James Zern  } else {
2547c8da7ce66017295a65ec028084b90800be377f8James Zern    __asm__ volatile (
2557c8da7ce66017295a65ec028084b90800be377f8James Zern      "li       %[temp3],    0x10000                    \n\t"
2567c8da7ce66017295a65ec028084b90800be377f8James Zern      "li       %[temp4],    0x8000                     \n\t"
2577c8da7ce66017295a65ec028084b90800be377f8James Zern      "addu     %[loop_end], %[irow],     %[temp6]      \n\t"
2587c8da7ce66017295a65ec028084b90800be377f8James Zern    "1:                                                 \n\t"
2597c8da7ce66017295a65ec028084b90800be377f8James Zern      "lw       %[temp0],    0(%[irow])                 \n\t"
2607c8da7ce66017295a65ec028084b90800be377f8James Zern      "addiu    %[dst],      %[dst],      1             \n\t"
2617c8da7ce66017295a65ec028084b90800be377f8James Zern      "addiu    %[irow],     %[irow],     4             \n\t"
2627c8da7ce66017295a65ec028084b90800be377f8James Zern      "mult     %[temp3],    %[temp4]                   \n\t"
2637c8da7ce66017295a65ec028084b90800be377f8James Zern      "maddu    %[temp0],    %[temp2]                   \n\t"
2647c8da7ce66017295a65ec028084b90800be377f8James Zern      "mfhi     %[temp5]                                \n\t"
2657c8da7ce66017295a65ec028084b90800be377f8James Zern      "sw       $zero,       -4(%[irow])                \n\t"
2667c8da7ce66017295a65ec028084b90800be377f8James Zern      "sb       %[temp5],    -1(%[dst])                 \n\t"
2677c8da7ce66017295a65ec028084b90800be377f8James Zern      "bne      %[irow],     %[loop_end], 1b            \n\t"
2687c8da7ce66017295a65ec028084b90800be377f8James Zern      : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp3]"=&r"(temp3),
2697c8da7ce66017295a65ec028084b90800be377f8James Zern        [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [irow]"+r"(irow),
2707c8da7ce66017295a65ec028084b90800be377f8James Zern        [dst]"+r"(dst), [loop_end]"=&r"(loop_end)
2717c8da7ce66017295a65ec028084b90800be377f8James Zern      : [temp2]"r"(temp2), [temp6]"r"(temp6)
2727c8da7ce66017295a65ec028084b90800be377f8James Zern      : "memory", "hi", "lo"
2737c8da7ce66017295a65ec028084b90800be377f8James Zern    );
2747c8da7ce66017295a65ec028084b90800be377f8James Zern  }
2757c8da7ce66017295a65ec028084b90800be377f8James Zern}
2767c8da7ce66017295a65ec028084b90800be377f8James Zern
2777c8da7ce66017295a65ec028084b90800be377f8James Zern//------------------------------------------------------------------------------
2787c8da7ce66017295a65ec028084b90800be377f8James Zern// Entry point
2797c8da7ce66017295a65ec028084b90800be377f8James Zern
2807c8da7ce66017295a65ec028084b90800be377f8James Zernextern void WebPRescalerDspInitMIPS32(void);
2817c8da7ce66017295a65ec028084b90800be377f8James Zern
2827c8da7ce66017295a65ec028084b90800be377f8James ZernWEBP_TSAN_IGNORE_FUNCTION void WebPRescalerDspInitMIPS32(void) {
283a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern  WebPRescalerImportRowExpand = ImportRowExpand_MIPS32;
284a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern  WebPRescalerImportRowShrink = ImportRowShrink_MIPS32;
285a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern  WebPRescalerExportRowExpand = ExportRowExpand_MIPS32;
286a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern  WebPRescalerExportRowShrink = ExportRowShrink_MIPS32;
2877c8da7ce66017295a65ec028084b90800be377f8James Zern}
2887c8da7ce66017295a65ec028084b90800be377f8James Zern
2897c8da7ce66017295a65ec028084b90800be377f8James Zern#else  // !WEBP_USE_MIPS32
2907c8da7ce66017295a65ec028084b90800be377f8James Zern
2917c8da7ce66017295a65ec028084b90800be377f8James ZernWEBP_DSP_INIT_STUB(WebPRescalerDspInitMIPS32)
2927c8da7ce66017295a65ec028084b90800be377f8James Zern
2937c8da7ce66017295a65ec028084b90800be377f8James Zern#endif  // WEBP_USE_MIPS32
294