mirror of https://gitee.com/openkylin/linux.git
MIPS: Move unaligned load/store helpers to inst.h
Move unaligned load/store helpers from unaligned.c to inst.h, then other parts of the kernel can use these helpers. Use __ASSEMBLY__ to guard the definition of "LONG" in asm.h to avoid build error on IPxx platforms. Signed-off-by: Huacai Chen <chenhc@lemote.com> Signed-off-by: Pei Huang <huangpei@loongson.cn> Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
This commit is contained in:
parent
c05b5940d9
commit
d339cd02b8
|
@ -202,7 +202,9 @@ symbol = value
|
||||||
#define LONG_SRA sra
|
#define LONG_SRA sra
|
||||||
#define LONG_SRAV srav
|
#define LONG_SRAV srav
|
||||||
|
|
||||||
|
#ifdef __ASSEMBLY__
|
||||||
#define LONG .word
|
#define LONG .word
|
||||||
|
#endif
|
||||||
#define LONGSIZE 4
|
#define LONGSIZE 4
|
||||||
#define LONGMASK 3
|
#define LONGMASK 3
|
||||||
#define LONGLOG 2
|
#define LONGLOG 2
|
||||||
|
@ -225,7 +227,9 @@ symbol = value
|
||||||
#define LONG_SRA dsra
|
#define LONG_SRA dsra
|
||||||
#define LONG_SRAV dsrav
|
#define LONG_SRAV dsrav
|
||||||
|
|
||||||
|
#ifdef __ASSEMBLY__
|
||||||
#define LONG .dword
|
#define LONG .dword
|
||||||
|
#endif
|
||||||
#define LONGSIZE 8
|
#define LONGSIZE 8
|
||||||
#define LONGMASK 7
|
#define LONGMASK 7
|
||||||
#define LONGLOG 3
|
#define LONGLOG 3
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#ifndef _ASM_INST_H
|
#ifndef _ASM_INST_H
|
||||||
#define _ASM_INST_H
|
#define _ASM_INST_H
|
||||||
|
|
||||||
|
#include <asm/asm.h>
|
||||||
#include <uapi/asm/inst.h>
|
#include <uapi/asm/inst.h>
|
||||||
|
|
||||||
/* HACHACHAHCAHC ... */
|
/* HACHACHAHCAHC ... */
|
||||||
|
@ -85,4 +86,776 @@ struct mm_decoded_insn {
|
||||||
/* Recode table from 16-bit register notation to 32-bit GPR. Do NOT export!!! */
|
/* Recode table from 16-bit register notation to 32-bit GPR. Do NOT export!!! */
|
||||||
extern const int reg16to32[];
|
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 */
|
#endif /* _ASM_INST_H */
|
||||||
|
|
|
@ -92,9 +92,6 @@
|
||||||
#include <asm/mmu_context.h>
|
#include <asm/mmu_context.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
#define STR(x) __STR(x)
|
|
||||||
#define __STR(x) #x
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
UNALIGNED_ACTION_QUIET,
|
UNALIGNED_ACTION_QUIET,
|
||||||
UNALIGNED_ACTION_SIGNAL,
|
UNALIGNED_ACTION_SIGNAL,
|
||||||
|
@ -108,778 +105,6 @@ static u32 unaligned_action;
|
||||||
#endif
|
#endif
|
||||||
extern void show_registers(struct pt_regs *regs);
|
extern void show_registers(struct pt_regs *regs);
|
||||||
|
|
||||||
#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)
|
|
||||||
|
|
||||||
static void emulate_load_store_insn(struct pt_regs *regs,
|
static void emulate_load_store_insn(struct pt_regs *regs,
|
||||||
void __user *addr, unsigned int __user *pc)
|
void __user *addr, unsigned int __user *pc)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue