1 /* SPDX-License-Identifier: GPL-2.0-or-later * 1 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)") 12 "2:\t"type##_lbu("$1", "1(%2)" 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\ 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)") 35 "2:\t"type##_lwr("%0", "3(%2)" 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\ 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)")"\ 59 "2:"type##_lbu("$1", "1(%2)")" 60 "sll\t%0, 0x8\n\t" 61 "or\t%0, $1\n\t" 62 "3:"type##_lbu("$1", "2(%2)")" 63 "sll\t%0, 0x8\n\t" 64 "or\t%0, $1\n\t" 65 "4:"type##_lbu("$1", "3(%2)")" 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\ 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)" 93 "2:\t"type##_lbu("$1", "1(%2)" 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\ 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)") 117 "2:\t"type##_lwr("%0", "3(%2)" 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\ 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\ 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)")" 163 "2:"type##_lbu("$1", "1(%2)")" 164 "sll\t%0, 0x8\n\t" 165 "or\t%0, $1\n\t" 166 "3:"type##_lbu("$1", "2(%2)")" 167 "sll\t%0, 0x8\n\t" 168 "or\t%0, $1\n\t" 169 "4:"type##_lbu("$1", "3(%2)")" 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\ 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\ 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)") 247 "srl\t$1, %1, 0x8\n" 248 "2:\t"type##_sb("$1", "0(%2)") 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\ 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" 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)") 270 "2:\t"type##_swr("%1", "3(%2)" 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\ 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" 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\ 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" 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)")"\ 313 "srl\t$1, %1, 0x8\n\t" 314 "2:"type##_sb("$1", "2(%2)")"\ 315 "srl\t$1, $1, 0x8\n\t" 316 "3:"type##_sb("$1", "1(%2)")"\ 317 "srl\t$1, $1, 0x8\n\t" 318 "4:"type##_sb("$1", "0(%2)")"\ 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\ 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" 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\ 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" 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)") 390 "2:\t"type##_lbu("$1", "0(%2)" 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\ 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)" 413 "2:\t"type##_lwr("%0", "(%2)") 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\ 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)")"\ 437 "2:"type##_lbu("$1", "2(%2)")" 438 "sll\t%0, 0x8\n\t" 439 "or\t%0, $1\n\t" 440 "3:"type##_lbu("$1", "1(%2)")" 441 "sll\t%0, 0x8\n\t" 442 "or\t%0, $1\n\t" 443 "4:"type##_lbu("$1", "0(%2)")" 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\ 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)" 472 "2:\t"type##_lbu("$1", "0(%2)" 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\ 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)" 496 "2:\t"type##_lwr("%0", "(%2)") 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\ 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\ 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)")" 542 "2:"type##_lbu("$1", "2(%2)")" 543 "sll\t%0, 0x8\n\t" 544 "or\t%0, $1\n\t" 545 "3:"type##_lbu("$1", "1(%2)")" 546 "sll\t%0, 0x8\n\t" 547 "or\t%0, $1\n\t" 548 "4:"type##_lbu("$1", "0(%2)")" 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\ 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\ 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)") 624 "srl\t$1,%1, 0x8\n" 625 "2:\t"type##_sb("$1", "1(%2)") 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\ 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" 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)" 647 "2:\t"type##_swr("%1", "(%2)") 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\ 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" 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\ 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" 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)")"\ 691 "srl\t$1, %1, 0x8\n\t" 692 "2:"type##_sb("$1", "1(%2)")"\ 693 "srl\t$1, $1, 0x8\n\t" 694 "3:"type##_sb("$1", "2(%2)")"\ 695 "srl\t$1, $1, 0x8\n\t" 696 "4:"type##_sb("$1", "3(%2)")"\ 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\ 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" 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\ 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" 757 : "memory"); 758 } while (0) 759 760 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */ 761 #endif 762 763 #define LoadHWU(addr, value, res) _LoadH 764 #define LoadHWUE(addr, value, res) _LoadH 765 #define LoadWU(addr, value, res) _LoadW 766 #define LoadWUE(addr, value, res) _LoadW 767 #define LoadHW(addr, value, res) _LoadH 768 #define LoadHWE(addr, value, res) _LoadH 769 #define LoadW(addr, value, res) _LoadW 770 #define LoadWE(addr, value, res) _LoadW 771 #define LoadDW(addr, value, res) _LoadD 772 773 #define StoreHW(addr, value, res) _Store 774 #define StoreHWE(addr, value, res) _Store 775 #define StoreW(addr, value, res) _Store 776 #define StoreWE(addr, value, res) _Store 777 #define StoreDW(addr, value, res) _Store 778 779 #endif /* _ASM_MIPS_UNALIGNED_EMUL_H */ 780
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.