/* * Format of an instruction in memory. * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1996, 2000 by Ralf Baechle * Copyright (C) 2006 by Thiemo Seufer */ #ifndef _ASM_INST_H #define _ASM_INST_H #include #include /* HACHACHAHCAHC ... */ /* In case some other massaging is needed, keep MIPSInst as wrapper */ #define MIPSInst(x) x #define I_OPCODE_SFT 26 #define MIPSInst_OPCODE(x) (MIPSInst(x) >> I_OPCODE_SFT) #define I_JTARGET_SFT 0 #define MIPSInst_JTARGET(x) (MIPSInst(x) & 0x03ffffff) #define I_RS_SFT 21 #define MIPSInst_RS(x) ((MIPSInst(x) & 0x03e00000) >> I_RS_SFT) #define I_RT_SFT 16 #define MIPSInst_RT(x) ((MIPSInst(x) & 0x001f0000) >> I_RT_SFT) #define I_IMM_SFT 0 #define MIPSInst_SIMM(x) ((int)((short)(MIPSInst(x) & 0xffff))) #define MIPSInst_UIMM(x) (MIPSInst(x) & 0xffff) #define I_CACHEOP_SFT 18 #define MIPSInst_CACHEOP(x) ((MIPSInst(x) & 0x001c0000) >> I_CACHEOP_SFT) #define I_CACHESEL_SFT 16 #define MIPSInst_CACHESEL(x) ((MIPSInst(x) & 0x00030000) >> I_CACHESEL_SFT) #define I_RD_SFT 11 #define MIPSInst_RD(x) ((MIPSInst(x) & 0x0000f800) >> I_RD_SFT) #define I_RE_SFT 6 #define MIPSInst_RE(x) ((MIPSInst(x) & 0x000007c0) >> I_RE_SFT) #define I_FUNC_SFT 0 #define MIPSInst_FUNC(x) (MIPSInst(x) & 0x0000003f) #define I_FFMT_SFT 21 #define MIPSInst_FFMT(x) ((MIPSInst(x) & 0x01e00000) >> I_FFMT_SFT) #define I_FT_SFT 16 #define MIPSInst_FT(x) ((MIPSInst(x) & 0x001f0000) >> I_FT_SFT) #define I_FS_SFT 11 #define MIPSInst_FS(x) ((MIPSInst(x) & 0x0000f800) >> I_FS_SFT) #define I_FD_SFT 6 #define MIPSInst_FD(x) ((MIPSInst(x) & 0x000007c0) >> I_FD_SFT) #define I_FR_SFT 21 #define MIPSInst_FR(x) ((MIPSInst(x) & 0x03e00000) >> I_FR_SFT) #define I_FMA_FUNC_SFT 2 #define MIPSInst_FMA_FUNC(x) ((MIPSInst(x) & 0x0000003c) >> I_FMA_FUNC_SFT) #define I_FMA_FFMT_SFT 0 #define MIPSInst_FMA_FFMT(x) (MIPSInst(x) & 0x00000003) typedef unsigned int mips_instruction; /* microMIPS instruction decode structure. Do NOT export!!! */ struct mm_decoded_insn { mips_instruction insn; mips_instruction next_insn; int pc_inc; int next_pc_inc; int micro_mips_mode; }; /* Recode table from 16-bit register notation to 32-bit GPR. Do NOT export!!! */ extern const int reg16to32[]; #ifdef __BIG_ENDIAN #define _LoadHW(addr, value, res, type) \ do { \ __asm__ __volatile__ (".set\tnoat\n" \ "1:\t"type##_lb("%0", "0(%2)")"\n" \ "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \ "3:\t.set\tat\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "4:\tli\t%1, %3\n\t" \ "j\t3b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 4b\n\t" \ STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); \ } while (0) #ifndef CONFIG_CPU_NO_LOAD_STORE_LR #define _LoadW(addr, value, res, type) \ do { \ __asm__ __volatile__ ( \ "1:\t"type##_lwl("%0", "(%2)")"\n" \ "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\ "li\t%1, 0\n" \ "3:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "4:\tli\t%1, %3\n\t" \ "j\t3b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 4b\n\t" \ STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); \ } while (0) #else /* CONFIG_CPU_NO_LOAD_STORE_LR */ /* For CPUs without lwl instruction */ #define _LoadW(addr, value, res, type) \ do { \ __asm__ __volatile__ ( \ ".set\tpush\n" \ ".set\tnoat\n\t" \ "1:"type##_lb("%0", "0(%2)")"\n\t" \ "2:"type##_lbu("$1", "1(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "3:"type##_lbu("$1", "2(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "4:"type##_lbu("$1", "3(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \ ".set\tpop\n" \ "10:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "11:\tli\t%1, %3\n\t" \ "j\t10b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 11b\n\t" \ STR(PTR)"\t2b, 11b\n\t" \ STR(PTR)"\t3b, 11b\n\t" \ STR(PTR)"\t4b, 11b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); \ } while (0) #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */ #define _LoadHWU(addr, value, res, type) \ do { \ __asm__ __volatile__ ( \ ".set\tnoat\n" \ "1:\t"type##_lbu("%0", "0(%2)")"\n" \ "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \ "3:\n\t" \ ".insn\n\t" \ ".set\tat\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "4:\tli\t%1, %3\n\t" \ "j\t3b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 4b\n\t" \ STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); \ } while (0) #ifndef CONFIG_CPU_NO_LOAD_STORE_LR #define _LoadWU(addr, value, res, type) \ do { \ __asm__ __volatile__ ( \ "1:\t"type##_lwl("%0", "(%2)")"\n" \ "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\ "dsll\t%0, %0, 32\n\t" \ "dsrl\t%0, %0, 32\n\t" \ "li\t%1, 0\n" \ "3:\n\t" \ ".insn\n\t" \ "\t.section\t.fixup,\"ax\"\n\t" \ "4:\tli\t%1, %3\n\t" \ "j\t3b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 4b\n\t" \ STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); \ } while (0) #define _LoadDW(addr, value, res) \ do { \ __asm__ __volatile__ ( \ "1:\tldl\t%0, (%2)\n" \ "2:\tldr\t%0, 7(%2)\n\t" \ "li\t%1, 0\n" \ "3:\n\t" \ ".insn\n\t" \ "\t.section\t.fixup,\"ax\"\n\t" \ "4:\tli\t%1, %3\n\t" \ "j\t3b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 4b\n\t" \ STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); \ } while (0) #else /* CONFIG_CPU_NO_LOAD_STORE_LR */ /* For CPUs without lwl and ldl instructions */ #define _LoadWU(addr, value, res, type) \ do { \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \ "1:"type##_lbu("%0", "0(%2)")"\n\t" \ "2:"type##_lbu("$1", "1(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "3:"type##_lbu("$1", "2(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "4:"type##_lbu("$1", "3(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \ ".set\tpop\n" \ "10:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "11:\tli\t%1, %3\n\t" \ "j\t10b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 11b\n\t" \ STR(PTR)"\t2b, 11b\n\t" \ STR(PTR)"\t3b, 11b\n\t" \ STR(PTR)"\t4b, 11b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); \ } while (0) #define _LoadDW(addr, value, res) \ do { \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \ "1:lb\t%0, 0(%2)\n\t" \ "2:lbu\t $1, 1(%2)\n\t" \ "dsll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "3:lbu\t$1, 2(%2)\n\t" \ "dsll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "4:lbu\t$1, 3(%2)\n\t" \ "dsll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "5:lbu\t$1, 4(%2)\n\t" \ "dsll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "6:lbu\t$1, 5(%2)\n\t" \ "dsll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "7:lbu\t$1, 6(%2)\n\t" \ "dsll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "8:lbu\t$1, 7(%2)\n\t" \ "dsll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \ ".set\tpop\n\t" \ "10:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "11:\tli\t%1, %3\n\t" \ "j\t10b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 11b\n\t" \ STR(PTR)"\t2b, 11b\n\t" \ STR(PTR)"\t3b, 11b\n\t" \ STR(PTR)"\t4b, 11b\n\t" \ STR(PTR)"\t5b, 11b\n\t" \ STR(PTR)"\t6b, 11b\n\t" \ STR(PTR)"\t7b, 11b\n\t" \ STR(PTR)"\t8b, 11b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); \ } while (0) #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */ #define _StoreHW(addr, value, res, type) \ do { \ __asm__ __volatile__ ( \ ".set\tnoat\n" \ "1:\t"type##_sb("%1", "1(%2)")"\n" \ "srl\t$1, %1, 0x8\n" \ "2:\t"type##_sb("$1", "0(%2)")"\n" \ ".set\tat\n\t" \ "li\t%0, 0\n" \ "3:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "4:\tli\t%0, %3\n\t" \ "j\t3b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 4b\n\t" \ STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=r" (res) \ : "r" (value), "r" (addr), "i" (-EFAULT));\ } while (0) #ifndef CONFIG_CPU_NO_LOAD_STORE_LR #define _StoreW(addr, value, res, type) \ do { \ __asm__ __volatile__ ( \ "1:\t"type##_swl("%1", "(%2)")"\n" \ "2:\t"type##_swr("%1", "3(%2)")"\n\t"\ "li\t%0, 0\n" \ "3:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "4:\tli\t%0, %3\n\t" \ "j\t3b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 4b\n\t" \ STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=r" (res) \ : "r" (value), "r" (addr), "i" (-EFAULT)); \ } while (0) #define _StoreDW(addr, value, res) \ do { \ __asm__ __volatile__ ( \ "1:\tsdl\t%1,(%2)\n" \ "2:\tsdr\t%1, 7(%2)\n\t" \ "li\t%0, 0\n" \ "3:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "4:\tli\t%0, %3\n\t" \ "j\t3b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 4b\n\t" \ STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=r" (res) \ : "r" (value), "r" (addr), "i" (-EFAULT)); \ } while (0) #else /* CONFIG_CPU_NO_LOAD_STORE_LR */ #define _StoreW(addr, value, res, type) \ do { \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \ "1:"type##_sb("%1", "3(%2)")"\n\t" \ "srl\t$1, %1, 0x8\n\t" \ "2:"type##_sb("$1", "2(%2)")"\n\t" \ "srl\t$1, $1, 0x8\n\t" \ "3:"type##_sb("$1", "1(%2)")"\n\t" \ "srl\t$1, $1, 0x8\n\t" \ "4:"type##_sb("$1", "0(%2)")"\n\t" \ ".set\tpop\n\t" \ "li\t%0, 0\n" \ "10:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "11:\tli\t%0, %3\n\t" \ "j\t10b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 11b\n\t" \ STR(PTR)"\t2b, 11b\n\t" \ STR(PTR)"\t3b, 11b\n\t" \ STR(PTR)"\t4b, 11b\n\t" \ ".previous" \ : "=&r" (res) \ : "r" (value), "r" (addr), "i" (-EFAULT) \ : "memory"); \ } while (0) #define _StoreDW(addr, value, res) \ do { \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \ "1:sb\t%1, 7(%2)\n\t" \ "dsrl\t$1, %1, 0x8\n\t" \ "2:sb\t$1, 6(%2)\n\t" \ "dsrl\t$1, $1, 0x8\n\t" \ "3:sb\t$1, 5(%2)\n\t" \ "dsrl\t$1, $1, 0x8\n\t" \ "4:sb\t$1, 4(%2)\n\t" \ "dsrl\t$1, $1, 0x8\n\t" \ "5:sb\t$1, 3(%2)\n\t" \ "dsrl\t$1, $1, 0x8\n\t" \ "6:sb\t$1, 2(%2)\n\t" \ "dsrl\t$1, $1, 0x8\n\t" \ "7:sb\t$1, 1(%2)\n\t" \ "dsrl\t$1, $1, 0x8\n\t" \ "8:sb\t$1, 0(%2)\n\t" \ "dsrl\t$1, $1, 0x8\n\t" \ ".set\tpop\n\t" \ "li\t%0, 0\n" \ "10:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "11:\tli\t%0, %3\n\t" \ "j\t10b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 11b\n\t" \ STR(PTR)"\t2b, 11b\n\t" \ STR(PTR)"\t3b, 11b\n\t" \ STR(PTR)"\t4b, 11b\n\t" \ STR(PTR)"\t5b, 11b\n\t" \ STR(PTR)"\t6b, 11b\n\t" \ STR(PTR)"\t7b, 11b\n\t" \ STR(PTR)"\t8b, 11b\n\t" \ ".previous" \ : "=&r" (res) \ : "r" (value), "r" (addr), "i" (-EFAULT) \ : "memory"); \ } while (0) #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */ #else /* __BIG_ENDIAN */ #define _LoadHW(addr, value, res, type) \ do { \ __asm__ __volatile__ (".set\tnoat\n" \ "1:\t"type##_lb("%0", "1(%2)")"\n" \ "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \ "3:\t.set\tat\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "4:\tli\t%1, %3\n\t" \ "j\t3b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 4b\n\t" \ STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); \ } while (0) #ifndef CONFIG_CPU_NO_LOAD_STORE_LR #define _LoadW(addr, value, res, type) \ do { \ __asm__ __volatile__ ( \ "1:\t"type##_lwl("%0", "3(%2)")"\n" \ "2:\t"type##_lwr("%0", "(%2)")"\n\t"\ "li\t%1, 0\n" \ "3:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "4:\tli\t%1, %3\n\t" \ "j\t3b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 4b\n\t" \ STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); \ } while (0) #else /* CONFIG_CPU_NO_LOAD_STORE_LR */ /* For CPUs without lwl instruction */ #define _LoadW(addr, value, res, type) \ do { \ __asm__ __volatile__ ( \ ".set\tpush\n" \ ".set\tnoat\n\t" \ "1:"type##_lb("%0", "3(%2)")"\n\t" \ "2:"type##_lbu("$1", "2(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "3:"type##_lbu("$1", "1(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "4:"type##_lbu("$1", "0(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \ ".set\tpop\n" \ "10:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "11:\tli\t%1, %3\n\t" \ "j\t10b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 11b\n\t" \ STR(PTR)"\t2b, 11b\n\t" \ STR(PTR)"\t3b, 11b\n\t" \ STR(PTR)"\t4b, 11b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); \ } while (0) #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */ #define _LoadHWU(addr, value, res, type) \ do { \ __asm__ __volatile__ ( \ ".set\tnoat\n" \ "1:\t"type##_lbu("%0", "1(%2)")"\n" \ "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \ "3:\n\t" \ ".insn\n\t" \ ".set\tat\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "4:\tli\t%1, %3\n\t" \ "j\t3b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 4b\n\t" \ STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); \ } while (0) #ifndef CONFIG_CPU_NO_LOAD_STORE_LR #define _LoadWU(addr, value, res, type) \ do { \ __asm__ __volatile__ ( \ "1:\t"type##_lwl("%0", "3(%2)")"\n" \ "2:\t"type##_lwr("%0", "(%2)")"\n\t"\ "dsll\t%0, %0, 32\n\t" \ "dsrl\t%0, %0, 32\n\t" \ "li\t%1, 0\n" \ "3:\n\t" \ ".insn\n\t" \ "\t.section\t.fixup,\"ax\"\n\t" \ "4:\tli\t%1, %3\n\t" \ "j\t3b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 4b\n\t" \ STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); \ } while (0) #define _LoadDW(addr, value, res) \ do { \ __asm__ __volatile__ ( \ "1:\tldl\t%0, 7(%2)\n" \ "2:\tldr\t%0, (%2)\n\t" \ "li\t%1, 0\n" \ "3:\n\t" \ ".insn\n\t" \ "\t.section\t.fixup,\"ax\"\n\t" \ "4:\tli\t%1, %3\n\t" \ "j\t3b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 4b\n\t" \ STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); \ } while (0) #else /* CONFIG_CPU_NO_LOAD_STORE_LR */ /* For CPUs without lwl and ldl instructions */ #define _LoadWU(addr, value, res, type) \ do { \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \ "1:"type##_lbu("%0", "3(%2)")"\n\t" \ "2:"type##_lbu("$1", "2(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "3:"type##_lbu("$1", "1(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "4:"type##_lbu("$1", "0(%2)")"\n\t" \ "sll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \ ".set\tpop\n" \ "10:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "11:\tli\t%1, %3\n\t" \ "j\t10b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 11b\n\t" \ STR(PTR)"\t2b, 11b\n\t" \ STR(PTR)"\t3b, 11b\n\t" \ STR(PTR)"\t4b, 11b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); \ } while (0) #define _LoadDW(addr, value, res) \ do { \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \ "1:lb\t%0, 7(%2)\n\t" \ "2:lbu\t$1, 6(%2)\n\t" \ "dsll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "3:lbu\t$1, 5(%2)\n\t" \ "dsll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "4:lbu\t$1, 4(%2)\n\t" \ "dsll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "5:lbu\t$1, 3(%2)\n\t" \ "dsll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "6:lbu\t$1, 2(%2)\n\t" \ "dsll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "7:lbu\t$1, 1(%2)\n\t" \ "dsll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "8:lbu\t$1, 0(%2)\n\t" \ "dsll\t%0, 0x8\n\t" \ "or\t%0, $1\n\t" \ "li\t%1, 0\n" \ ".set\tpop\n\t" \ "10:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "11:\tli\t%1, %3\n\t" \ "j\t10b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 11b\n\t" \ STR(PTR)"\t2b, 11b\n\t" \ STR(PTR)"\t3b, 11b\n\t" \ STR(PTR)"\t4b, 11b\n\t" \ STR(PTR)"\t5b, 11b\n\t" \ STR(PTR)"\t6b, 11b\n\t" \ STR(PTR)"\t7b, 11b\n\t" \ STR(PTR)"\t8b, 11b\n\t" \ ".previous" \ : "=&r" (value), "=r" (res) \ : "r" (addr), "i" (-EFAULT)); \ } while (0) #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */ #define _StoreHW(addr, value, res, type) \ do { \ __asm__ __volatile__ ( \ ".set\tnoat\n" \ "1:\t"type##_sb("%1", "0(%2)")"\n" \ "srl\t$1,%1, 0x8\n" \ "2:\t"type##_sb("$1", "1(%2)")"\n" \ ".set\tat\n\t" \ "li\t%0, 0\n" \ "3:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "4:\tli\t%0, %3\n\t" \ "j\t3b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 4b\n\t" \ STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=r" (res) \ : "r" (value), "r" (addr), "i" (-EFAULT));\ } while (0) #ifndef CONFIG_CPU_NO_LOAD_STORE_LR #define _StoreW(addr, value, res, type) \ do { \ __asm__ __volatile__ ( \ "1:\t"type##_swl("%1", "3(%2)")"\n" \ "2:\t"type##_swr("%1", "(%2)")"\n\t"\ "li\t%0, 0\n" \ "3:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "4:\tli\t%0, %3\n\t" \ "j\t3b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 4b\n\t" \ STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=r" (res) \ : "r" (value), "r" (addr), "i" (-EFAULT)); \ } while (0) #define _StoreDW(addr, value, res) \ do { \ __asm__ __volatile__ ( \ "1:\tsdl\t%1, 7(%2)\n" \ "2:\tsdr\t%1, (%2)\n\t" \ "li\t%0, 0\n" \ "3:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "4:\tli\t%0, %3\n\t" \ "j\t3b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 4b\n\t" \ STR(PTR)"\t2b, 4b\n\t" \ ".previous" \ : "=r" (res) \ : "r" (value), "r" (addr), "i" (-EFAULT)); \ } while (0) #else /* CONFIG_CPU_NO_LOAD_STORE_LR */ /* For CPUs without swl and sdl instructions */ #define _StoreW(addr, value, res, type) \ do { \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \ "1:"type##_sb("%1", "0(%2)")"\n\t" \ "srl\t$1, %1, 0x8\n\t" \ "2:"type##_sb("$1", "1(%2)")"\n\t" \ "srl\t$1, $1, 0x8\n\t" \ "3:"type##_sb("$1", "2(%2)")"\n\t" \ "srl\t$1, $1, 0x8\n\t" \ "4:"type##_sb("$1", "3(%2)")"\n\t" \ ".set\tpop\n\t" \ "li\t%0, 0\n" \ "10:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "11:\tli\t%0, %3\n\t" \ "j\t10b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 11b\n\t" \ STR(PTR)"\t2b, 11b\n\t" \ STR(PTR)"\t3b, 11b\n\t" \ STR(PTR)"\t4b, 11b\n\t" \ ".previous" \ : "=&r" (res) \ : "r" (value), "r" (addr), "i" (-EFAULT) \ : "memory"); \ } while (0) #define _StoreDW(addr, value, res) \ do { \ __asm__ __volatile__ ( \ ".set\tpush\n\t" \ ".set\tnoat\n\t" \ "1:sb\t%1, 0(%2)\n\t" \ "dsrl\t$1, %1, 0x8\n\t" \ "2:sb\t$1, 1(%2)\n\t" \ "dsrl\t$1, $1, 0x8\n\t" \ "3:sb\t$1, 2(%2)\n\t" \ "dsrl\t$1, $1, 0x8\n\t" \ "4:sb\t$1, 3(%2)\n\t" \ "dsrl\t$1, $1, 0x8\n\t" \ "5:sb\t$1, 4(%2)\n\t" \ "dsrl\t$1, $1, 0x8\n\t" \ "6:sb\t$1, 5(%2)\n\t" \ "dsrl\t$1, $1, 0x8\n\t" \ "7:sb\t$1, 6(%2)\n\t" \ "dsrl\t$1, $1, 0x8\n\t" \ "8:sb\t$1, 7(%2)\n\t" \ "dsrl\t$1, $1, 0x8\n\t" \ ".set\tpop\n\t" \ "li\t%0, 0\n" \ "10:\n\t" \ ".insn\n\t" \ ".section\t.fixup,\"ax\"\n\t" \ "11:\tli\t%0, %3\n\t" \ "j\t10b\n\t" \ ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b, 11b\n\t" \ STR(PTR)"\t2b, 11b\n\t" \ STR(PTR)"\t3b, 11b\n\t" \ STR(PTR)"\t4b, 11b\n\t" \ STR(PTR)"\t5b, 11b\n\t" \ STR(PTR)"\t6b, 11b\n\t" \ STR(PTR)"\t7b, 11b\n\t" \ STR(PTR)"\t8b, 11b\n\t" \ ".previous" \ : "=&r" (res) \ : "r" (value), "r" (addr), "i" (-EFAULT) \ : "memory"); \ } while (0) #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */ #endif #define LoadHWU(addr, value, res) _LoadHWU(addr, value, res, kernel) #define LoadHWUE(addr, value, res) _LoadHWU(addr, value, res, user) #define LoadWU(addr, value, res) _LoadWU(addr, value, res, kernel) #define LoadWUE(addr, value, res) _LoadWU(addr, value, res, user) #define LoadHW(addr, value, res) _LoadHW(addr, value, res, kernel) #define LoadHWE(addr, value, res) _LoadHW(addr, value, res, user) #define LoadW(addr, value, res) _LoadW(addr, value, res, kernel) #define LoadWE(addr, value, res) _LoadW(addr, value, res, user) #define LoadDW(addr, value, res) _LoadDW(addr, value, res) #define StoreHW(addr, value, res) _StoreHW(addr, value, res, kernel) #define StoreHWE(addr, value, res) _StoreHW(addr, value, res, user) #define StoreW(addr, value, res) _StoreW(addr, value, res, kernel) #define StoreWE(addr, value, res) _StoreW(addr, value, res, user) #define StoreDW(addr, value, res) _StoreDW(addr, value, res) #endif /* _ASM_INST_H */