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