Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qt_mips_asm_dsp_p.h
Go to the documentation of this file.
1// Copyright (C) 2013 Imagination Technologies Limited, www.imgtec.com
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QT_MIPS_ASM_DSP_H
6#define QT_MIPS_ASM_DSP_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#if 0
20#pragma qt_sync_stop_processing
21#endif
22
23#ifndef Q_QDOC
24#define zero $0
25#define AT $1
26#define v0 $2
27#define v1 $3
28#define a0 $4
29#define a1 $5
30#define a2 $6
31#define a3 $7
32#define t0 $8
33#define t1 $9
34#define t2 $10
35#define t3 $11
36#define t4 $12
37#define t5 $13
38#define t6 $14
39#define t7 $15
40#define s0 $16
41#define s1 $17
42#define s2 $18
43#define s3 $19
44#define s4 $20
45#define s5 $21
46#define s6 $22
47#define s7 $23
48#define t8 $24
49#define t9 $25
50#define k0 $26
51#define k1 $27
52#define gp $28
53#define sp $29
54#define fp $30
55#define s8 $30
56#define ra $31
57#endif
58
59/*
60 * LEAF_MIPS32R2 - declare leaf_mips32r2 routine
61 */
62#define LEAF_MIPS32R2(symbol)
63 .globl symbol;
64 .align 2;
65 .type symbol,@function;
66 .ent symbol,0; symbol
67 : .frame sp, 0, ra;
68 .set arch=mips32r2;
69 .set noreorder;
70
71/*
72 * LEAF_MIPS_DSP - declare leaf_mips_dsp routine
73 */
74#define LEAF_MIPS_DSP(symbol) LEAF_MIPS32R2
75 (symbol)
76 .set dsp;
77
78/*
79 * LEAF_MIPS_DSPR2 - declare leaf_mips_dspr2 routine
80 */
81#define LEAF_MIPS_DSPR2(symbol) LEAF_MIPS32R2
82 (symbol)
83 .set dspr2;
84
85/*
86 * END - mark end of function
87 */
88#define END(function)
89 .set reorder;
90 .end function;
91 .size function,.-function
92
93/*
94 * BYTE_MUL operation on two pixels (in_1 and in_2) with two
95 * multiplicator bytes, repl_a1 and repl_a2, which should be
96 * prepered with:
97 * replv.ph repl_a1, a1
98 * replv.ph repl_a2, a2
99 * to became such as:
100 * repl_a1 = | 00 | a1 | 00 | a1 |
101 * repl_a2 = | 00 | a2 | 00 | a2 |
102 *
103 * rounding_factor must have following value:
104 * li rounding_factor, 0x00800080
105 *
106 * scratch(n) - temporary registers
107 *
108 * in_const: 1 -> (default) causes that in_1, in_2
109 * registers will remain unchanged after usage
110 * 0 -> (or anything different then 1) causes
111 * that registers repl_a1, repl_a2 remain
112 * unchanged after usage
113 */
114.macro BYTE_MUL_x2 in_1, in_2, out_1, out_2
115 repl_a1, repl_a2, rounding_factor,
116 scratch1, scratch2, scratch3, scratch4,
117 in_const = 1
118 muleu_s.ph.qbl \scratch1, \in_1, \repl_a1
119 muleu_s.ph.qbr \scratch2, \in_1, \repl_a1
120 muleu_s.ph.qbl \scratch3, \in_2, \repl_a2
121 muleu_s.ph.qbr \scratch4, \in_2, \repl_a2
122
123.if \in_const == 1
124 preceu.ph.qbla \repl_a1, \scratch1
125 preceu.ph.qbla \repl_a2, \scratch2
126 preceu.ph.qbla \out_1, \scratch3
127 preceu.ph.qbla \out_2, \scratch4
128
129 addu \scratch1, \repl_a1, \scratch1
130 addu \scratch2, \repl_a2, \scratch2
131.else
132 preceu.ph.qbla \in_1, \scratch1
133 preceu.ph.qbla \in_2, \scratch2
134 preceu.ph.qbla \out_1, \scratch3
135 preceu.ph.qbla \out_2, \scratch4
136
137 addu \scratch1, \in_1, \scratch1
138 addu \scratch2, \in_2, \scratch2
139.endif
140
141 addu \out_1, \out_1, \scratch3
142 addu \out_2, \out_2, \scratch4
143
144 addu \scratch1, \scratch1, \rounding_factor
145 addu \scratch2, \scratch2, \rounding_factor
146 addu \scratch3, \out_1, \rounding_factor
147 addu \scratch4, \out_2, \rounding_factor
148
149 precrq.qb.ph \out_1, \scratch1, \scratch2
150 precrq.qb.ph \out_2, \scratch3, \scratch4
151
152.endm
153
154/*
155 * BYTE_MUL operation on one pixel (in_1) with
156 * multiplicator byte, repl_a1, which should be
157 * prepered with:
158 * replv.ph repl_a1, a1
159 * to became such as:
160 * repl_a1 = | 00 | a1 | 00 | a1 |
161 *
162 * rounding_factor must have following value:
163 * li rounding_factor, 0x00800080
164 *
165 * scratch(n) - temporary registers
166 */
167.macro BYTE_MUL in_1, out_1,
168 repl_a1, rounding_factor,
169 scratch1, scratch2, scratch3, scratch4
170 muleu_s.ph.qbl \scratch1, \in_1, \repl_a1
171 muleu_s.ph.qbr \scratch2, \in_1, \repl_a1
172
173 preceu.ph.qbla \scratch3, \scratch1
174 preceu.ph.qbla \scratch4, \scratch2
175
176 addu \scratch1, \scratch1, \scratch3
177 addu \scratch1, \scratch1, \rounding_factor
178
179 addu \scratch2, \scratch2, \scratch4
180 addu \scratch2, \scratch2, \rounding_factor
181
182 precrq.qb.ph \out_1, \scratch1, \scratch2
183
184.endm
185
186/*
187 * macro for INTERPOLATE_PIXEL_255 operation
188 * in_1 - First value to multiply
189 * mul_1 - Multiplicator byte for first value
190 * in_2 - Second value to multiply
191 * mul_2 - Multiplicator byte for second value
192 * rounding_factor and andi_factor should be prepared
193 * as:
194 * li rounding_factor, 0x00800080
195 * li andi_factor, 0xff00ff00
196 * scratch(n) - temporary registers
197 */
198.macro INTERPOLATE_PIXEL_255 in_1, mul_1,
199 in_2, mul_2,
200 out_1,
201 rounding_factor, andi_factor
202 scratch1, scratch2, scratch3, scratch4
203# x part
204 preceu.ph.qbra \scratch1, \in_1
205 preceu.ph.qbra \scratch2, \in_2
206 mul \scratch1, \scratch1, \mul_1
207 mul \scratch2, \scratch2, \mul_2
208# x>>8 part
209 preceu.ph.qbla \scratch3, \in_1
210 preceu.ph.qbla \scratch4, \in_2
211 mul \scratch3, \scratch3, \mul_1
212 mul \scratch4, \scratch4, \mul_2
213# x part
214 addu \scratch1, \scratch1, \scratch2
215 preceu.ph.qbla \scratch2, \scratch1
216 addu \scratch1, \scratch1, \scratch2
217 addu \scratch1, \scratch1, \rounding_factor
218 preceu.ph.qbla \scratch1, \scratch1
219# x>>8 part
220 addu \scratch3, \scratch3, \scratch4
221 preceu.ph.qbla \scratch4, \scratch3
222 addu \scratch3, \scratch3, \scratch4
223 addu \scratch3, \scratch3, \rounding_factor
224 and \scratch3, \scratch3, \andi_factor
225
226 or \out_1, \scratch1, \scratch3
227.endm
228
229/*
230 * Checks if stack offset is big enough for storing/restoring regs_num
231 * number of register to/from stack. Stack offset must be greater than
232 * or equal to the number of bytes needed for storing registers (regs_num*4).
233 * Since MIPS ABI allows usage of first 16 bytes of stack frame (this is
234 * preserved for input arguments of the functions, already stored in a0-a3),
235 * stack size can be further optimized by utilizing this space.
236 */
237.macro CHECK_STACK_OFFSET regs_num, stack_offset
238.if \stack_offset < \regs_num * 4 - 16
239.error "Stack offset too small."
240.endif
241.endm
242
243/*
244 * Saves set of registers on stack. Maximum number of registers that
245 * can be saved on stack is limited to 14 (a0-a3, v0-v1 and s0-s7).
246 * Stack offset is number of bytes that are added to stack pointer (sp)
247 * before registers are pushed in order to provide enough space on stack
248 * (offset must be multiple of 4, and must be big enough, as described by
249 * CHECK_STACK_OFFSET macro). This macro is intended to be used in
250 * combination with RESTORE_REGS_FROM_STACK macro. Example:
251 * SAVE_REGS_ON_STACK 4, v0, v1, s0, s1
252 * RESTORE_REGS_FROM_STACK 4, v0, v1, s0, s1
253 */
254.macro SAVE_REGS_ON_STACK stack_offset = 0, r1,
255 r2 = 0, r3 = 0, r4 = 0,
256 r5 = 0, r6 = 0, r7 = 0,
257 r8 = 0, r9 = 0, r10 = 0,
258 r11 = 0, r12 = 0, r13 = 0,
259 r14 = 0
260 .if (\stack_offset < 0) || (\stack_offset - (\stack_offset / 4) * 4)
261 .error "Stack offset must be positive and multiple of 4."
262 .endif
263 .if \stack_offset != 0
264 addiu sp, sp, -\stack_offset
265 .endif
266 sw \r1, 0(sp)
267 .if \r2 != 0
268 sw \r2, 4(sp)
269 .endif
270 .if \r3 != 0
271 sw \r3, 8(sp)
272 .endif
273 .if \r4 != 0
274 sw \r4, 12(sp)
275 .endif
276 .if \r5 != 0
277 CHECK_STACK_OFFSET 5, \stack_offset
278 sw \r5, 16(sp)
279 .endif
280 .if \r6 != 0
281 CHECK_STACK_OFFSET 6, \stack_offset
282 sw \r6, 20(sp)
283 .endif
284 .if \r7 != 0
285 CHECK_STACK_OFFSET 7, \stack_offset
286 sw \r7, 24(sp)
287 .endif
288 .if \r8 != 0
289 CHECK_STACK_OFFSET 8, \stack_offset
290 sw \r8, 28(sp)
291 .endif
292 .if \r9 != 0
293 CHECK_STACK_OFFSET 9, \stack_offset
294 sw \r9, 32(sp)
295 .endif
296 .if \r10 != 0
297 CHECK_STACK_OFFSET 10, \stack_offset
298 sw \r10, 36(sp)
299 .endif
300 .if \r11 != 0
301 CHECK_STACK_OFFSET 11, \stack_offset
302 sw \r11, 40(sp)
303 .endif
304 .if \r12 != 0
305 CHECK_STACK_OFFSET 12, \stack_offset
306 sw \r12, 44(sp)
307 .endif
308 .if \r13 != 0
309 CHECK_STACK_OFFSET 13, \stack_offset
310 sw \r13, 48(sp)
311 .endif
312 .if \r14 != 0
313 CHECK_STACK_OFFSET 14, \stack_offset
314 sw \r14, 52(sp)
315 .endif
316.endm
317
318/*
319 * Restores set of registers from stack. Maximum number of registers that
320 * can be restored from stack is limited to 14 (a0-a3, v0-v1 and s0-s7).
321 * Stack offset is number of bytes that are added to stack pointer (sp)
322 * after registers are restored (offset must be multiple of 4, and must
323 * be big enough, as described by CHECK_STACK_OFFSET macro). This macro is
324 * intended to be used in combination with RESTORE_REGS_FROM_STACK macro.
325 * Example:
326 * SAVE_REGS_ON_STACK 4, v0, v1, s0, s1
327 * RESTORE_REGS_FROM_STACK 4, v0, v1, s0, s1
328 */
329.macro RESTORE_REGS_FROM_STACK stack_offset = 0, r1,
330 r2 = 0, r3 = 0, r4 = 0,
331 r5 = 0, r6 = 0, r7 = 0,
332 r8 = 0, r9 = 0, r10 = 0,
333 r11 = 0, r12 = 0, r13 = 0,
334 r14 = 0
335 .if (\stack_offset < 0) || (\stack_offset - (\stack_offset/4)*4)
336 .error "Stack offset must be pozitive and multiple of 4."
337 .endif
338 lw \r1, 0(sp)
339 .if \r2 != 0
340 lw \r2, 4(sp)
341 .endif
342 .if \r3 != 0
343 lw \r3, 8(sp)
344 .endif
345 .if \r4 != 0
346 lw \r4, 12(sp)
347 .endif
348 .if \r5 != 0
349 CHECK_STACK_OFFSET 5, \stack_offset
350 lw \r5, 16(sp)
351 .endif
352 .if \r6 != 0
353 CHECK_STACK_OFFSET 6, \stack_offset
354 lw \r6, 20(sp)
355 .endif
356 .if \r7 != 0
357 CHECK_STACK_OFFSET 7, \stack_offset
358 lw \r7, 24(sp)
359 .endif
360 .if \r8 != 0
361 CHECK_STACK_OFFSET 8, \stack_offset
362 lw \r8, 28(sp)
363 .endif
364 .if \r9 != 0
365 CHECK_STACK_OFFSET 9, \stack_offset
366 lw \r9, 32(sp)
367 .endif
368 .if \r10 != 0
369 CHECK_STACK_OFFSET 10, \stack_offset
370 lw \r10, 36(sp)
371 .endif
372 .if \r11 != 0
373 CHECK_STACK_OFFSET 11, \stack_offset
374 lw \r11, 40(sp)
375 .endif
376 .if \r12 != 0
377 CHECK_STACK_OFFSET 12, \stack_offset
378 lw \r12, 44(sp)
379 .endif
380 .if \r13 != 0
381 CHECK_STACK_OFFSET 13, \stack_offset
382 lw \r13, 48(sp)
383 .endif
384 .if \r14 != 0
385 CHECK_STACK_OFFSET 14, \stack_offset
386 lw \r14, 52(sp)
387 .endif
388 .if \stack_offset != 0
389 addiu sp, sp, \stack_offset
390 .endif
391.endm
392
393#endif // QT_MIPS_ASM_DSP_H
#define ra
#define sp