1 /* 2 * Format of an instruction in memory. 3 * 4 * This file is subject to the terms and conditions of the GNU General Public 5 * License. See the file "COPYING" in the main directory of this archive 6 * for more details. 7 * 8 * Copyright (C) 1996, 2000 by Ralf Baechle 9 * Copyright (C) 2006 by Thiemo Seufer 10 */ 11 #ifndef _ASM_INST_H 12 #define _ASM_INST_H 13 14 #include <uapi/asm/inst.h> 15 16 #if (_MIPS_SZPTR == 32) 17 #define PTR_STR ".word" 18 #endif 19 #if (_MIPS_SZPTR == 64) 20 #define PTR_STR ".dword" 21 #endif 22 23 /* HACHACHAHCAHC ... */ 24 25 /* In case some other massaging is needed, keep MIPSInst as wrapper */ 26 27 #define MIPSInst(x) x 28 29 #define I_OPCODE_SFT 26 30 #define MIPSInst_OPCODE(x) (MIPSInst(x) >> I_OPCODE_SFT) 31 32 #define I_JTARGET_SFT 0 33 #define MIPSInst_JTARGET(x) (MIPSInst(x) & 0x03ffffff) 34 35 #define I_RS_SFT 21 36 #define MIPSInst_RS(x) ((MIPSInst(x) & 0x03e00000) >> I_RS_SFT) 37 38 #define I_RT_SFT 16 39 #define MIPSInst_RT(x) ((MIPSInst(x) & 0x001f0000) >> I_RT_SFT) 40 41 #define I_IMM_SFT 0 42 #define MIPSInst_SIMM(x) ((int)((short)(MIPSInst(x) & 0xffff))) 43 #define MIPSInst_UIMM(x) (MIPSInst(x) & 0xffff) 44 45 #define I_CACHEOP_SFT 18 46 #define MIPSInst_CACHEOP(x) ((MIPSInst(x) & 0x001c0000) >> I_CACHEOP_SFT) 47 48 #define I_CACHESEL_SFT 16 49 #define MIPSInst_CACHESEL(x) ((MIPSInst(x) & 0x00030000) >> I_CACHESEL_SFT) 50 51 #define I_RD_SFT 11 52 #define MIPSInst_RD(x) ((MIPSInst(x) & 0x0000f800) >> I_RD_SFT) 53 54 #define I_RE_SFT 6 55 #define MIPSInst_RE(x) ((MIPSInst(x) & 0x000007c0) >> I_RE_SFT) 56 57 #define I_FUNC_SFT 0 58 #define MIPSInst_FUNC(x) (MIPSInst(x) & 0x0000003f) 59 60 #define I_FFMT_SFT 21 61 #define MIPSInst_FFMT(x) ((MIPSInst(x) & 0x01e00000) >> I_FFMT_SFT) 62 63 #define I_FT_SFT 16 64 #define MIPSInst_FT(x) ((MIPSInst(x) & 0x001f0000) >> I_FT_SFT) 65 66 #define I_FS_SFT 11 67 #define MIPSInst_FS(x) ((MIPSInst(x) & 0x0000f800) >> I_FS_SFT) 68 69 #define I_FD_SFT 6 70 #define MIPSInst_FD(x) ((MIPSInst(x) & 0x000007c0) >> I_FD_SFT) 71 72 #define I_FR_SFT 21 73 #define MIPSInst_FR(x) ((MIPSInst(x) & 0x03e00000) >> I_FR_SFT) 74 75 #define I_FMA_FUNC_SFT 2 76 #define MIPSInst_FMA_FUNC(x) ((MIPSInst(x) & 0x0000003c) >> I_FMA_FUNC_SFT) 77 78 #define I_FMA_FFMT_SFT 0 79 #define MIPSInst_FMA_FFMT(x) (MIPSInst(x) & 0x00000003) 80 81 typedef unsigned int mips_instruction; 82 83 /* microMIPS instruction decode structure. Do NOT export!!! */ 84 struct mm_decoded_insn { 85 mips_instruction insn; 86 mips_instruction next_insn; 87 int pc_inc; 88 int next_pc_inc; 89 int micro_mips_mode; 90 }; 91 92 /* Recode table from 16-bit register notation to 32-bit GPR. Do NOT export!!! */ 93 extern const int reg16to32[]; 94 95 #ifdef __BIG_ENDIAN 96 #define _LoadHW(addr, value, res, type) \ 97 do { \ 98 __asm__ __volatile__ (".set\tnoat\n" \ 99 "1:\t"type##_lb("%0", "0(%2)")"\n" \ 100 "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\ 101 "sll\t%0, 0x8\n\t" \ 102 "or\t%0, $1\n\t" \ 103 "li\t%1, 0\n" \ 104 "3:\t.set\tat\n\t" \ 105 ".insn\n\t" \ 106 ".section\t.fixup,\"ax\"\n\t" \ 107 "4:\tli\t%1, %3\n\t" \ 108 "j\t3b\n\t" \ 109 ".previous\n\t" \ 110 ".section\t__ex_table,\"a\"\n\t" \ 111 PTR_STR"\t1b, 4b\n\t" \ 112 PTR_STR"\t2b, 4b\n\t" \ 113 ".previous" \ 114 : "=&r" (value), "=r" (res) \ 115 : "r" (addr), "i" (-EFAULT)); \ 116 } while (0) 117 118 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR 119 #define _LoadW(addr, value, res, type) \ 120 do { \ 121 __asm__ __volatile__ ( \ 122 "1:\t"type##_lwl("%0", "(%2)")"\n" \ 123 "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\ 124 "li\t%1, 0\n" \ 125 "3:\n\t" \ 126 ".insn\n\t" \ 127 ".section\t.fixup,\"ax\"\n\t" \ 128 "4:\tli\t%1, %3\n\t" \ 129 "j\t3b\n\t" \ 130 ".previous\n\t" \ 131 ".section\t__ex_table,\"a\"\n\t" \ 132 PTR_STR"\t1b, 4b\n\t" \ 133 PTR_STR"\t2b, 4b\n\t" \ 134 ".previous" \ 135 : "=&r" (value), "=r" (res) \ 136 : "r" (addr), "i" (-EFAULT)); \ 137 } while (0) 138 139 #else /* CONFIG_CPU_NO_LOAD_STORE_LR */ 140 /* For CPUs without lwl instruction */ 141 #define _LoadW(addr, value, res, type) \ 142 do { \ 143 __asm__ __volatile__ ( \ 144 ".set\tpush\n" \ 145 ".set\tnoat\n\t" \ 146 "1:"type##_lb("%0", "0(%2)")"\n\t" \ 147 "2:"type##_lbu("$1", "1(%2)")"\n\t" \ 148 "sll\t%0, 0x8\n\t" \ 149 "or\t%0, $1\n\t" \ 150 "3:"type##_lbu("$1", "2(%2)")"\n\t" \ 151 "sll\t%0, 0x8\n\t" \ 152 "or\t%0, $1\n\t" \ 153 "4:"type##_lbu("$1", "3(%2)")"\n\t" \ 154 "sll\t%0, 0x8\n\t" \ 155 "or\t%0, $1\n\t" \ 156 "li\t%1, 0\n" \ 157 ".set\tpop\n" \ 158 "10:\n\t" \ 159 ".insn\n\t" \ 160 ".section\t.fixup,\"ax\"\n\t" \ 161 "11:\tli\t%1, %3\n\t" \ 162 "j\t10b\n\t" \ 163 ".previous\n\t" \ 164 ".section\t__ex_table,\"a\"\n\t" \ 165 PTR_STR"\t1b, 11b\n\t" \ 166 PTR_STR"\t2b, 11b\n\t" \ 167 PTR_STR"\t3b, 11b\n\t" \ 168 PTR_STR"\t4b, 11b\n\t" \ 169 ".previous" \ 170 : "=&r" (value), "=r" (res) \ 171 : "r" (addr), "i" (-EFAULT)); \ 172 } while (0) 173 174 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */ 175 176 #define _LoadHWU(addr, value, res, type) \ 177 do { \ 178 __asm__ __volatile__ ( \ 179 ".set\tnoat\n" \ 180 "1:\t"type##_lbu("%0", "0(%2)")"\n" \ 181 "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\ 182 "sll\t%0, 0x8\n\t" \ 183 "or\t%0, $1\n\t" \ 184 "li\t%1, 0\n" \ 185 "3:\n\t" \ 186 ".insn\n\t" \ 187 ".set\tat\n\t" \ 188 ".section\t.fixup,\"ax\"\n\t" \ 189 "4:\tli\t%1, %3\n\t" \ 190 "j\t3b\n\t" \ 191 ".previous\n\t" \ 192 ".section\t__ex_table,\"a\"\n\t" \ 193 PTR_STR"\t1b, 4b\n\t" \ 194 PTR_STR"\t2b, 4b\n\t" \ 195 ".previous" \ 196 : "=&r" (value), "=r" (res) \ 197 : "r" (addr), "i" (-EFAULT)); \ 198 } while (0) 199 200 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR 201 #define _LoadWU(addr, value, res, type) \ 202 do { \ 203 __asm__ __volatile__ ( \ 204 "1:\t"type##_lwl("%0", "(%2)")"\n" \ 205 "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\ 206 "dsll\t%0, %0, 32\n\t" \ 207 "dsrl\t%0, %0, 32\n\t" \ 208 "li\t%1, 0\n" \ 209 "3:\n\t" \ 210 ".insn\n\t" \ 211 "\t.section\t.fixup,\"ax\"\n\t" \ 212 "4:\tli\t%1, %3\n\t" \ 213 "j\t3b\n\t" \ 214 ".previous\n\t" \ 215 ".section\t__ex_table,\"a\"\n\t" \ 216 PTR_STR"\t1b, 4b\n\t" \ 217 PTR_STR"\t2b, 4b\n\t" \ 218 ".previous" \ 219 : "=&r" (value), "=r" (res) \ 220 : "r" (addr), "i" (-EFAULT)); \ 221 } while (0) 222 223 #define _LoadDW(addr, value, res) \ 224 do { \ 225 __asm__ __volatile__ ( \ 226 "1:\tldl\t%0, (%2)\n" \ 227 "2:\tldr\t%0, 7(%2)\n\t" \ 228 "li\t%1, 0\n" \ 229 "3:\n\t" \ 230 ".insn\n\t" \ 231 "\t.section\t.fixup,\"ax\"\n\t" \ 232 "4:\tli\t%1, %3\n\t" \ 233 "j\t3b\n\t" \ 234 ".previous\n\t" \ 235 ".section\t__ex_table,\"a\"\n\t" \ 236 PTR_STR"\t1b, 4b\n\t" \ 237 PTR_STR"\t2b, 4b\n\t" \ 238 ".previous" \ 239 : "=&r" (value), "=r" (res) \ 240 : "r" (addr), "i" (-EFAULT)); \ 241 } while (0) 242 243 #else /* CONFIG_CPU_NO_LOAD_STORE_LR */ 244 /* For CPUs without lwl and ldl instructions */ 245 #define _LoadWU(addr, value, res, type) \ 246 do { \ 247 __asm__ __volatile__ ( \ 248 ".set\tpush\n\t" \ 249 ".set\tnoat\n\t" \ 250 "1:"type##_lbu("%0", "0(%2)")"\n\t" \ 251 "2:"type##_lbu("$1", "1(%2)")"\n\t" \ 252 "sll\t%0, 0x8\n\t" \ 253 "or\t%0, $1\n\t" \ 254 "3:"type##_lbu("$1", "2(%2)")"\n\t" \ 255 "sll\t%0, 0x8\n\t" \ 256 "or\t%0, $1\n\t" \ 257 "4:"type##_lbu("$1", "3(%2)")"\n\t" \ 258 "sll\t%0, 0x8\n\t" \ 259 "or\t%0, $1\n\t" \ 260 "li\t%1, 0\n" \ 261 ".set\tpop\n" \ 262 "10:\n\t" \ 263 ".insn\n\t" \ 264 ".section\t.fixup,\"ax\"\n\t" \ 265 "11:\tli\t%1, %3\n\t" \ 266 "j\t10b\n\t" \ 267 ".previous\n\t" \ 268 ".section\t__ex_table,\"a\"\n\t" \ 269 PTR_STR"\t1b, 11b\n\t" \ 270 PTR_STR"\t2b, 11b\n\t" \ 271 PTR_STR"\t3b, 11b\n\t" \ 272 PTR_STR"\t4b, 11b\n\t" \ 273 ".previous" \ 274 : "=&r" (value), "=r" (res) \ 275 : "r" (addr), "i" (-EFAULT)); \ 276 } while (0) 277 278 #define _LoadDW(addr, value, res) \ 279 do { \ 280 __asm__ __volatile__ ( \ 281 ".set\tpush\n\t" \ 282 ".set\tnoat\n\t" \ 283 "1:lb\t%0, 0(%2)\n\t" \ 284 "2:lbu\t $1, 1(%2)\n\t" \ 285 "dsll\t%0, 0x8\n\t" \ 286 "or\t%0, $1\n\t" \ 287 "3:lbu\t$1, 2(%2)\n\t" \ 288 "dsll\t%0, 0x8\n\t" \ 289 "or\t%0, $1\n\t" \ 290 "4:lbu\t$1, 3(%2)\n\t" \ 291 "dsll\t%0, 0x8\n\t" \ 292 "or\t%0, $1\n\t" \ 293 "5:lbu\t$1, 4(%2)\n\t" \ 294 "dsll\t%0, 0x8\n\t" \ 295 "or\t%0, $1\n\t" \ 296 "6:lbu\t$1, 5(%2)\n\t" \ 297 "dsll\t%0, 0x8\n\t" \ 298 "or\t%0, $1\n\t" \ 299 "7:lbu\t$1, 6(%2)\n\t" \ 300 "dsll\t%0, 0x8\n\t" \ 301 "or\t%0, $1\n\t" \ 302 "8:lbu\t$1, 7(%2)\n\t" \ 303 "dsll\t%0, 0x8\n\t" \ 304 "or\t%0, $1\n\t" \ 305 "li\t%1, 0\n" \ 306 ".set\tpop\n\t" \ 307 "10:\n\t" \ 308 ".insn\n\t" \ 309 ".section\t.fixup,\"ax\"\n\t" \ 310 "11:\tli\t%1, %3\n\t" \ 311 "j\t10b\n\t" \ 312 ".previous\n\t" \ 313 ".section\t__ex_table,\"a\"\n\t" \ 314 PTR_STR"\t1b, 11b\n\t" \ 315 PTR_STR"\t2b, 11b\n\t" \ 316 PTR_STR"\t3b, 11b\n\t" \ 317 PTR_STR"\t4b, 11b\n\t" \ 318 PTR_STR"\t5b, 11b\n\t" \ 319 PTR_STR"\t6b, 11b\n\t" \ 320 PTR_STR"\t7b, 11b\n\t" \ 321 PTR_STR"\t8b, 11b\n\t" \ 322 ".previous" \ 323 : "=&r" (value), "=r" (res) \ 324 : "r" (addr), "i" (-EFAULT)); \ 325 } while (0) 326 327 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */ 328 329 330 #define _StoreHW(addr, value, res, type) \ 331 do { \ 332 __asm__ __volatile__ ( \ 333 ".set\tnoat\n" \ 334 "1:\t"type##_sb("%1", "1(%2)")"\n" \ 335 "srl\t$1, %1, 0x8\n" \ 336 "2:\t"type##_sb("$1", "0(%2)")"\n" \ 337 ".set\tat\n\t" \ 338 "li\t%0, 0\n" \ 339 "3:\n\t" \ 340 ".insn\n\t" \ 341 ".section\t.fixup,\"ax\"\n\t" \ 342 "4:\tli\t%0, %3\n\t" \ 343 "j\t3b\n\t" \ 344 ".previous\n\t" \ 345 ".section\t__ex_table,\"a\"\n\t" \ 346 PTR_STR"\t1b, 4b\n\t" \ 347 PTR_STR"\t2b, 4b\n\t" \ 348 ".previous" \ 349 : "=r" (res) \ 350 : "r" (value), "r" (addr), "i" (-EFAULT));\ 351 } while (0) 352 353 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR 354 #define _StoreW(addr, value, res, type) \ 355 do { \ 356 __asm__ __volatile__ ( \ 357 "1:\t"type##_swl("%1", "(%2)")"\n" \ 358 "2:\t"type##_swr("%1", "3(%2)")"\n\t"\ 359 "li\t%0, 0\n" \ 360 "3:\n\t" \ 361 ".insn\n\t" \ 362 ".section\t.fixup,\"ax\"\n\t" \ 363 "4:\tli\t%0, %3\n\t" \ 364 "j\t3b\n\t" \ 365 ".previous\n\t" \ 366 ".section\t__ex_table,\"a\"\n\t" \ 367 PTR_STR"\t1b, 4b\n\t" \ 368 PTR_STR"\t2b, 4b\n\t" \ 369 ".previous" \ 370 : "=r" (res) \ 371 : "r" (value), "r" (addr), "i" (-EFAULT)); \ 372 } while (0) 373 374 #define _StoreDW(addr, value, res) \ 375 do { \ 376 __asm__ __volatile__ ( \ 377 "1:\tsdl\t%1,(%2)\n" \ 378 "2:\tsdr\t%1, 7(%2)\n\t" \ 379 "li\t%0, 0\n" \ 380 "3:\n\t" \ 381 ".insn\n\t" \ 382 ".section\t.fixup,\"ax\"\n\t" \ 383 "4:\tli\t%0, %3\n\t" \ 384 "j\t3b\n\t" \ 385 ".previous\n\t" \ 386 ".section\t__ex_table,\"a\"\n\t" \ 387 PTR_STR"\t1b, 4b\n\t" \ 388 PTR_STR"\t2b, 4b\n\t" \ 389 ".previous" \ 390 : "=r" (res) \ 391 : "r" (value), "r" (addr), "i" (-EFAULT)); \ 392 } while (0) 393 394 #else /* CONFIG_CPU_NO_LOAD_STORE_LR */ 395 #define _StoreW(addr, value, res, type) \ 396 do { \ 397 __asm__ __volatile__ ( \ 398 ".set\tpush\n\t" \ 399 ".set\tnoat\n\t" \ 400 "1:"type##_sb("%1", "3(%2)")"\n\t" \ 401 "srl\t$1, %1, 0x8\n\t" \ 402 "2:"type##_sb("$1", "2(%2)")"\n\t" \ 403 "srl\t$1, $1, 0x8\n\t" \ 404 "3:"type##_sb("$1", "1(%2)")"\n\t" \ 405 "srl\t$1, $1, 0x8\n\t" \ 406 "4:"type##_sb("$1", "0(%2)")"\n\t" \ 407 ".set\tpop\n\t" \ 408 "li\t%0, 0\n" \ 409 "10:\n\t" \ 410 ".insn\n\t" \ 411 ".section\t.fixup,\"ax\"\n\t" \ 412 "11:\tli\t%0, %3\n\t" \ 413 "j\t10b\n\t" \ 414 ".previous\n\t" \ 415 ".section\t__ex_table,\"a\"\n\t" \ 416 PTR_STR"\t1b, 11b\n\t" \ 417 PTR_STR"\t2b, 11b\n\t" \ 418 PTR_STR"\t3b, 11b\n\t" \ 419 PTR_STR"\t4b, 11b\n\t" \ 420 ".previous" \ 421 : "=&r" (res) \ 422 : "r" (value), "r" (addr), "i" (-EFAULT) \ 423 : "memory"); \ 424 } while (0) 425 426 #define _StoreDW(addr, value, res) \ 427 do { \ 428 __asm__ __volatile__ ( \ 429 ".set\tpush\n\t" \ 430 ".set\tnoat\n\t" \ 431 "1:sb\t%1, 7(%2)\n\t" \ 432 "dsrl\t$1, %1, 0x8\n\t" \ 433 "2:sb\t$1, 6(%2)\n\t" \ 434 "dsrl\t$1, $1, 0x8\n\t" \ 435 "3:sb\t$1, 5(%2)\n\t" \ 436 "dsrl\t$1, $1, 0x8\n\t" \ 437 "4:sb\t$1, 4(%2)\n\t" \ 438 "dsrl\t$1, $1, 0x8\n\t" \ 439 "5:sb\t$1, 3(%2)\n\t" \ 440 "dsrl\t$1, $1, 0x8\n\t" \ 441 "6:sb\t$1, 2(%2)\n\t" \ 442 "dsrl\t$1, $1, 0x8\n\t" \ 443 "7:sb\t$1, 1(%2)\n\t" \ 444 "dsrl\t$1, $1, 0x8\n\t" \ 445 "8:sb\t$1, 0(%2)\n\t" \ 446 "dsrl\t$1, $1, 0x8\n\t" \ 447 ".set\tpop\n\t" \ 448 "li\t%0, 0\n" \ 449 "10:\n\t" \ 450 ".insn\n\t" \ 451 ".section\t.fixup,\"ax\"\n\t" \ 452 "11:\tli\t%0, %3\n\t" \ 453 "j\t10b\n\t" \ 454 ".previous\n\t" \ 455 ".section\t__ex_table,\"a\"\n\t" \ 456 PTR_STR"\t1b, 11b\n\t" \ 457 PTR_STR"\t2b, 11b\n\t" \ 458 PTR_STR"\t3b, 11b\n\t" \ 459 PTR_STR"\t4b, 11b\n\t" \ 460 PTR_STR"\t5b, 11b\n\t" \ 461 PTR_STR"\t6b, 11b\n\t" \ 462 PTR_STR"\t7b, 11b\n\t" \ 463 PTR_STR"\t8b, 11b\n\t" \ 464 ".previous" \ 465 : "=&r" (res) \ 466 : "r" (value), "r" (addr), "i" (-EFAULT) \ 467 : "memory"); \ 468 } while (0) 469 470 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */ 471 472 #else /* __BIG_ENDIAN */ 473 474 #define _LoadHW(addr, value, res, type) \ 475 do { \ 476 __asm__ __volatile__ (".set\tnoat\n" \ 477 "1:\t"type##_lb("%0", "1(%2)")"\n" \ 478 "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\ 479 "sll\t%0, 0x8\n\t" \ 480 "or\t%0, $1\n\t" \ 481 "li\t%1, 0\n" \ 482 "3:\t.set\tat\n\t" \ 483 ".insn\n\t" \ 484 ".section\t.fixup,\"ax\"\n\t" \ 485 "4:\tli\t%1, %3\n\t" \ 486 "j\t3b\n\t" \ 487 ".previous\n\t" \ 488 ".section\t__ex_table,\"a\"\n\t" \ 489 PTR_STR"\t1b, 4b\n\t" \ 490 PTR_STR"\t2b, 4b\n\t" \ 491 ".previous" \ 492 : "=&r" (value), "=r" (res) \ 493 : "r" (addr), "i" (-EFAULT)); \ 494 } while (0) 495 496 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR 497 #define _LoadW(addr, value, res, type) \ 498 do { \ 499 __asm__ __volatile__ ( \ 500 "1:\t"type##_lwl("%0", "3(%2)")"\n" \ 501 "2:\t"type##_lwr("%0", "(%2)")"\n\t"\ 502 "li\t%1, 0\n" \ 503 "3:\n\t" \ 504 ".insn\n\t" \ 505 ".section\t.fixup,\"ax\"\n\t" \ 506 "4:\tli\t%1, %3\n\t" \ 507 "j\t3b\n\t" \ 508 ".previous\n\t" \ 509 ".section\t__ex_table,\"a\"\n\t" \ 510 PTR_STR"\t1b, 4b\n\t" \ 511 PTR_STR"\t2b, 4b\n\t" \ 512 ".previous" \ 513 : "=&r" (value), "=r" (res) \ 514 : "r" (addr), "i" (-EFAULT)); \ 515 } while (0) 516 517 #else /* CONFIG_CPU_NO_LOAD_STORE_LR */ 518 /* For CPUs without lwl instruction */ 519 #define _LoadW(addr, value, res, type) \ 520 do { \ 521 __asm__ __volatile__ ( \ 522 ".set\tpush\n" \ 523 ".set\tnoat\n\t" \ 524 "1:"type##_lb("%0", "3(%2)")"\n\t" \ 525 "2:"type##_lbu("$1", "2(%2)")"\n\t" \ 526 "sll\t%0, 0x8\n\t" \ 527 "or\t%0, $1\n\t" \ 528 "3:"type##_lbu("$1", "1(%2)")"\n\t" \ 529 "sll\t%0, 0x8\n\t" \ 530 "or\t%0, $1\n\t" \ 531 "4:"type##_lbu("$1", "0(%2)")"\n\t" \ 532 "sll\t%0, 0x8\n\t" \ 533 "or\t%0, $1\n\t" \ 534 "li\t%1, 0\n" \ 535 ".set\tpop\n" \ 536 "10:\n\t" \ 537 ".insn\n\t" \ 538 ".section\t.fixup,\"ax\"\n\t" \ 539 "11:\tli\t%1, %3\n\t" \ 540 "j\t10b\n\t" \ 541 ".previous\n\t" \ 542 ".section\t__ex_table,\"a\"\n\t" \ 543 PTR_STR"\t1b, 11b\n\t" \ 544 PTR_STR"\t2b, 11b\n\t" \ 545 PTR_STR"\t3b, 11b\n\t" \ 546 PTR_STR"\t4b, 11b\n\t" \ 547 ".previous" \ 548 : "=&r" (value), "=r" (res) \ 549 : "r" (addr), "i" (-EFAULT)); \ 550 } while (0) 551 552 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */ 553 554 555 #define _LoadHWU(addr, value, res, type) \ 556 do { \ 557 __asm__ __volatile__ ( \ 558 ".set\tnoat\n" \ 559 "1:\t"type##_lbu("%0", "1(%2)")"\n" \ 560 "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\ 561 "sll\t%0, 0x8\n\t" \ 562 "or\t%0, $1\n\t" \ 563 "li\t%1, 0\n" \ 564 "3:\n\t" \ 565 ".insn\n\t" \ 566 ".set\tat\n\t" \ 567 ".section\t.fixup,\"ax\"\n\t" \ 568 "4:\tli\t%1, %3\n\t" \ 569 "j\t3b\n\t" \ 570 ".previous\n\t" \ 571 ".section\t__ex_table,\"a\"\n\t" \ 572 PTR_STR"\t1b, 4b\n\t" \ 573 PTR_STR"\t2b, 4b\n\t" \ 574 ".previous" \ 575 : "=&r" (value), "=r" (res) \ 576 : "r" (addr), "i" (-EFAULT)); \ 577 } while (0) 578 579 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR 580 #define _LoadWU(addr, value, res, type) \ 581 do { \ 582 __asm__ __volatile__ ( \ 583 "1:\t"type##_lwl("%0", "3(%2)")"\n" \ 584 "2:\t"type##_lwr("%0", "(%2)")"\n\t"\ 585 "dsll\t%0, %0, 32\n\t" \ 586 "dsrl\t%0, %0, 32\n\t" \ 587 "li\t%1, 0\n" \ 588 "3:\n\t" \ 589 ".insn\n\t" \ 590 "\t.section\t.fixup,\"ax\"\n\t" \ 591 "4:\tli\t%1, %3\n\t" \ 592 "j\t3b\n\t" \ 593 ".previous\n\t" \ 594 ".section\t__ex_table,\"a\"\n\t" \ 595 PTR_STR"\t1b, 4b\n\t" \ 596 PTR_STR"\t2b, 4b\n\t" \ 597 ".previous" \ 598 : "=&r" (value), "=r" (res) \ 599 : "r" (addr), "i" (-EFAULT)); \ 600 } while (0) 601 602 #define _LoadDW(addr, value, res) \ 603 do { \ 604 __asm__ __volatile__ ( \ 605 "1:\tldl\t%0, 7(%2)\n" \ 606 "2:\tldr\t%0, (%2)\n\t" \ 607 "li\t%1, 0\n" \ 608 "3:\n\t" \ 609 ".insn\n\t" \ 610 "\t.section\t.fixup,\"ax\"\n\t" \ 611 "4:\tli\t%1, %3\n\t" \ 612 "j\t3b\n\t" \ 613 ".previous\n\t" \ 614 ".section\t__ex_table,\"a\"\n\t" \ 615 PTR_STR"\t1b, 4b\n\t" \ 616 PTR_STR"\t2b, 4b\n\t" \ 617 ".previous" \ 618 : "=&r" (value), "=r" (res) \ 619 : "r" (addr), "i" (-EFAULT)); \ 620 } while (0) 621 622 #else /* CONFIG_CPU_NO_LOAD_STORE_LR */ 623 /* For CPUs without lwl and ldl instructions */ 624 #define _LoadWU(addr, value, res, type) \ 625 do { \ 626 __asm__ __volatile__ ( \ 627 ".set\tpush\n\t" \ 628 ".set\tnoat\n\t" \ 629 "1:"type##_lbu("%0", "3(%2)")"\n\t" \ 630 "2:"type##_lbu("$1", "2(%2)")"\n\t" \ 631 "sll\t%0, 0x8\n\t" \ 632 "or\t%0, $1\n\t" \ 633 "3:"type##_lbu("$1", "1(%2)")"\n\t" \ 634 "sll\t%0, 0x8\n\t" \ 635 "or\t%0, $1\n\t" \ 636 "4:"type##_lbu("$1", "0(%2)")"\n\t" \ 637 "sll\t%0, 0x8\n\t" \ 638 "or\t%0, $1\n\t" \ 639 "li\t%1, 0\n" \ 640 ".set\tpop\n" \ 641 "10:\n\t" \ 642 ".insn\n\t" \ 643 ".section\t.fixup,\"ax\"\n\t" \ 644 "11:\tli\t%1, %3\n\t" \ 645 "j\t10b\n\t" \ 646 ".previous\n\t" \ 647 ".section\t__ex_table,\"a\"\n\t" \ 648 PTR_STR"\t1b, 11b\n\t" \ 649 PTR_STR"\t2b, 11b\n\t" \ 650 PTR_STR"\t3b, 11b\n\t" \ 651 PTR_STR"\t4b, 11b\n\t" \ 652 ".previous" \ 653 : "=&r" (value), "=r" (res) \ 654 : "r" (addr), "i" (-EFAULT)); \ 655 } while (0) 656 657 #define _LoadDW(addr, value, res) \ 658 do { \ 659 __asm__ __volatile__ ( \ 660 ".set\tpush\n\t" \ 661 ".set\tnoat\n\t" \ 662 "1:lb\t%0, 7(%2)\n\t" \ 663 "2:lbu\t$1, 6(%2)\n\t" \ 664 "dsll\t%0, 0x8\n\t" \ 665 "or\t%0, $1\n\t" \ 666 "3:lbu\t$1, 5(%2)\n\t" \ 667 "dsll\t%0, 0x8\n\t" \ 668 "or\t%0, $1\n\t" \ 669 "4:lbu\t$1, 4(%2)\n\t" \ 670 "dsll\t%0, 0x8\n\t" \ 671 "or\t%0, $1\n\t" \ 672 "5:lbu\t$1, 3(%2)\n\t" \ 673 "dsll\t%0, 0x8\n\t" \ 674 "or\t%0, $1\n\t" \ 675 "6:lbu\t$1, 2(%2)\n\t" \ 676 "dsll\t%0, 0x8\n\t" \ 677 "or\t%0, $1\n\t" \ 678 "7:lbu\t$1, 1(%2)\n\t" \ 679 "dsll\t%0, 0x8\n\t" \ 680 "or\t%0, $1\n\t" \ 681 "8:lbu\t$1, 0(%2)\n\t" \ 682 "dsll\t%0, 0x8\n\t" \ 683 "or\t%0, $1\n\t" \ 684 "li\t%1, 0\n" \ 685 ".set\tpop\n\t" \ 686 "10:\n\t" \ 687 ".insn\n\t" \ 688 ".section\t.fixup,\"ax\"\n\t" \ 689 "11:\tli\t%1, %3\n\t" \ 690 "j\t10b\n\t" \ 691 ".previous\n\t" \ 692 ".section\t__ex_table,\"a\"\n\t" \ 693 PTR_STR"\t1b, 11b\n\t" \ 694 PTR_STR"\t2b, 11b\n\t" \ 695 PTR_STR"\t3b, 11b\n\t" \ 696 PTR_STR"\t4b, 11b\n\t" \ 697 PTR_STR"\t5b, 11b\n\t" \ 698 PTR_STR"\t6b, 11b\n\t" \ 699 PTR_STR"\t7b, 11b\n\t" \ 700 PTR_STR"\t8b, 11b\n\t" \ 701 ".previous" \ 702 : "=&r" (value), "=r" (res) \ 703 : "r" (addr), "i" (-EFAULT)); \ 704 } while (0) 705 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */ 706 707 #define _StoreHW(addr, value, res, type) \ 708 do { \ 709 __asm__ __volatile__ ( \ 710 ".set\tnoat\n" \ 711 "1:\t"type##_sb("%1", "0(%2)")"\n" \ 712 "srl\t$1,%1, 0x8\n" \ 713 "2:\t"type##_sb("$1", "1(%2)")"\n" \ 714 ".set\tat\n\t" \ 715 "li\t%0, 0\n" \ 716 "3:\n\t" \ 717 ".insn\n\t" \ 718 ".section\t.fixup,\"ax\"\n\t" \ 719 "4:\tli\t%0, %3\n\t" \ 720 "j\t3b\n\t" \ 721 ".previous\n\t" \ 722 ".section\t__ex_table,\"a\"\n\t" \ 723 PTR_STR"\t1b, 4b\n\t" \ 724 PTR_STR"\t2b, 4b\n\t" \ 725 ".previous" \ 726 : "=r" (res) \ 727 : "r" (value), "r" (addr), "i" (-EFAULT));\ 728 } while (0) 729 730 #ifndef CONFIG_CPU_NO_LOAD_STORE_LR 731 #define _StoreW(addr, value, res, type) \ 732 do { \ 733 __asm__ __volatile__ ( \ 734 "1:\t"type##_swl("%1", "3(%2)")"\n" \ 735 "2:\t"type##_swr("%1", "(%2)")"\n\t"\ 736 "li\t%0, 0\n" \ 737 "3:\n\t" \ 738 ".insn\n\t" \ 739 ".section\t.fixup,\"ax\"\n\t" \ 740 "4:\tli\t%0, %3\n\t" \ 741 "j\t3b\n\t" \ 742 ".previous\n\t" \ 743 ".section\t__ex_table,\"a\"\n\t" \ 744 PTR_STR"\t1b, 4b\n\t" \ 745 PTR_STR"\t2b, 4b\n\t" \ 746 ".previous" \ 747 : "=r" (res) \ 748 : "r" (value), "r" (addr), "i" (-EFAULT)); \ 749 } while (0) 750 751 #define _StoreDW(addr, value, res) \ 752 do { \ 753 __asm__ __volatile__ ( \ 754 "1:\tsdl\t%1, 7(%2)\n" \ 755 "2:\tsdr\t%1, (%2)\n\t" \ 756 "li\t%0, 0\n" \ 757 "3:\n\t" \ 758 ".insn\n\t" \ 759 ".section\t.fixup,\"ax\"\n\t" \ 760 "4:\tli\t%0, %3\n\t" \ 761 "j\t3b\n\t" \ 762 ".previous\n\t" \ 763 ".section\t__ex_table,\"a\"\n\t" \ 764 PTR_STR"\t1b, 4b\n\t" \ 765 PTR_STR"\t2b, 4b\n\t" \ 766 ".previous" \ 767 : "=r" (res) \ 768 : "r" (value), "r" (addr), "i" (-EFAULT)); \ 769 } while (0) 770 771 #else /* CONFIG_CPU_NO_LOAD_STORE_LR */ 772 /* For CPUs without swl and sdl instructions */ 773 #define _StoreW(addr, value, res, type) \ 774 do { \ 775 __asm__ __volatile__ ( \ 776 ".set\tpush\n\t" \ 777 ".set\tnoat\n\t" \ 778 "1:"type##_sb("%1", "0(%2)")"\n\t" \ 779 "srl\t$1, %1, 0x8\n\t" \ 780 "2:"type##_sb("$1", "1(%2)")"\n\t" \ 781 "srl\t$1, $1, 0x8\n\t" \ 782 "3:"type##_sb("$1", "2(%2)")"\n\t" \ 783 "srl\t$1, $1, 0x8\n\t" \ 784 "4:"type##_sb("$1", "3(%2)")"\n\t" \ 785 ".set\tpop\n\t" \ 786 "li\t%0, 0\n" \ 787 "10:\n\t" \ 788 ".insn\n\t" \ 789 ".section\t.fixup,\"ax\"\n\t" \ 790 "11:\tli\t%0, %3\n\t" \ 791 "j\t10b\n\t" \ 792 ".previous\n\t" \ 793 ".section\t__ex_table,\"a\"\n\t" \ 794 PTR_STR"\t1b, 11b\n\t" \ 795 PTR_STR"\t2b, 11b\n\t" \ 796 PTR_STR"\t3b, 11b\n\t" \ 797 PTR_STR"\t4b, 11b\n\t" \ 798 ".previous" \ 799 : "=&r" (res) \ 800 : "r" (value), "r" (addr), "i" (-EFAULT) \ 801 : "memory"); \ 802 } while (0) 803 804 #define _StoreDW(addr, value, res) \ 805 do { \ 806 __asm__ __volatile__ ( \ 807 ".set\tpush\n\t" \ 808 ".set\tnoat\n\t" \ 809 "1:sb\t%1, 0(%2)\n\t" \ 810 "dsrl\t$1, %1, 0x8\n\t" \ 811 "2:sb\t$1, 1(%2)\n\t" \ 812 "dsrl\t$1, $1, 0x8\n\t" \ 813 "3:sb\t$1, 2(%2)\n\t" \ 814 "dsrl\t$1, $1, 0x8\n\t" \ 815 "4:sb\t$1, 3(%2)\n\t" \ 816 "dsrl\t$1, $1, 0x8\n\t" \ 817 "5:sb\t$1, 4(%2)\n\t" \ 818 "dsrl\t$1, $1, 0x8\n\t" \ 819 "6:sb\t$1, 5(%2)\n\t" \ 820 "dsrl\t$1, $1, 0x8\n\t" \ 821 "7:sb\t$1, 6(%2)\n\t" \ 822 "dsrl\t$1, $1, 0x8\n\t" \ 823 "8:sb\t$1, 7(%2)\n\t" \ 824 "dsrl\t$1, $1, 0x8\n\t" \ 825 ".set\tpop\n\t" \ 826 "li\t%0, 0\n" \ 827 "10:\n\t" \ 828 ".insn\n\t" \ 829 ".section\t.fixup,\"ax\"\n\t" \ 830 "11:\tli\t%0, %3\n\t" \ 831 "j\t10b\n\t" \ 832 ".previous\n\t" \ 833 ".section\t__ex_table,\"a\"\n\t" \ 834 PTR_STR"\t1b, 11b\n\t" \ 835 PTR_STR"\t2b, 11b\n\t" \ 836 PTR_STR"\t3b, 11b\n\t" \ 837 PTR_STR"\t4b, 11b\n\t" \ 838 PTR_STR"\t5b, 11b\n\t" \ 839 PTR_STR"\t6b, 11b\n\t" \ 840 PTR_STR"\t7b, 11b\n\t" \ 841 PTR_STR"\t8b, 11b\n\t" \ 842 ".previous" \ 843 : "=&r" (res) \ 844 : "r" (value), "r" (addr), "i" (-EFAULT) \ 845 : "memory"); \ 846 } while (0) 847 848 #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */ 849 #endif 850 851 #define LoadHWU(addr, value, res) _LoadHWU(addr, value, res, kernel) 852 #define LoadHWUE(addr, value, res) _LoadHWU(addr, value, res, user) 853 #define LoadWU(addr, value, res) _LoadWU(addr, value, res, kernel) 854 #define LoadWUE(addr, value, res) _LoadWU(addr, value, res, user) 855 #define LoadHW(addr, value, res) _LoadHW(addr, value, res, kernel) 856 #define LoadHWE(addr, value, res) _LoadHW(addr, value, res, user) 857 #define LoadW(addr, value, res) _LoadW(addr, value, res, kernel) 858 #define LoadWE(addr, value, res) _LoadW(addr, value, res, user) 859 #define LoadDW(addr, value, res) _LoadDW(addr, value, res) 860 861 #define StoreHW(addr, value, res) _StoreHW(addr, value, res, kernel) 862 #define StoreHWE(addr, value, res) _StoreHW(addr, value, res, user) 863 #define StoreW(addr, value, res) _StoreW(addr, value, res, kernel) 864 #define StoreWE(addr, value, res) _StoreW(addr, value, res, user) 865 #define StoreDW(addr, value, res) _StoreDW(addr, value, res) 866 867 #endif /* _ASM_INST_H */ 868