| 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@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 |  | 
|---|