Home | History | Annotate | Download | only in dsp
      1 // Copyright 2014 Google Inc. All Rights Reserved.
      2 //
      3 // Use of this source code is governed by a BSD-style license
      4 // that can be found in the COPYING file in the root of the source
      5 // tree. An additional intellectual property rights grant can be found
      6 // in the file PATENTS. All contributing project authors may
      7 // be found in the AUTHORS file in the root of the source tree.
      8 // -----------------------------------------------------------------------------
      9 //
     10 //   ARGB making functions (mips version).
     11 //
     12 // Author: Djordje Pesut (djordje.pesut (at) imgtec.com)
     13 
     14 #include "./dsp.h"
     15 
     16 #if defined(WEBP_USE_MIPS_DSP_R2)
     17 
     18 static void PackARGB(const uint8_t* a, const uint8_t* r, const uint8_t* g,
     19                      const uint8_t* b, int len, uint32_t* out) {
     20   int temp0, temp1, temp2, temp3, offset;
     21   const int rest = len & 1;
     22   const uint32_t* const loop_end = out + len - rest;
     23   const int step = 4;
     24   __asm__ volatile (
     25     "xor          %[offset],   %[offset], %[offset]    \n\t"
     26     "beq          %[loop_end], %[out],    0f           \n\t"
     27   "2:                                                  \n\t"
     28     "lbux         %[temp0],    %[offset](%[a])         \n\t"
     29     "lbux         %[temp1],    %[offset](%[r])         \n\t"
     30     "lbux         %[temp2],    %[offset](%[g])         \n\t"
     31     "lbux         %[temp3],    %[offset](%[b])         \n\t"
     32     "ins          %[temp1],    %[temp0],  16,     16   \n\t"
     33     "ins          %[temp3],    %[temp2],  16,     16   \n\t"
     34     "addiu        %[out],      %[out],    4            \n\t"
     35     "precr.qb.ph  %[temp0],    %[temp1],  %[temp3]     \n\t"
     36     "sw           %[temp0],    -4(%[out])              \n\t"
     37     "addu         %[offset],   %[offset], %[step]      \n\t"
     38     "bne          %[loop_end], %[out],    2b           \n\t"
     39   "0:                                                  \n\t"
     40     "beq          %[rest],     $zero,     1f           \n\t"
     41     "lbux         %[temp0],    %[offset](%[a])         \n\t"
     42     "lbux         %[temp1],    %[offset](%[r])         \n\t"
     43     "lbux         %[temp2],    %[offset](%[g])         \n\t"
     44     "lbux         %[temp3],    %[offset](%[b])         \n\t"
     45     "ins          %[temp1],    %[temp0],  16,     16   \n\t"
     46     "ins          %[temp3],    %[temp2],  16,     16   \n\t"
     47     "precr.qb.ph  %[temp0],    %[temp1],  %[temp3]     \n\t"
     48     "sw           %[temp0],    0(%[out])               \n\t"
     49   "1:                                                  \n\t"
     50     : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
     51       [temp3]"=&r"(temp3), [offset]"=&r"(offset), [out]"+&r"(out)
     52     : [a]"r"(a), [r]"r"(r), [g]"r"(g), [b]"r"(b), [step]"r"(step),
     53       [loop_end]"r"(loop_end), [rest]"r"(rest)
     54     : "memory"
     55   );
     56 }
     57 
     58 static void PackRGB(const uint8_t* r, const uint8_t* g, const uint8_t* b,
     59                     int len, int step, uint32_t* out) {
     60   int temp0, temp1, temp2, offset;
     61   const int rest = len & 1;
     62   const int a = 0xff;
     63   const uint32_t* const loop_end = out + len - rest;
     64   __asm__ volatile (
     65     "xor          %[offset],   %[offset], %[offset]    \n\t"
     66     "beq          %[loop_end], %[out],    0f           \n\t"
     67   "2:                                                  \n\t"
     68     "lbux         %[temp0],    %[offset](%[r])         \n\t"
     69     "lbux         %[temp1],    %[offset](%[g])         \n\t"
     70     "lbux         %[temp2],    %[offset](%[b])         \n\t"
     71     "ins          %[temp0],    %[a],      16,     16   \n\t"
     72     "ins          %[temp2],    %[temp1],  16,     16   \n\t"
     73     "addiu        %[out],      %[out],    4            \n\t"
     74     "precr.qb.ph  %[temp0],    %[temp0],  %[temp2]     \n\t"
     75     "sw           %[temp0],    -4(%[out])              \n\t"
     76     "addu         %[offset],   %[offset], %[step]      \n\t"
     77     "bne          %[loop_end], %[out],    2b           \n\t"
     78   "0:                                                  \n\t"
     79     "beq          %[rest],     $zero,     1f           \n\t"
     80     "lbux         %[temp0],    %[offset](%[r])         \n\t"
     81     "lbux         %[temp1],    %[offset](%[g])         \n\t"
     82     "lbux         %[temp2],    %[offset](%[b])         \n\t"
     83     "ins          %[temp0],    %[a],      16,     16   \n\t"
     84     "ins          %[temp2],    %[temp1],  16,     16   \n\t"
     85     "precr.qb.ph  %[temp0],    %[temp0],  %[temp2]     \n\t"
     86     "sw           %[temp0],    0(%[out])               \n\t"
     87   "1:                                                  \n\t"
     88     : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
     89       [offset]"=&r"(offset), [out]"+&r"(out)
     90     : [a]"r"(a), [r]"r"(r), [g]"r"(g), [b]"r"(b), [step]"r"(step),
     91       [loop_end]"r"(loop_end), [rest]"r"(rest)
     92     : "memory"
     93   );
     94 }
     95 
     96 //------------------------------------------------------------------------------
     97 // Entry point
     98 
     99 extern void VP8EncDspARGBInitMIPSdspR2(void);
    100 
    101 WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspARGBInitMIPSdspR2(void) {
    102   VP8PackARGB = PackARGB;
    103   VP8PackRGB = PackRGB;
    104 }
    105 
    106 #else  // !WEBP_USE_MIPS_DSP_R2
    107 
    108 WEBP_DSP_INIT_STUB(VP8EncDspARGBInitMIPSdspR2)
    109 
    110 #endif  // WEBP_USE_MIPS_DSP_R2
    111