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