0001
0002 #ifndef _ASM_MIPS_UNALIGNED_EMUL_H
0003 #define _ASM_MIPS_UNALIGNED_EMUL_H
0004
0005 #include <asm/asm.h>
0006
0007 #ifdef __BIG_ENDIAN
0008 #define _LoadHW(addr, value, res, type) \
0009 do { \
0010 __asm__ __volatile__ (".set\tnoat\n" \
0011 "1:\t"type##_lb("%0", "0(%2)")"\n" \
0012 "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\
0013 "sll\t%0, 0x8\n\t" \
0014 "or\t%0, $1\n\t" \
0015 "li\t%1, 0\n" \
0016 "3:\t.set\tat\n\t" \
0017 ".insn\n\t" \
0018 ".section\t.fixup,\"ax\"\n\t" \
0019 "4:\tli\t%1, %3\n\t" \
0020 "j\t3b\n\t" \
0021 ".previous\n\t" \
0022 ".section\t__ex_table,\"a\"\n\t" \
0023 STR(PTR_WD)"\t1b, 4b\n\t" \
0024 STR(PTR_WD)"\t2b, 4b\n\t" \
0025 ".previous" \
0026 : "=&r" (value), "=r" (res) \
0027 : "r" (addr), "i" (-EFAULT)); \
0028 } while (0)
0029
0030 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
0031 #define _LoadW(addr, value, res, type) \
0032 do { \
0033 __asm__ __volatile__ ( \
0034 "1:\t"type##_lwl("%0", "(%2)")"\n" \
0035 "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
0036 "li\t%1, 0\n" \
0037 "3:\n\t" \
0038 ".insn\n\t" \
0039 ".section\t.fixup,\"ax\"\n\t" \
0040 "4:\tli\t%1, %3\n\t" \
0041 "j\t3b\n\t" \
0042 ".previous\n\t" \
0043 ".section\t__ex_table,\"a\"\n\t" \
0044 STR(PTR_WD)"\t1b, 4b\n\t" \
0045 STR(PTR_WD)"\t2b, 4b\n\t" \
0046 ".previous" \
0047 : "=&r" (value), "=r" (res) \
0048 : "r" (addr), "i" (-EFAULT)); \
0049 } while (0)
0050
0051 #else
0052
0053 #define _LoadW(addr, value, res, type) \
0054 do { \
0055 __asm__ __volatile__ ( \
0056 ".set\tpush\n" \
0057 ".set\tnoat\n\t" \
0058 "1:"type##_lb("%0", "0(%2)")"\n\t" \
0059 "2:"type##_lbu("$1", "1(%2)")"\n\t" \
0060 "sll\t%0, 0x8\n\t" \
0061 "or\t%0, $1\n\t" \
0062 "3:"type##_lbu("$1", "2(%2)")"\n\t" \
0063 "sll\t%0, 0x8\n\t" \
0064 "or\t%0, $1\n\t" \
0065 "4:"type##_lbu("$1", "3(%2)")"\n\t" \
0066 "sll\t%0, 0x8\n\t" \
0067 "or\t%0, $1\n\t" \
0068 "li\t%1, 0\n" \
0069 ".set\tpop\n" \
0070 "10:\n\t" \
0071 ".insn\n\t" \
0072 ".section\t.fixup,\"ax\"\n\t" \
0073 "11:\tli\t%1, %3\n\t" \
0074 "j\t10b\n\t" \
0075 ".previous\n\t" \
0076 ".section\t__ex_table,\"a\"\n\t" \
0077 STR(PTR_WD)"\t1b, 11b\n\t" \
0078 STR(PTR_WD)"\t2b, 11b\n\t" \
0079 STR(PTR_WD)"\t3b, 11b\n\t" \
0080 STR(PTR_WD)"\t4b, 11b\n\t" \
0081 ".previous" \
0082 : "=&r" (value), "=r" (res) \
0083 : "r" (addr), "i" (-EFAULT)); \
0084 } while (0)
0085
0086 #endif
0087
0088 #define _LoadHWU(addr, value, res, type) \
0089 do { \
0090 __asm__ __volatile__ ( \
0091 ".set\tnoat\n" \
0092 "1:\t"type##_lbu("%0", "0(%2)")"\n" \
0093 "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\
0094 "sll\t%0, 0x8\n\t" \
0095 "or\t%0, $1\n\t" \
0096 "li\t%1, 0\n" \
0097 "3:\n\t" \
0098 ".insn\n\t" \
0099 ".set\tat\n\t" \
0100 ".section\t.fixup,\"ax\"\n\t" \
0101 "4:\tli\t%1, %3\n\t" \
0102 "j\t3b\n\t" \
0103 ".previous\n\t" \
0104 ".section\t__ex_table,\"a\"\n\t" \
0105 STR(PTR_WD)"\t1b, 4b\n\t" \
0106 STR(PTR_WD)"\t2b, 4b\n\t" \
0107 ".previous" \
0108 : "=&r" (value), "=r" (res) \
0109 : "r" (addr), "i" (-EFAULT)); \
0110 } while (0)
0111
0112 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
0113 #define _LoadWU(addr, value, res, type) \
0114 do { \
0115 __asm__ __volatile__ ( \
0116 "1:\t"type##_lwl("%0", "(%2)")"\n" \
0117 "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
0118 "dsll\t%0, %0, 32\n\t" \
0119 "dsrl\t%0, %0, 32\n\t" \
0120 "li\t%1, 0\n" \
0121 "3:\n\t" \
0122 ".insn\n\t" \
0123 "\t.section\t.fixup,\"ax\"\n\t" \
0124 "4:\tli\t%1, %3\n\t" \
0125 "j\t3b\n\t" \
0126 ".previous\n\t" \
0127 ".section\t__ex_table,\"a\"\n\t" \
0128 STR(PTR_WD)"\t1b, 4b\n\t" \
0129 STR(PTR_WD)"\t2b, 4b\n\t" \
0130 ".previous" \
0131 : "=&r" (value), "=r" (res) \
0132 : "r" (addr), "i" (-EFAULT)); \
0133 } while (0)
0134
0135 #define _LoadDW(addr, value, res) \
0136 do { \
0137 __asm__ __volatile__ ( \
0138 "1:\tldl\t%0, (%2)\n" \
0139 "2:\tldr\t%0, 7(%2)\n\t" \
0140 "li\t%1, 0\n" \
0141 "3:\n\t" \
0142 ".insn\n\t" \
0143 "\t.section\t.fixup,\"ax\"\n\t" \
0144 "4:\tli\t%1, %3\n\t" \
0145 "j\t3b\n\t" \
0146 ".previous\n\t" \
0147 ".section\t__ex_table,\"a\"\n\t" \
0148 STR(PTR_WD)"\t1b, 4b\n\t" \
0149 STR(PTR_WD)"\t2b, 4b\n\t" \
0150 ".previous" \
0151 : "=&r" (value), "=r" (res) \
0152 : "r" (addr), "i" (-EFAULT)); \
0153 } while (0)
0154
0155 #else
0156
0157 #define _LoadWU(addr, value, res, type) \
0158 do { \
0159 __asm__ __volatile__ ( \
0160 ".set\tpush\n\t" \
0161 ".set\tnoat\n\t" \
0162 "1:"type##_lbu("%0", "0(%2)")"\n\t" \
0163 "2:"type##_lbu("$1", "1(%2)")"\n\t" \
0164 "sll\t%0, 0x8\n\t" \
0165 "or\t%0, $1\n\t" \
0166 "3:"type##_lbu("$1", "2(%2)")"\n\t" \
0167 "sll\t%0, 0x8\n\t" \
0168 "or\t%0, $1\n\t" \
0169 "4:"type##_lbu("$1", "3(%2)")"\n\t" \
0170 "sll\t%0, 0x8\n\t" \
0171 "or\t%0, $1\n\t" \
0172 "li\t%1, 0\n" \
0173 ".set\tpop\n" \
0174 "10:\n\t" \
0175 ".insn\n\t" \
0176 ".section\t.fixup,\"ax\"\n\t" \
0177 "11:\tli\t%1, %3\n\t" \
0178 "j\t10b\n\t" \
0179 ".previous\n\t" \
0180 ".section\t__ex_table,\"a\"\n\t" \
0181 STR(PTR_WD)"\t1b, 11b\n\t" \
0182 STR(PTR_WD)"\t2b, 11b\n\t" \
0183 STR(PTR_WD)"\t3b, 11b\n\t" \
0184 STR(PTR_WD)"\t4b, 11b\n\t" \
0185 ".previous" \
0186 : "=&r" (value), "=r" (res) \
0187 : "r" (addr), "i" (-EFAULT)); \
0188 } while (0)
0189
0190 #define _LoadDW(addr, value, res) \
0191 do { \
0192 __asm__ __volatile__ ( \
0193 ".set\tpush\n\t" \
0194 ".set\tnoat\n\t" \
0195 "1:lb\t%0, 0(%2)\n\t" \
0196 "2:lbu\t $1, 1(%2)\n\t" \
0197 "dsll\t%0, 0x8\n\t" \
0198 "or\t%0, $1\n\t" \
0199 "3:lbu\t$1, 2(%2)\n\t" \
0200 "dsll\t%0, 0x8\n\t" \
0201 "or\t%0, $1\n\t" \
0202 "4:lbu\t$1, 3(%2)\n\t" \
0203 "dsll\t%0, 0x8\n\t" \
0204 "or\t%0, $1\n\t" \
0205 "5:lbu\t$1, 4(%2)\n\t" \
0206 "dsll\t%0, 0x8\n\t" \
0207 "or\t%0, $1\n\t" \
0208 "6:lbu\t$1, 5(%2)\n\t" \
0209 "dsll\t%0, 0x8\n\t" \
0210 "or\t%0, $1\n\t" \
0211 "7:lbu\t$1, 6(%2)\n\t" \
0212 "dsll\t%0, 0x8\n\t" \
0213 "or\t%0, $1\n\t" \
0214 "8:lbu\t$1, 7(%2)\n\t" \
0215 "dsll\t%0, 0x8\n\t" \
0216 "or\t%0, $1\n\t" \
0217 "li\t%1, 0\n" \
0218 ".set\tpop\n\t" \
0219 "10:\n\t" \
0220 ".insn\n\t" \
0221 ".section\t.fixup,\"ax\"\n\t" \
0222 "11:\tli\t%1, %3\n\t" \
0223 "j\t10b\n\t" \
0224 ".previous\n\t" \
0225 ".section\t__ex_table,\"a\"\n\t" \
0226 STR(PTR_WD)"\t1b, 11b\n\t" \
0227 STR(PTR_WD)"\t2b, 11b\n\t" \
0228 STR(PTR_WD)"\t3b, 11b\n\t" \
0229 STR(PTR_WD)"\t4b, 11b\n\t" \
0230 STR(PTR_WD)"\t5b, 11b\n\t" \
0231 STR(PTR_WD)"\t6b, 11b\n\t" \
0232 STR(PTR_WD)"\t7b, 11b\n\t" \
0233 STR(PTR_WD)"\t8b, 11b\n\t" \
0234 ".previous" \
0235 : "=&r" (value), "=r" (res) \
0236 : "r" (addr), "i" (-EFAULT)); \
0237 } while (0)
0238
0239 #endif
0240
0241
0242 #define _StoreHW(addr, value, res, type) \
0243 do { \
0244 __asm__ __volatile__ ( \
0245 ".set\tnoat\n" \
0246 "1:\t"type##_sb("%1", "1(%2)")"\n" \
0247 "srl\t$1, %1, 0x8\n" \
0248 "2:\t"type##_sb("$1", "0(%2)")"\n" \
0249 ".set\tat\n\t" \
0250 "li\t%0, 0\n" \
0251 "3:\n\t" \
0252 ".insn\n\t" \
0253 ".section\t.fixup,\"ax\"\n\t" \
0254 "4:\tli\t%0, %3\n\t" \
0255 "j\t3b\n\t" \
0256 ".previous\n\t" \
0257 ".section\t__ex_table,\"a\"\n\t" \
0258 STR(PTR_WD)"\t1b, 4b\n\t" \
0259 STR(PTR_WD)"\t2b, 4b\n\t" \
0260 ".previous" \
0261 : "=r" (res) \
0262 : "r" (value), "r" (addr), "i" (-EFAULT));\
0263 } while (0)
0264
0265 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
0266 #define _StoreW(addr, value, res, type) \
0267 do { \
0268 __asm__ __volatile__ ( \
0269 "1:\t"type##_swl("%1", "(%2)")"\n" \
0270 "2:\t"type##_swr("%1", "3(%2)")"\n\t"\
0271 "li\t%0, 0\n" \
0272 "3:\n\t" \
0273 ".insn\n\t" \
0274 ".section\t.fixup,\"ax\"\n\t" \
0275 "4:\tli\t%0, %3\n\t" \
0276 "j\t3b\n\t" \
0277 ".previous\n\t" \
0278 ".section\t__ex_table,\"a\"\n\t" \
0279 STR(PTR_WD)"\t1b, 4b\n\t" \
0280 STR(PTR_WD)"\t2b, 4b\n\t" \
0281 ".previous" \
0282 : "=r" (res) \
0283 : "r" (value), "r" (addr), "i" (-EFAULT)); \
0284 } while (0)
0285
0286 #define _StoreDW(addr, value, res) \
0287 do { \
0288 __asm__ __volatile__ ( \
0289 "1:\tsdl\t%1,(%2)\n" \
0290 "2:\tsdr\t%1, 7(%2)\n\t" \
0291 "li\t%0, 0\n" \
0292 "3:\n\t" \
0293 ".insn\n\t" \
0294 ".section\t.fixup,\"ax\"\n\t" \
0295 "4:\tli\t%0, %3\n\t" \
0296 "j\t3b\n\t" \
0297 ".previous\n\t" \
0298 ".section\t__ex_table,\"a\"\n\t" \
0299 STR(PTR_WD)"\t1b, 4b\n\t" \
0300 STR(PTR_WD)"\t2b, 4b\n\t" \
0301 ".previous" \
0302 : "=r" (res) \
0303 : "r" (value), "r" (addr), "i" (-EFAULT)); \
0304 } while (0)
0305
0306 #else
0307 #define _StoreW(addr, value, res, type) \
0308 do { \
0309 __asm__ __volatile__ ( \
0310 ".set\tpush\n\t" \
0311 ".set\tnoat\n\t" \
0312 "1:"type##_sb("%1", "3(%2)")"\n\t" \
0313 "srl\t$1, %1, 0x8\n\t" \
0314 "2:"type##_sb("$1", "2(%2)")"\n\t" \
0315 "srl\t$1, $1, 0x8\n\t" \
0316 "3:"type##_sb("$1", "1(%2)")"\n\t" \
0317 "srl\t$1, $1, 0x8\n\t" \
0318 "4:"type##_sb("$1", "0(%2)")"\n\t" \
0319 ".set\tpop\n\t" \
0320 "li\t%0, 0\n" \
0321 "10:\n\t" \
0322 ".insn\n\t" \
0323 ".section\t.fixup,\"ax\"\n\t" \
0324 "11:\tli\t%0, %3\n\t" \
0325 "j\t10b\n\t" \
0326 ".previous\n\t" \
0327 ".section\t__ex_table,\"a\"\n\t" \
0328 STR(PTR_WD)"\t1b, 11b\n\t" \
0329 STR(PTR_WD)"\t2b, 11b\n\t" \
0330 STR(PTR_WD)"\t3b, 11b\n\t" \
0331 STR(PTR_WD)"\t4b, 11b\n\t" \
0332 ".previous" \
0333 : "=&r" (res) \
0334 : "r" (value), "r" (addr), "i" (-EFAULT) \
0335 : "memory"); \
0336 } while (0)
0337
0338 #define _StoreDW(addr, value, res) \
0339 do { \
0340 __asm__ __volatile__ ( \
0341 ".set\tpush\n\t" \
0342 ".set\tnoat\n\t" \
0343 "1:sb\t%1, 7(%2)\n\t" \
0344 "dsrl\t$1, %1, 0x8\n\t" \
0345 "2:sb\t$1, 6(%2)\n\t" \
0346 "dsrl\t$1, $1, 0x8\n\t" \
0347 "3:sb\t$1, 5(%2)\n\t" \
0348 "dsrl\t$1, $1, 0x8\n\t" \
0349 "4:sb\t$1, 4(%2)\n\t" \
0350 "dsrl\t$1, $1, 0x8\n\t" \
0351 "5:sb\t$1, 3(%2)\n\t" \
0352 "dsrl\t$1, $1, 0x8\n\t" \
0353 "6:sb\t$1, 2(%2)\n\t" \
0354 "dsrl\t$1, $1, 0x8\n\t" \
0355 "7:sb\t$1, 1(%2)\n\t" \
0356 "dsrl\t$1, $1, 0x8\n\t" \
0357 "8:sb\t$1, 0(%2)\n\t" \
0358 "dsrl\t$1, $1, 0x8\n\t" \
0359 ".set\tpop\n\t" \
0360 "li\t%0, 0\n" \
0361 "10:\n\t" \
0362 ".insn\n\t" \
0363 ".section\t.fixup,\"ax\"\n\t" \
0364 "11:\tli\t%0, %3\n\t" \
0365 "j\t10b\n\t" \
0366 ".previous\n\t" \
0367 ".section\t__ex_table,\"a\"\n\t" \
0368 STR(PTR_WD)"\t1b, 11b\n\t" \
0369 STR(PTR_WD)"\t2b, 11b\n\t" \
0370 STR(PTR_WD)"\t3b, 11b\n\t" \
0371 STR(PTR_WD)"\t4b, 11b\n\t" \
0372 STR(PTR_WD)"\t5b, 11b\n\t" \
0373 STR(PTR_WD)"\t6b, 11b\n\t" \
0374 STR(PTR_WD)"\t7b, 11b\n\t" \
0375 STR(PTR_WD)"\t8b, 11b\n\t" \
0376 ".previous" \
0377 : "=&r" (res) \
0378 : "r" (value), "r" (addr), "i" (-EFAULT) \
0379 : "memory"); \
0380 } while (0)
0381
0382 #endif
0383
0384 #else
0385
0386 #define _LoadHW(addr, value, res, type) \
0387 do { \
0388 __asm__ __volatile__ (".set\tnoat\n" \
0389 "1:\t"type##_lb("%0", "1(%2)")"\n" \
0390 "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\
0391 "sll\t%0, 0x8\n\t" \
0392 "or\t%0, $1\n\t" \
0393 "li\t%1, 0\n" \
0394 "3:\t.set\tat\n\t" \
0395 ".insn\n\t" \
0396 ".section\t.fixup,\"ax\"\n\t" \
0397 "4:\tli\t%1, %3\n\t" \
0398 "j\t3b\n\t" \
0399 ".previous\n\t" \
0400 ".section\t__ex_table,\"a\"\n\t" \
0401 STR(PTR_WD)"\t1b, 4b\n\t" \
0402 STR(PTR_WD)"\t2b, 4b\n\t" \
0403 ".previous" \
0404 : "=&r" (value), "=r" (res) \
0405 : "r" (addr), "i" (-EFAULT)); \
0406 } while (0)
0407
0408 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
0409 #define _LoadW(addr, value, res, type) \
0410 do { \
0411 __asm__ __volatile__ ( \
0412 "1:\t"type##_lwl("%0", "3(%2)")"\n" \
0413 "2:\t"type##_lwr("%0", "(%2)")"\n\t"\
0414 "li\t%1, 0\n" \
0415 "3:\n\t" \
0416 ".insn\n\t" \
0417 ".section\t.fixup,\"ax\"\n\t" \
0418 "4:\tli\t%1, %3\n\t" \
0419 "j\t3b\n\t" \
0420 ".previous\n\t" \
0421 ".section\t__ex_table,\"a\"\n\t" \
0422 STR(PTR_WD)"\t1b, 4b\n\t" \
0423 STR(PTR_WD)"\t2b, 4b\n\t" \
0424 ".previous" \
0425 : "=&r" (value), "=r" (res) \
0426 : "r" (addr), "i" (-EFAULT)); \
0427 } while (0)
0428
0429 #else
0430
0431 #define _LoadW(addr, value, res, type) \
0432 do { \
0433 __asm__ __volatile__ ( \
0434 ".set\tpush\n" \
0435 ".set\tnoat\n\t" \
0436 "1:"type##_lb("%0", "3(%2)")"\n\t" \
0437 "2:"type##_lbu("$1", "2(%2)")"\n\t" \
0438 "sll\t%0, 0x8\n\t" \
0439 "or\t%0, $1\n\t" \
0440 "3:"type##_lbu("$1", "1(%2)")"\n\t" \
0441 "sll\t%0, 0x8\n\t" \
0442 "or\t%0, $1\n\t" \
0443 "4:"type##_lbu("$1", "0(%2)")"\n\t" \
0444 "sll\t%0, 0x8\n\t" \
0445 "or\t%0, $1\n\t" \
0446 "li\t%1, 0\n" \
0447 ".set\tpop\n" \
0448 "10:\n\t" \
0449 ".insn\n\t" \
0450 ".section\t.fixup,\"ax\"\n\t" \
0451 "11:\tli\t%1, %3\n\t" \
0452 "j\t10b\n\t" \
0453 ".previous\n\t" \
0454 ".section\t__ex_table,\"a\"\n\t" \
0455 STR(PTR_WD)"\t1b, 11b\n\t" \
0456 STR(PTR_WD)"\t2b, 11b\n\t" \
0457 STR(PTR_WD)"\t3b, 11b\n\t" \
0458 STR(PTR_WD)"\t4b, 11b\n\t" \
0459 ".previous" \
0460 : "=&r" (value), "=r" (res) \
0461 : "r" (addr), "i" (-EFAULT)); \
0462 } while (0)
0463
0464 #endif
0465
0466
0467 #define _LoadHWU(addr, value, res, type) \
0468 do { \
0469 __asm__ __volatile__ ( \
0470 ".set\tnoat\n" \
0471 "1:\t"type##_lbu("%0", "1(%2)")"\n" \
0472 "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\
0473 "sll\t%0, 0x8\n\t" \
0474 "or\t%0, $1\n\t" \
0475 "li\t%1, 0\n" \
0476 "3:\n\t" \
0477 ".insn\n\t" \
0478 ".set\tat\n\t" \
0479 ".section\t.fixup,\"ax\"\n\t" \
0480 "4:\tli\t%1, %3\n\t" \
0481 "j\t3b\n\t" \
0482 ".previous\n\t" \
0483 ".section\t__ex_table,\"a\"\n\t" \
0484 STR(PTR_WD)"\t1b, 4b\n\t" \
0485 STR(PTR_WD)"\t2b, 4b\n\t" \
0486 ".previous" \
0487 : "=&r" (value), "=r" (res) \
0488 : "r" (addr), "i" (-EFAULT)); \
0489 } while (0)
0490
0491 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
0492 #define _LoadWU(addr, value, res, type) \
0493 do { \
0494 __asm__ __volatile__ ( \
0495 "1:\t"type##_lwl("%0", "3(%2)")"\n" \
0496 "2:\t"type##_lwr("%0", "(%2)")"\n\t"\
0497 "dsll\t%0, %0, 32\n\t" \
0498 "dsrl\t%0, %0, 32\n\t" \
0499 "li\t%1, 0\n" \
0500 "3:\n\t" \
0501 ".insn\n\t" \
0502 "\t.section\t.fixup,\"ax\"\n\t" \
0503 "4:\tli\t%1, %3\n\t" \
0504 "j\t3b\n\t" \
0505 ".previous\n\t" \
0506 ".section\t__ex_table,\"a\"\n\t" \
0507 STR(PTR_WD)"\t1b, 4b\n\t" \
0508 STR(PTR_WD)"\t2b, 4b\n\t" \
0509 ".previous" \
0510 : "=&r" (value), "=r" (res) \
0511 : "r" (addr), "i" (-EFAULT)); \
0512 } while (0)
0513
0514 #define _LoadDW(addr, value, res) \
0515 do { \
0516 __asm__ __volatile__ ( \
0517 "1:\tldl\t%0, 7(%2)\n" \
0518 "2:\tldr\t%0, (%2)\n\t" \
0519 "li\t%1, 0\n" \
0520 "3:\n\t" \
0521 ".insn\n\t" \
0522 "\t.section\t.fixup,\"ax\"\n\t" \
0523 "4:\tli\t%1, %3\n\t" \
0524 "j\t3b\n\t" \
0525 ".previous\n\t" \
0526 ".section\t__ex_table,\"a\"\n\t" \
0527 STR(PTR_WD)"\t1b, 4b\n\t" \
0528 STR(PTR_WD)"\t2b, 4b\n\t" \
0529 ".previous" \
0530 : "=&r" (value), "=r" (res) \
0531 : "r" (addr), "i" (-EFAULT)); \
0532 } while (0)
0533
0534 #else
0535
0536 #define _LoadWU(addr, value, res, type) \
0537 do { \
0538 __asm__ __volatile__ ( \
0539 ".set\tpush\n\t" \
0540 ".set\tnoat\n\t" \
0541 "1:"type##_lbu("%0", "3(%2)")"\n\t" \
0542 "2:"type##_lbu("$1", "2(%2)")"\n\t" \
0543 "sll\t%0, 0x8\n\t" \
0544 "or\t%0, $1\n\t" \
0545 "3:"type##_lbu("$1", "1(%2)")"\n\t" \
0546 "sll\t%0, 0x8\n\t" \
0547 "or\t%0, $1\n\t" \
0548 "4:"type##_lbu("$1", "0(%2)")"\n\t" \
0549 "sll\t%0, 0x8\n\t" \
0550 "or\t%0, $1\n\t" \
0551 "li\t%1, 0\n" \
0552 ".set\tpop\n" \
0553 "10:\n\t" \
0554 ".insn\n\t" \
0555 ".section\t.fixup,\"ax\"\n\t" \
0556 "11:\tli\t%1, %3\n\t" \
0557 "j\t10b\n\t" \
0558 ".previous\n\t" \
0559 ".section\t__ex_table,\"a\"\n\t" \
0560 STR(PTR_WD)"\t1b, 11b\n\t" \
0561 STR(PTR_WD)"\t2b, 11b\n\t" \
0562 STR(PTR_WD)"\t3b, 11b\n\t" \
0563 STR(PTR_WD)"\t4b, 11b\n\t" \
0564 ".previous" \
0565 : "=&r" (value), "=r" (res) \
0566 : "r" (addr), "i" (-EFAULT)); \
0567 } while (0)
0568
0569 #define _LoadDW(addr, value, res) \
0570 do { \
0571 __asm__ __volatile__ ( \
0572 ".set\tpush\n\t" \
0573 ".set\tnoat\n\t" \
0574 "1:lb\t%0, 7(%2)\n\t" \
0575 "2:lbu\t$1, 6(%2)\n\t" \
0576 "dsll\t%0, 0x8\n\t" \
0577 "or\t%0, $1\n\t" \
0578 "3:lbu\t$1, 5(%2)\n\t" \
0579 "dsll\t%0, 0x8\n\t" \
0580 "or\t%0, $1\n\t" \
0581 "4:lbu\t$1, 4(%2)\n\t" \
0582 "dsll\t%0, 0x8\n\t" \
0583 "or\t%0, $1\n\t" \
0584 "5:lbu\t$1, 3(%2)\n\t" \
0585 "dsll\t%0, 0x8\n\t" \
0586 "or\t%0, $1\n\t" \
0587 "6:lbu\t$1, 2(%2)\n\t" \
0588 "dsll\t%0, 0x8\n\t" \
0589 "or\t%0, $1\n\t" \
0590 "7:lbu\t$1, 1(%2)\n\t" \
0591 "dsll\t%0, 0x8\n\t" \
0592 "or\t%0, $1\n\t" \
0593 "8:lbu\t$1, 0(%2)\n\t" \
0594 "dsll\t%0, 0x8\n\t" \
0595 "or\t%0, $1\n\t" \
0596 "li\t%1, 0\n" \
0597 ".set\tpop\n\t" \
0598 "10:\n\t" \
0599 ".insn\n\t" \
0600 ".section\t.fixup,\"ax\"\n\t" \
0601 "11:\tli\t%1, %3\n\t" \
0602 "j\t10b\n\t" \
0603 ".previous\n\t" \
0604 ".section\t__ex_table,\"a\"\n\t" \
0605 STR(PTR_WD)"\t1b, 11b\n\t" \
0606 STR(PTR_WD)"\t2b, 11b\n\t" \
0607 STR(PTR_WD)"\t3b, 11b\n\t" \
0608 STR(PTR_WD)"\t4b, 11b\n\t" \
0609 STR(PTR_WD)"\t5b, 11b\n\t" \
0610 STR(PTR_WD)"\t6b, 11b\n\t" \
0611 STR(PTR_WD)"\t7b, 11b\n\t" \
0612 STR(PTR_WD)"\t8b, 11b\n\t" \
0613 ".previous" \
0614 : "=&r" (value), "=r" (res) \
0615 : "r" (addr), "i" (-EFAULT)); \
0616 } while (0)
0617 #endif
0618
0619 #define _StoreHW(addr, value, res, type) \
0620 do { \
0621 __asm__ __volatile__ ( \
0622 ".set\tnoat\n" \
0623 "1:\t"type##_sb("%1", "0(%2)")"\n" \
0624 "srl\t$1,%1, 0x8\n" \
0625 "2:\t"type##_sb("$1", "1(%2)")"\n" \
0626 ".set\tat\n\t" \
0627 "li\t%0, 0\n" \
0628 "3:\n\t" \
0629 ".insn\n\t" \
0630 ".section\t.fixup,\"ax\"\n\t" \
0631 "4:\tli\t%0, %3\n\t" \
0632 "j\t3b\n\t" \
0633 ".previous\n\t" \
0634 ".section\t__ex_table,\"a\"\n\t" \
0635 STR(PTR_WD)"\t1b, 4b\n\t" \
0636 STR(PTR_WD)"\t2b, 4b\n\t" \
0637 ".previous" \
0638 : "=r" (res) \
0639 : "r" (value), "r" (addr), "i" (-EFAULT));\
0640 } while (0)
0641
0642 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
0643 #define _StoreW(addr, value, res, type) \
0644 do { \
0645 __asm__ __volatile__ ( \
0646 "1:\t"type##_swl("%1", "3(%2)")"\n" \
0647 "2:\t"type##_swr("%1", "(%2)")"\n\t"\
0648 "li\t%0, 0\n" \
0649 "3:\n\t" \
0650 ".insn\n\t" \
0651 ".section\t.fixup,\"ax\"\n\t" \
0652 "4:\tli\t%0, %3\n\t" \
0653 "j\t3b\n\t" \
0654 ".previous\n\t" \
0655 ".section\t__ex_table,\"a\"\n\t" \
0656 STR(PTR_WD)"\t1b, 4b\n\t" \
0657 STR(PTR_WD)"\t2b, 4b\n\t" \
0658 ".previous" \
0659 : "=r" (res) \
0660 : "r" (value), "r" (addr), "i" (-EFAULT)); \
0661 } while (0)
0662
0663 #define _StoreDW(addr, value, res) \
0664 do { \
0665 __asm__ __volatile__ ( \
0666 "1:\tsdl\t%1, 7(%2)\n" \
0667 "2:\tsdr\t%1, (%2)\n\t" \
0668 "li\t%0, 0\n" \
0669 "3:\n\t" \
0670 ".insn\n\t" \
0671 ".section\t.fixup,\"ax\"\n\t" \
0672 "4:\tli\t%0, %3\n\t" \
0673 "j\t3b\n\t" \
0674 ".previous\n\t" \
0675 ".section\t__ex_table,\"a\"\n\t" \
0676 STR(PTR_WD)"\t1b, 4b\n\t" \
0677 STR(PTR_WD)"\t2b, 4b\n\t" \
0678 ".previous" \
0679 : "=r" (res) \
0680 : "r" (value), "r" (addr), "i" (-EFAULT)); \
0681 } while (0)
0682
0683 #else
0684
0685 #define _StoreW(addr, value, res, type) \
0686 do { \
0687 __asm__ __volatile__ ( \
0688 ".set\tpush\n\t" \
0689 ".set\tnoat\n\t" \
0690 "1:"type##_sb("%1", "0(%2)")"\n\t" \
0691 "srl\t$1, %1, 0x8\n\t" \
0692 "2:"type##_sb("$1", "1(%2)")"\n\t" \
0693 "srl\t$1, $1, 0x8\n\t" \
0694 "3:"type##_sb("$1", "2(%2)")"\n\t" \
0695 "srl\t$1, $1, 0x8\n\t" \
0696 "4:"type##_sb("$1", "3(%2)")"\n\t" \
0697 ".set\tpop\n\t" \
0698 "li\t%0, 0\n" \
0699 "10:\n\t" \
0700 ".insn\n\t" \
0701 ".section\t.fixup,\"ax\"\n\t" \
0702 "11:\tli\t%0, %3\n\t" \
0703 "j\t10b\n\t" \
0704 ".previous\n\t" \
0705 ".section\t__ex_table,\"a\"\n\t" \
0706 STR(PTR_WD)"\t1b, 11b\n\t" \
0707 STR(PTR_WD)"\t2b, 11b\n\t" \
0708 STR(PTR_WD)"\t3b, 11b\n\t" \
0709 STR(PTR_WD)"\t4b, 11b\n\t" \
0710 ".previous" \
0711 : "=&r" (res) \
0712 : "r" (value), "r" (addr), "i" (-EFAULT) \
0713 : "memory"); \
0714 } while (0)
0715
0716 #define _StoreDW(addr, value, res) \
0717 do { \
0718 __asm__ __volatile__ ( \
0719 ".set\tpush\n\t" \
0720 ".set\tnoat\n\t" \
0721 "1:sb\t%1, 0(%2)\n\t" \
0722 "dsrl\t$1, %1, 0x8\n\t" \
0723 "2:sb\t$1, 1(%2)\n\t" \
0724 "dsrl\t$1, $1, 0x8\n\t" \
0725 "3:sb\t$1, 2(%2)\n\t" \
0726 "dsrl\t$1, $1, 0x8\n\t" \
0727 "4:sb\t$1, 3(%2)\n\t" \
0728 "dsrl\t$1, $1, 0x8\n\t" \
0729 "5:sb\t$1, 4(%2)\n\t" \
0730 "dsrl\t$1, $1, 0x8\n\t" \
0731 "6:sb\t$1, 5(%2)\n\t" \
0732 "dsrl\t$1, $1, 0x8\n\t" \
0733 "7:sb\t$1, 6(%2)\n\t" \
0734 "dsrl\t$1, $1, 0x8\n\t" \
0735 "8:sb\t$1, 7(%2)\n\t" \
0736 "dsrl\t$1, $1, 0x8\n\t" \
0737 ".set\tpop\n\t" \
0738 "li\t%0, 0\n" \
0739 "10:\n\t" \
0740 ".insn\n\t" \
0741 ".section\t.fixup,\"ax\"\n\t" \
0742 "11:\tli\t%0, %3\n\t" \
0743 "j\t10b\n\t" \
0744 ".previous\n\t" \
0745 ".section\t__ex_table,\"a\"\n\t" \
0746 STR(PTR_WD)"\t1b, 11b\n\t" \
0747 STR(PTR_WD)"\t2b, 11b\n\t" \
0748 STR(PTR_WD)"\t3b, 11b\n\t" \
0749 STR(PTR_WD)"\t4b, 11b\n\t" \
0750 STR(PTR_WD)"\t5b, 11b\n\t" \
0751 STR(PTR_WD)"\t6b, 11b\n\t" \
0752 STR(PTR_WD)"\t7b, 11b\n\t" \
0753 STR(PTR_WD)"\t8b, 11b\n\t" \
0754 ".previous" \
0755 : "=&r" (res) \
0756 : "r" (value), "r" (addr), "i" (-EFAULT) \
0757 : "memory"); \
0758 } while (0)
0759
0760 #endif
0761 #endif
0762
0763 #define LoadHWU(addr, value, res) _LoadHWU(addr, value, res, kernel)
0764 #define LoadHWUE(addr, value, res) _LoadHWU(addr, value, res, user)
0765 #define LoadWU(addr, value, res) _LoadWU(addr, value, res, kernel)
0766 #define LoadWUE(addr, value, res) _LoadWU(addr, value, res, user)
0767 #define LoadHW(addr, value, res) _LoadHW(addr, value, res, kernel)
0768 #define LoadHWE(addr, value, res) _LoadHW(addr, value, res, user)
0769 #define LoadW(addr, value, res) _LoadW(addr, value, res, kernel)
0770 #define LoadWE(addr, value, res) _LoadW(addr, value, res, user)
0771 #define LoadDW(addr, value, res) _LoadDW(addr, value, res)
0772
0773 #define StoreHW(addr, value, res) _StoreHW(addr, value, res, kernel)
0774 #define StoreHWE(addr, value, res) _StoreHW(addr, value, res, user)
0775 #define StoreW(addr, value, res) _StoreW(addr, value, res, kernel)
0776 #define StoreWE(addr, value, res) _StoreW(addr, value, res, user)
0777 #define StoreDW(addr, value, res) _StoreDW(addr, value, res)
0778
0779 #endif