~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/include/asm/unaligned-emul.h

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0-or-later */
  2 #ifndef _ASM_MIPS_UNALIGNED_EMUL_H
  3 #define _ASM_MIPS_UNALIGNED_EMUL_H
  4 
  5 #include <asm/asm.h>
  6 
  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)
 29 
 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)
 50 
 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)
 85 
 86 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
 87 
 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)
111 
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)
134 
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)
154 
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)
189 
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)
238 
239 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
240 
241 
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)
264 
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)
285 
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)
305 
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)
337 
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)
381 
382 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
383 
384 #else /* __BIG_ENDIAN */
385 
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)
407 
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)
428 
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)
463 
464 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
465 
466 
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)
490 
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)
513 
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)
533 
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)
568 
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 */
618 
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)
641 
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)
662 
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)
682 
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)
715 
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)
759 
760 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
761 #endif
762 
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)
772 
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)
778 
779 #endif /* _ASM_MIPS_UNALIGNED_EMUL_H */
780 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php