drm/rockchip: vop2: Fix the windows switch between different layers
[drm/drm-misc.git] / arch / mips / include / asm / unaligned-emul.h
blob9af0f4d3d288c47b77e4270b9476f9a5fc17ceb9
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 #ifndef _ASM_MIPS_UNALIGNED_EMUL_H
3 #define _ASM_MIPS_UNALIGNED_EMUL_H
5 #include <asm/asm.h>
7 #ifdef __BIG_ENDIAN
8 #define _LoadHW(addr, value, res, type) \
9 do { \
10 __asm__ __volatile__ (".set\tnoat\n" \
11 "1:\t"type##_lb("%0", "0(%2)")"\n" \
12 "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\
13 "sll\t%0, 0x8\n\t" \
14 "or\t%0, $1\n\t" \
15 "li\t%1, 0\n" \
16 "3:\t.set\tat\n\t" \
17 ".insn\n\t" \
18 ".section\t.fixup,\"ax\"\n\t" \
19 "4:\tli\t%1, %3\n\t" \
20 "j\t3b\n\t" \
21 ".previous\n\t" \
22 ".section\t__ex_table,\"a\"\n\t" \
23 STR(PTR_WD)"\t1b, 4b\n\t" \
24 STR(PTR_WD)"\t2b, 4b\n\t" \
25 ".previous" \
26 : "=&r" (value), "=r" (res) \
27 : "r" (addr), "i" (-EFAULT)); \
28 } while (0)
30 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
31 #define _LoadW(addr, value, res, type) \
32 do { \
33 __asm__ __volatile__ ( \
34 "1:\t"type##_lwl("%0", "(%2)")"\n" \
35 "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
36 "li\t%1, 0\n" \
37 "3:\n\t" \
38 ".insn\n\t" \
39 ".section\t.fixup,\"ax\"\n\t" \
40 "4:\tli\t%1, %3\n\t" \
41 "j\t3b\n\t" \
42 ".previous\n\t" \
43 ".section\t__ex_table,\"a\"\n\t" \
44 STR(PTR_WD)"\t1b, 4b\n\t" \
45 STR(PTR_WD)"\t2b, 4b\n\t" \
46 ".previous" \
47 : "=&r" (value), "=r" (res) \
48 : "r" (addr), "i" (-EFAULT)); \
49 } while (0)
51 #else /* CONFIG_CPU_NO_LOAD_STORE_LR */
52 /* For CPUs without lwl instruction */
53 #define _LoadW(addr, value, res, type) \
54 do { \
55 __asm__ __volatile__ ( \
56 ".set\tpush\n" \
57 ".set\tnoat\n\t" \
58 "1:"type##_lb("%0", "0(%2)")"\n\t" \
59 "2:"type##_lbu("$1", "1(%2)")"\n\t" \
60 "sll\t%0, 0x8\n\t" \
61 "or\t%0, $1\n\t" \
62 "3:"type##_lbu("$1", "2(%2)")"\n\t" \
63 "sll\t%0, 0x8\n\t" \
64 "or\t%0, $1\n\t" \
65 "4:"type##_lbu("$1", "3(%2)")"\n\t" \
66 "sll\t%0, 0x8\n\t" \
67 "or\t%0, $1\n\t" \
68 "li\t%1, 0\n" \
69 ".set\tpop\n" \
70 "10:\n\t" \
71 ".insn\n\t" \
72 ".section\t.fixup,\"ax\"\n\t" \
73 "11:\tli\t%1, %3\n\t" \
74 "j\t10b\n\t" \
75 ".previous\n\t" \
76 ".section\t__ex_table,\"a\"\n\t" \
77 STR(PTR_WD)"\t1b, 11b\n\t" \
78 STR(PTR_WD)"\t2b, 11b\n\t" \
79 STR(PTR_WD)"\t3b, 11b\n\t" \
80 STR(PTR_WD)"\t4b, 11b\n\t" \
81 ".previous" \
82 : "=&r" (value), "=r" (res) \
83 : "r" (addr), "i" (-EFAULT)); \
84 } while (0)
86 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
88 #define _LoadHWU(addr, value, res, type) \
89 do { \
90 __asm__ __volatile__ ( \
91 ".set\tnoat\n" \
92 "1:\t"type##_lbu("%0", "0(%2)")"\n" \
93 "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\
94 "sll\t%0, 0x8\n\t" \
95 "or\t%0, $1\n\t" \
96 "li\t%1, 0\n" \
97 "3:\n\t" \
98 ".insn\n\t" \
99 ".set\tat\n\t" \
100 ".section\t.fixup,\"ax\"\n\t" \
101 "4:\tli\t%1, %3\n\t" \
102 "j\t3b\n\t" \
103 ".previous\n\t" \
104 ".section\t__ex_table,\"a\"\n\t" \
105 STR(PTR_WD)"\t1b, 4b\n\t" \
106 STR(PTR_WD)"\t2b, 4b\n\t" \
107 ".previous" \
108 : "=&r" (value), "=r" (res) \
109 : "r" (addr), "i" (-EFAULT)); \
110 } while (0)
112 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
113 #define _LoadWU(addr, value, res, type) \
114 do { \
115 __asm__ __volatile__ ( \
116 "1:\t"type##_lwl("%0", "(%2)")"\n" \
117 "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
118 "dsll\t%0, %0, 32\n\t" \
119 "dsrl\t%0, %0, 32\n\t" \
120 "li\t%1, 0\n" \
121 "3:\n\t" \
122 ".insn\n\t" \
123 "\t.section\t.fixup,\"ax\"\n\t" \
124 "4:\tli\t%1, %3\n\t" \
125 "j\t3b\n\t" \
126 ".previous\n\t" \
127 ".section\t__ex_table,\"a\"\n\t" \
128 STR(PTR_WD)"\t1b, 4b\n\t" \
129 STR(PTR_WD)"\t2b, 4b\n\t" \
130 ".previous" \
131 : "=&r" (value), "=r" (res) \
132 : "r" (addr), "i" (-EFAULT)); \
133 } while (0)
135 #define _LoadDW(addr, value, res) \
136 do { \
137 __asm__ __volatile__ ( \
138 "1:\tldl\t%0, (%2)\n" \
139 "2:\tldr\t%0, 7(%2)\n\t" \
140 "li\t%1, 0\n" \
141 "3:\n\t" \
142 ".insn\n\t" \
143 "\t.section\t.fixup,\"ax\"\n\t" \
144 "4:\tli\t%1, %3\n\t" \
145 "j\t3b\n\t" \
146 ".previous\n\t" \
147 ".section\t__ex_table,\"a\"\n\t" \
148 STR(PTR_WD)"\t1b, 4b\n\t" \
149 STR(PTR_WD)"\t2b, 4b\n\t" \
150 ".previous" \
151 : "=&r" (value), "=r" (res) \
152 : "r" (addr), "i" (-EFAULT)); \
153 } while (0)
155 #else /* CONFIG_CPU_NO_LOAD_STORE_LR */
156 /* For CPUs without lwl and ldl instructions */
157 #define _LoadWU(addr, value, res, type) \
158 do { \
159 __asm__ __volatile__ ( \
160 ".set\tpush\n\t" \
161 ".set\tnoat\n\t" \
162 "1:"type##_lbu("%0", "0(%2)")"\n\t" \
163 "2:"type##_lbu("$1", "1(%2)")"\n\t" \
164 "sll\t%0, 0x8\n\t" \
165 "or\t%0, $1\n\t" \
166 "3:"type##_lbu("$1", "2(%2)")"\n\t" \
167 "sll\t%0, 0x8\n\t" \
168 "or\t%0, $1\n\t" \
169 "4:"type##_lbu("$1", "3(%2)")"\n\t" \
170 "sll\t%0, 0x8\n\t" \
171 "or\t%0, $1\n\t" \
172 "li\t%1, 0\n" \
173 ".set\tpop\n" \
174 "10:\n\t" \
175 ".insn\n\t" \
176 ".section\t.fixup,\"ax\"\n\t" \
177 "11:\tli\t%1, %3\n\t" \
178 "j\t10b\n\t" \
179 ".previous\n\t" \
180 ".section\t__ex_table,\"a\"\n\t" \
181 STR(PTR_WD)"\t1b, 11b\n\t" \
182 STR(PTR_WD)"\t2b, 11b\n\t" \
183 STR(PTR_WD)"\t3b, 11b\n\t" \
184 STR(PTR_WD)"\t4b, 11b\n\t" \
185 ".previous" \
186 : "=&r" (value), "=r" (res) \
187 : "r" (addr), "i" (-EFAULT)); \
188 } while (0)
190 #define _LoadDW(addr, value, res) \
191 do { \
192 __asm__ __volatile__ ( \
193 ".set\tpush\n\t" \
194 ".set\tnoat\n\t" \
195 "1:lb\t%0, 0(%2)\n\t" \
196 "2:lbu\t $1, 1(%2)\n\t" \
197 "dsll\t%0, 0x8\n\t" \
198 "or\t%0, $1\n\t" \
199 "3:lbu\t$1, 2(%2)\n\t" \
200 "dsll\t%0, 0x8\n\t" \
201 "or\t%0, $1\n\t" \
202 "4:lbu\t$1, 3(%2)\n\t" \
203 "dsll\t%0, 0x8\n\t" \
204 "or\t%0, $1\n\t" \
205 "5:lbu\t$1, 4(%2)\n\t" \
206 "dsll\t%0, 0x8\n\t" \
207 "or\t%0, $1\n\t" \
208 "6:lbu\t$1, 5(%2)\n\t" \
209 "dsll\t%0, 0x8\n\t" \
210 "or\t%0, $1\n\t" \
211 "7:lbu\t$1, 6(%2)\n\t" \
212 "dsll\t%0, 0x8\n\t" \
213 "or\t%0, $1\n\t" \
214 "8:lbu\t$1, 7(%2)\n\t" \
215 "dsll\t%0, 0x8\n\t" \
216 "or\t%0, $1\n\t" \
217 "li\t%1, 0\n" \
218 ".set\tpop\n\t" \
219 "10:\n\t" \
220 ".insn\n\t" \
221 ".section\t.fixup,\"ax\"\n\t" \
222 "11:\tli\t%1, %3\n\t" \
223 "j\t10b\n\t" \
224 ".previous\n\t" \
225 ".section\t__ex_table,\"a\"\n\t" \
226 STR(PTR_WD)"\t1b, 11b\n\t" \
227 STR(PTR_WD)"\t2b, 11b\n\t" \
228 STR(PTR_WD)"\t3b, 11b\n\t" \
229 STR(PTR_WD)"\t4b, 11b\n\t" \
230 STR(PTR_WD)"\t5b, 11b\n\t" \
231 STR(PTR_WD)"\t6b, 11b\n\t" \
232 STR(PTR_WD)"\t7b, 11b\n\t" \
233 STR(PTR_WD)"\t8b, 11b\n\t" \
234 ".previous" \
235 : "=&r" (value), "=r" (res) \
236 : "r" (addr), "i" (-EFAULT)); \
237 } while (0)
239 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
242 #define _StoreHW(addr, value, res, type) \
243 do { \
244 __asm__ __volatile__ ( \
245 ".set\tnoat\n" \
246 "1:\t"type##_sb("%1", "1(%2)")"\n" \
247 "srl\t$1, %1, 0x8\n" \
248 "2:\t"type##_sb("$1", "0(%2)")"\n" \
249 ".set\tat\n\t" \
250 "li\t%0, 0\n" \
251 "3:\n\t" \
252 ".insn\n\t" \
253 ".section\t.fixup,\"ax\"\n\t" \
254 "4:\tli\t%0, %3\n\t" \
255 "j\t3b\n\t" \
256 ".previous\n\t" \
257 ".section\t__ex_table,\"a\"\n\t" \
258 STR(PTR_WD)"\t1b, 4b\n\t" \
259 STR(PTR_WD)"\t2b, 4b\n\t" \
260 ".previous" \
261 : "=r" (res) \
262 : "r" (value), "r" (addr), "i" (-EFAULT));\
263 } while (0)
265 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
266 #define _StoreW(addr, value, res, type) \
267 do { \
268 __asm__ __volatile__ ( \
269 "1:\t"type##_swl("%1", "(%2)")"\n" \
270 "2:\t"type##_swr("%1", "3(%2)")"\n\t"\
271 "li\t%0, 0\n" \
272 "3:\n\t" \
273 ".insn\n\t" \
274 ".section\t.fixup,\"ax\"\n\t" \
275 "4:\tli\t%0, %3\n\t" \
276 "j\t3b\n\t" \
277 ".previous\n\t" \
278 ".section\t__ex_table,\"a\"\n\t" \
279 STR(PTR_WD)"\t1b, 4b\n\t" \
280 STR(PTR_WD)"\t2b, 4b\n\t" \
281 ".previous" \
282 : "=r" (res) \
283 : "r" (value), "r" (addr), "i" (-EFAULT)); \
284 } while (0)
286 #define _StoreDW(addr, value, res) \
287 do { \
288 __asm__ __volatile__ ( \
289 "1:\tsdl\t%1,(%2)\n" \
290 "2:\tsdr\t%1, 7(%2)\n\t" \
291 "li\t%0, 0\n" \
292 "3:\n\t" \
293 ".insn\n\t" \
294 ".section\t.fixup,\"ax\"\n\t" \
295 "4:\tli\t%0, %3\n\t" \
296 "j\t3b\n\t" \
297 ".previous\n\t" \
298 ".section\t__ex_table,\"a\"\n\t" \
299 STR(PTR_WD)"\t1b, 4b\n\t" \
300 STR(PTR_WD)"\t2b, 4b\n\t" \
301 ".previous" \
302 : "=r" (res) \
303 : "r" (value), "r" (addr), "i" (-EFAULT)); \
304 } while (0)
306 #else /* CONFIG_CPU_NO_LOAD_STORE_LR */
307 #define _StoreW(addr, value, res, type) \
308 do { \
309 __asm__ __volatile__ ( \
310 ".set\tpush\n\t" \
311 ".set\tnoat\n\t" \
312 "1:"type##_sb("%1", "3(%2)")"\n\t" \
313 "srl\t$1, %1, 0x8\n\t" \
314 "2:"type##_sb("$1", "2(%2)")"\n\t" \
315 "srl\t$1, $1, 0x8\n\t" \
316 "3:"type##_sb("$1", "1(%2)")"\n\t" \
317 "srl\t$1, $1, 0x8\n\t" \
318 "4:"type##_sb("$1", "0(%2)")"\n\t" \
319 ".set\tpop\n\t" \
320 "li\t%0, 0\n" \
321 "10:\n\t" \
322 ".insn\n\t" \
323 ".section\t.fixup,\"ax\"\n\t" \
324 "11:\tli\t%0, %3\n\t" \
325 "j\t10b\n\t" \
326 ".previous\n\t" \
327 ".section\t__ex_table,\"a\"\n\t" \
328 STR(PTR_WD)"\t1b, 11b\n\t" \
329 STR(PTR_WD)"\t2b, 11b\n\t" \
330 STR(PTR_WD)"\t3b, 11b\n\t" \
331 STR(PTR_WD)"\t4b, 11b\n\t" \
332 ".previous" \
333 : "=&r" (res) \
334 : "r" (value), "r" (addr), "i" (-EFAULT) \
335 : "memory"); \
336 } while (0)
338 #define _StoreDW(addr, value, res) \
339 do { \
340 __asm__ __volatile__ ( \
341 ".set\tpush\n\t" \
342 ".set\tnoat\n\t" \
343 "1:sb\t%1, 7(%2)\n\t" \
344 "dsrl\t$1, %1, 0x8\n\t" \
345 "2:sb\t$1, 6(%2)\n\t" \
346 "dsrl\t$1, $1, 0x8\n\t" \
347 "3:sb\t$1, 5(%2)\n\t" \
348 "dsrl\t$1, $1, 0x8\n\t" \
349 "4:sb\t$1, 4(%2)\n\t" \
350 "dsrl\t$1, $1, 0x8\n\t" \
351 "5:sb\t$1, 3(%2)\n\t" \
352 "dsrl\t$1, $1, 0x8\n\t" \
353 "6:sb\t$1, 2(%2)\n\t" \
354 "dsrl\t$1, $1, 0x8\n\t" \
355 "7:sb\t$1, 1(%2)\n\t" \
356 "dsrl\t$1, $1, 0x8\n\t" \
357 "8:sb\t$1, 0(%2)\n\t" \
358 "dsrl\t$1, $1, 0x8\n\t" \
359 ".set\tpop\n\t" \
360 "li\t%0, 0\n" \
361 "10:\n\t" \
362 ".insn\n\t" \
363 ".section\t.fixup,\"ax\"\n\t" \
364 "11:\tli\t%0, %3\n\t" \
365 "j\t10b\n\t" \
366 ".previous\n\t" \
367 ".section\t__ex_table,\"a\"\n\t" \
368 STR(PTR_WD)"\t1b, 11b\n\t" \
369 STR(PTR_WD)"\t2b, 11b\n\t" \
370 STR(PTR_WD)"\t3b, 11b\n\t" \
371 STR(PTR_WD)"\t4b, 11b\n\t" \
372 STR(PTR_WD)"\t5b, 11b\n\t" \
373 STR(PTR_WD)"\t6b, 11b\n\t" \
374 STR(PTR_WD)"\t7b, 11b\n\t" \
375 STR(PTR_WD)"\t8b, 11b\n\t" \
376 ".previous" \
377 : "=&r" (res) \
378 : "r" (value), "r" (addr), "i" (-EFAULT) \
379 : "memory"); \
380 } while (0)
382 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
384 #else /* __BIG_ENDIAN */
386 #define _LoadHW(addr, value, res, type) \
387 do { \
388 __asm__ __volatile__ (".set\tnoat\n" \
389 "1:\t"type##_lb("%0", "1(%2)")"\n" \
390 "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\
391 "sll\t%0, 0x8\n\t" \
392 "or\t%0, $1\n\t" \
393 "li\t%1, 0\n" \
394 "3:\t.set\tat\n\t" \
395 ".insn\n\t" \
396 ".section\t.fixup,\"ax\"\n\t" \
397 "4:\tli\t%1, %3\n\t" \
398 "j\t3b\n\t" \
399 ".previous\n\t" \
400 ".section\t__ex_table,\"a\"\n\t" \
401 STR(PTR_WD)"\t1b, 4b\n\t" \
402 STR(PTR_WD)"\t2b, 4b\n\t" \
403 ".previous" \
404 : "=&r" (value), "=r" (res) \
405 : "r" (addr), "i" (-EFAULT)); \
406 } while (0)
408 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
409 #define _LoadW(addr, value, res, type) \
410 do { \
411 __asm__ __volatile__ ( \
412 "1:\t"type##_lwl("%0", "3(%2)")"\n" \
413 "2:\t"type##_lwr("%0", "(%2)")"\n\t"\
414 "li\t%1, 0\n" \
415 "3:\n\t" \
416 ".insn\n\t" \
417 ".section\t.fixup,\"ax\"\n\t" \
418 "4:\tli\t%1, %3\n\t" \
419 "j\t3b\n\t" \
420 ".previous\n\t" \
421 ".section\t__ex_table,\"a\"\n\t" \
422 STR(PTR_WD)"\t1b, 4b\n\t" \
423 STR(PTR_WD)"\t2b, 4b\n\t" \
424 ".previous" \
425 : "=&r" (value), "=r" (res) \
426 : "r" (addr), "i" (-EFAULT)); \
427 } while (0)
429 #else /* CONFIG_CPU_NO_LOAD_STORE_LR */
430 /* For CPUs without lwl instruction */
431 #define _LoadW(addr, value, res, type) \
432 do { \
433 __asm__ __volatile__ ( \
434 ".set\tpush\n" \
435 ".set\tnoat\n\t" \
436 "1:"type##_lb("%0", "3(%2)")"\n\t" \
437 "2:"type##_lbu("$1", "2(%2)")"\n\t" \
438 "sll\t%0, 0x8\n\t" \
439 "or\t%0, $1\n\t" \
440 "3:"type##_lbu("$1", "1(%2)")"\n\t" \
441 "sll\t%0, 0x8\n\t" \
442 "or\t%0, $1\n\t" \
443 "4:"type##_lbu("$1", "0(%2)")"\n\t" \
444 "sll\t%0, 0x8\n\t" \
445 "or\t%0, $1\n\t" \
446 "li\t%1, 0\n" \
447 ".set\tpop\n" \
448 "10:\n\t" \
449 ".insn\n\t" \
450 ".section\t.fixup,\"ax\"\n\t" \
451 "11:\tli\t%1, %3\n\t" \
452 "j\t10b\n\t" \
453 ".previous\n\t" \
454 ".section\t__ex_table,\"a\"\n\t" \
455 STR(PTR_WD)"\t1b, 11b\n\t" \
456 STR(PTR_WD)"\t2b, 11b\n\t" \
457 STR(PTR_WD)"\t3b, 11b\n\t" \
458 STR(PTR_WD)"\t4b, 11b\n\t" \
459 ".previous" \
460 : "=&r" (value), "=r" (res) \
461 : "r" (addr), "i" (-EFAULT)); \
462 } while (0)
464 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
467 #define _LoadHWU(addr, value, res, type) \
468 do { \
469 __asm__ __volatile__ ( \
470 ".set\tnoat\n" \
471 "1:\t"type##_lbu("%0", "1(%2)")"\n" \
472 "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\
473 "sll\t%0, 0x8\n\t" \
474 "or\t%0, $1\n\t" \
475 "li\t%1, 0\n" \
476 "3:\n\t" \
477 ".insn\n\t" \
478 ".set\tat\n\t" \
479 ".section\t.fixup,\"ax\"\n\t" \
480 "4:\tli\t%1, %3\n\t" \
481 "j\t3b\n\t" \
482 ".previous\n\t" \
483 ".section\t__ex_table,\"a\"\n\t" \
484 STR(PTR_WD)"\t1b, 4b\n\t" \
485 STR(PTR_WD)"\t2b, 4b\n\t" \
486 ".previous" \
487 : "=&r" (value), "=r" (res) \
488 : "r" (addr), "i" (-EFAULT)); \
489 } while (0)
491 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
492 #define _LoadWU(addr, value, res, type) \
493 do { \
494 __asm__ __volatile__ ( \
495 "1:\t"type##_lwl("%0", "3(%2)")"\n" \
496 "2:\t"type##_lwr("%0", "(%2)")"\n\t"\
497 "dsll\t%0, %0, 32\n\t" \
498 "dsrl\t%0, %0, 32\n\t" \
499 "li\t%1, 0\n" \
500 "3:\n\t" \
501 ".insn\n\t" \
502 "\t.section\t.fixup,\"ax\"\n\t" \
503 "4:\tli\t%1, %3\n\t" \
504 "j\t3b\n\t" \
505 ".previous\n\t" \
506 ".section\t__ex_table,\"a\"\n\t" \
507 STR(PTR_WD)"\t1b, 4b\n\t" \
508 STR(PTR_WD)"\t2b, 4b\n\t" \
509 ".previous" \
510 : "=&r" (value), "=r" (res) \
511 : "r" (addr), "i" (-EFAULT)); \
512 } while (0)
514 #define _LoadDW(addr, value, res) \
515 do { \
516 __asm__ __volatile__ ( \
517 "1:\tldl\t%0, 7(%2)\n" \
518 "2:\tldr\t%0, (%2)\n\t" \
519 "li\t%1, 0\n" \
520 "3:\n\t" \
521 ".insn\n\t" \
522 "\t.section\t.fixup,\"ax\"\n\t" \
523 "4:\tli\t%1, %3\n\t" \
524 "j\t3b\n\t" \
525 ".previous\n\t" \
526 ".section\t__ex_table,\"a\"\n\t" \
527 STR(PTR_WD)"\t1b, 4b\n\t" \
528 STR(PTR_WD)"\t2b, 4b\n\t" \
529 ".previous" \
530 : "=&r" (value), "=r" (res) \
531 : "r" (addr), "i" (-EFAULT)); \
532 } while (0)
534 #else /* CONFIG_CPU_NO_LOAD_STORE_LR */
535 /* For CPUs without lwl and ldl instructions */
536 #define _LoadWU(addr, value, res, type) \
537 do { \
538 __asm__ __volatile__ ( \
539 ".set\tpush\n\t" \
540 ".set\tnoat\n\t" \
541 "1:"type##_lbu("%0", "3(%2)")"\n\t" \
542 "2:"type##_lbu("$1", "2(%2)")"\n\t" \
543 "sll\t%0, 0x8\n\t" \
544 "or\t%0, $1\n\t" \
545 "3:"type##_lbu("$1", "1(%2)")"\n\t" \
546 "sll\t%0, 0x8\n\t" \
547 "or\t%0, $1\n\t" \
548 "4:"type##_lbu("$1", "0(%2)")"\n\t" \
549 "sll\t%0, 0x8\n\t" \
550 "or\t%0, $1\n\t" \
551 "li\t%1, 0\n" \
552 ".set\tpop\n" \
553 "10:\n\t" \
554 ".insn\n\t" \
555 ".section\t.fixup,\"ax\"\n\t" \
556 "11:\tli\t%1, %3\n\t" \
557 "j\t10b\n\t" \
558 ".previous\n\t" \
559 ".section\t__ex_table,\"a\"\n\t" \
560 STR(PTR_WD)"\t1b, 11b\n\t" \
561 STR(PTR_WD)"\t2b, 11b\n\t" \
562 STR(PTR_WD)"\t3b, 11b\n\t" \
563 STR(PTR_WD)"\t4b, 11b\n\t" \
564 ".previous" \
565 : "=&r" (value), "=r" (res) \
566 : "r" (addr), "i" (-EFAULT)); \
567 } while (0)
569 #define _LoadDW(addr, value, res) \
570 do { \
571 __asm__ __volatile__ ( \
572 ".set\tpush\n\t" \
573 ".set\tnoat\n\t" \
574 "1:lb\t%0, 7(%2)\n\t" \
575 "2:lbu\t$1, 6(%2)\n\t" \
576 "dsll\t%0, 0x8\n\t" \
577 "or\t%0, $1\n\t" \
578 "3:lbu\t$1, 5(%2)\n\t" \
579 "dsll\t%0, 0x8\n\t" \
580 "or\t%0, $1\n\t" \
581 "4:lbu\t$1, 4(%2)\n\t" \
582 "dsll\t%0, 0x8\n\t" \
583 "or\t%0, $1\n\t" \
584 "5:lbu\t$1, 3(%2)\n\t" \
585 "dsll\t%0, 0x8\n\t" \
586 "or\t%0, $1\n\t" \
587 "6:lbu\t$1, 2(%2)\n\t" \
588 "dsll\t%0, 0x8\n\t" \
589 "or\t%0, $1\n\t" \
590 "7:lbu\t$1, 1(%2)\n\t" \
591 "dsll\t%0, 0x8\n\t" \
592 "or\t%0, $1\n\t" \
593 "8:lbu\t$1, 0(%2)\n\t" \
594 "dsll\t%0, 0x8\n\t" \
595 "or\t%0, $1\n\t" \
596 "li\t%1, 0\n" \
597 ".set\tpop\n\t" \
598 "10:\n\t" \
599 ".insn\n\t" \
600 ".section\t.fixup,\"ax\"\n\t" \
601 "11:\tli\t%1, %3\n\t" \
602 "j\t10b\n\t" \
603 ".previous\n\t" \
604 ".section\t__ex_table,\"a\"\n\t" \
605 STR(PTR_WD)"\t1b, 11b\n\t" \
606 STR(PTR_WD)"\t2b, 11b\n\t" \
607 STR(PTR_WD)"\t3b, 11b\n\t" \
608 STR(PTR_WD)"\t4b, 11b\n\t" \
609 STR(PTR_WD)"\t5b, 11b\n\t" \
610 STR(PTR_WD)"\t6b, 11b\n\t" \
611 STR(PTR_WD)"\t7b, 11b\n\t" \
612 STR(PTR_WD)"\t8b, 11b\n\t" \
613 ".previous" \
614 : "=&r" (value), "=r" (res) \
615 : "r" (addr), "i" (-EFAULT)); \
616 } while (0)
617 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
619 #define _StoreHW(addr, value, res, type) \
620 do { \
621 __asm__ __volatile__ ( \
622 ".set\tnoat\n" \
623 "1:\t"type##_sb("%1", "0(%2)")"\n" \
624 "srl\t$1,%1, 0x8\n" \
625 "2:\t"type##_sb("$1", "1(%2)")"\n" \
626 ".set\tat\n\t" \
627 "li\t%0, 0\n" \
628 "3:\n\t" \
629 ".insn\n\t" \
630 ".section\t.fixup,\"ax\"\n\t" \
631 "4:\tli\t%0, %3\n\t" \
632 "j\t3b\n\t" \
633 ".previous\n\t" \
634 ".section\t__ex_table,\"a\"\n\t" \
635 STR(PTR_WD)"\t1b, 4b\n\t" \
636 STR(PTR_WD)"\t2b, 4b\n\t" \
637 ".previous" \
638 : "=r" (res) \
639 : "r" (value), "r" (addr), "i" (-EFAULT));\
640 } while (0)
642 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
643 #define _StoreW(addr, value, res, type) \
644 do { \
645 __asm__ __volatile__ ( \
646 "1:\t"type##_swl("%1", "3(%2)")"\n" \
647 "2:\t"type##_swr("%1", "(%2)")"\n\t"\
648 "li\t%0, 0\n" \
649 "3:\n\t" \
650 ".insn\n\t" \
651 ".section\t.fixup,\"ax\"\n\t" \
652 "4:\tli\t%0, %3\n\t" \
653 "j\t3b\n\t" \
654 ".previous\n\t" \
655 ".section\t__ex_table,\"a\"\n\t" \
656 STR(PTR_WD)"\t1b, 4b\n\t" \
657 STR(PTR_WD)"\t2b, 4b\n\t" \
658 ".previous" \
659 : "=r" (res) \
660 : "r" (value), "r" (addr), "i" (-EFAULT)); \
661 } while (0)
663 #define _StoreDW(addr, value, res) \
664 do { \
665 __asm__ __volatile__ ( \
666 "1:\tsdl\t%1, 7(%2)\n" \
667 "2:\tsdr\t%1, (%2)\n\t" \
668 "li\t%0, 0\n" \
669 "3:\n\t" \
670 ".insn\n\t" \
671 ".section\t.fixup,\"ax\"\n\t" \
672 "4:\tli\t%0, %3\n\t" \
673 "j\t3b\n\t" \
674 ".previous\n\t" \
675 ".section\t__ex_table,\"a\"\n\t" \
676 STR(PTR_WD)"\t1b, 4b\n\t" \
677 STR(PTR_WD)"\t2b, 4b\n\t" \
678 ".previous" \
679 : "=r" (res) \
680 : "r" (value), "r" (addr), "i" (-EFAULT)); \
681 } while (0)
683 #else /* CONFIG_CPU_NO_LOAD_STORE_LR */
684 /* For CPUs without swl and sdl instructions */
685 #define _StoreW(addr, value, res, type) \
686 do { \
687 __asm__ __volatile__ ( \
688 ".set\tpush\n\t" \
689 ".set\tnoat\n\t" \
690 "1:"type##_sb("%1", "0(%2)")"\n\t" \
691 "srl\t$1, %1, 0x8\n\t" \
692 "2:"type##_sb("$1", "1(%2)")"\n\t" \
693 "srl\t$1, $1, 0x8\n\t" \
694 "3:"type##_sb("$1", "2(%2)")"\n\t" \
695 "srl\t$1, $1, 0x8\n\t" \
696 "4:"type##_sb("$1", "3(%2)")"\n\t" \
697 ".set\tpop\n\t" \
698 "li\t%0, 0\n" \
699 "10:\n\t" \
700 ".insn\n\t" \
701 ".section\t.fixup,\"ax\"\n\t" \
702 "11:\tli\t%0, %3\n\t" \
703 "j\t10b\n\t" \
704 ".previous\n\t" \
705 ".section\t__ex_table,\"a\"\n\t" \
706 STR(PTR_WD)"\t1b, 11b\n\t" \
707 STR(PTR_WD)"\t2b, 11b\n\t" \
708 STR(PTR_WD)"\t3b, 11b\n\t" \
709 STR(PTR_WD)"\t4b, 11b\n\t" \
710 ".previous" \
711 : "=&r" (res) \
712 : "r" (value), "r" (addr), "i" (-EFAULT) \
713 : "memory"); \
714 } while (0)
716 #define _StoreDW(addr, value, res) \
717 do { \
718 __asm__ __volatile__ ( \
719 ".set\tpush\n\t" \
720 ".set\tnoat\n\t" \
721 "1:sb\t%1, 0(%2)\n\t" \
722 "dsrl\t$1, %1, 0x8\n\t" \
723 "2:sb\t$1, 1(%2)\n\t" \
724 "dsrl\t$1, $1, 0x8\n\t" \
725 "3:sb\t$1, 2(%2)\n\t" \
726 "dsrl\t$1, $1, 0x8\n\t" \
727 "4:sb\t$1, 3(%2)\n\t" \
728 "dsrl\t$1, $1, 0x8\n\t" \
729 "5:sb\t$1, 4(%2)\n\t" \
730 "dsrl\t$1, $1, 0x8\n\t" \
731 "6:sb\t$1, 5(%2)\n\t" \
732 "dsrl\t$1, $1, 0x8\n\t" \
733 "7:sb\t$1, 6(%2)\n\t" \
734 "dsrl\t$1, $1, 0x8\n\t" \
735 "8:sb\t$1, 7(%2)\n\t" \
736 "dsrl\t$1, $1, 0x8\n\t" \
737 ".set\tpop\n\t" \
738 "li\t%0, 0\n" \
739 "10:\n\t" \
740 ".insn\n\t" \
741 ".section\t.fixup,\"ax\"\n\t" \
742 "11:\tli\t%0, %3\n\t" \
743 "j\t10b\n\t" \
744 ".previous\n\t" \
745 ".section\t__ex_table,\"a\"\n\t" \
746 STR(PTR_WD)"\t1b, 11b\n\t" \
747 STR(PTR_WD)"\t2b, 11b\n\t" \
748 STR(PTR_WD)"\t3b, 11b\n\t" \
749 STR(PTR_WD)"\t4b, 11b\n\t" \
750 STR(PTR_WD)"\t5b, 11b\n\t" \
751 STR(PTR_WD)"\t6b, 11b\n\t" \
752 STR(PTR_WD)"\t7b, 11b\n\t" \
753 STR(PTR_WD)"\t8b, 11b\n\t" \
754 ".previous" \
755 : "=&r" (res) \
756 : "r" (value), "r" (addr), "i" (-EFAULT) \
757 : "memory"); \
758 } while (0)
760 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
761 #endif
763 #define LoadHWU(addr, value, res) _LoadHWU(addr, value, res, kernel)
764 #define LoadHWUE(addr, value, res) _LoadHWU(addr, value, res, user)
765 #define LoadWU(addr, value, res) _LoadWU(addr, value, res, kernel)
766 #define LoadWUE(addr, value, res) _LoadWU(addr, value, res, user)
767 #define LoadHW(addr, value, res) _LoadHW(addr, value, res, kernel)
768 #define LoadHWE(addr, value, res) _LoadHW(addr, value, res, user)
769 #define LoadW(addr, value, res) _LoadW(addr, value, res, kernel)
770 #define LoadWE(addr, value, res) _LoadW(addr, value, res, user)
771 #define LoadDW(addr, value, res) _LoadDW(addr, value, res)
773 #define StoreHW(addr, value, res) _StoreHW(addr, value, res, kernel)
774 #define StoreHWE(addr, value, res) _StoreHW(addr, value, res, user)
775 #define StoreW(addr, value, res) _StoreW(addr, value, res, kernel)
776 #define StoreWE(addr, value, res) _StoreW(addr, value, res, user)
777 #define StoreDW(addr, value, res) _StoreDW(addr, value, res)
779 #endif /* _ASM_MIPS_UNALIGNED_EMUL_H */