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