xref: /OK3568_Linux_fs/kernel/arch/mips/include/asm/unaligned-emul.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun #ifndef _ASM_MIPS_UNALIGNED_EMUL_H
3*4882a593Smuzhiyun #define _ASM_MIPS_UNALIGNED_EMUL_H
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include <asm/asm.h>
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #ifdef __BIG_ENDIAN
8*4882a593Smuzhiyun #define  _LoadHW(addr, value, res, type)  \
9*4882a593Smuzhiyun do {                                                \
10*4882a593Smuzhiyun 	__asm__ __volatile__ (".set\tnoat\n"        \
11*4882a593Smuzhiyun 		"1:\t"type##_lb("%0", "0(%2)")"\n"  \
12*4882a593Smuzhiyun 		"2:\t"type##_lbu("$1", "1(%2)")"\n\t"\
13*4882a593Smuzhiyun 		"sll\t%0, 0x8\n\t"                  \
14*4882a593Smuzhiyun 		"or\t%0, $1\n\t"                    \
15*4882a593Smuzhiyun 		"li\t%1, 0\n"                       \
16*4882a593Smuzhiyun 		"3:\t.set\tat\n\t"                  \
17*4882a593Smuzhiyun 		".insn\n\t"                         \
18*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"       \
19*4882a593Smuzhiyun 		"4:\tli\t%1, %3\n\t"                \
20*4882a593Smuzhiyun 		"j\t3b\n\t"                         \
21*4882a593Smuzhiyun 		".previous\n\t"                     \
22*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
23*4882a593Smuzhiyun 		STR(PTR)"\t1b, 4b\n\t"               \
24*4882a593Smuzhiyun 		STR(PTR)"\t2b, 4b\n\t"               \
25*4882a593Smuzhiyun 		".previous"                         \
26*4882a593Smuzhiyun 		: "=&r" (value), "=r" (res)         \
27*4882a593Smuzhiyun 		: "r" (addr), "i" (-EFAULT));       \
28*4882a593Smuzhiyun } while (0)
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
31*4882a593Smuzhiyun #define  _LoadW(addr, value, res, type)   \
32*4882a593Smuzhiyun do {                                                \
33*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
34*4882a593Smuzhiyun 		"1:\t"type##_lwl("%0", "(%2)")"\n"   \
35*4882a593Smuzhiyun 		"2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
36*4882a593Smuzhiyun 		"li\t%1, 0\n"                       \
37*4882a593Smuzhiyun 		"3:\n\t"                            \
38*4882a593Smuzhiyun 		".insn\n\t"                         \
39*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"       \
40*4882a593Smuzhiyun 		"4:\tli\t%1, %3\n\t"                \
41*4882a593Smuzhiyun 		"j\t3b\n\t"                         \
42*4882a593Smuzhiyun 		".previous\n\t"                     \
43*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
44*4882a593Smuzhiyun 		STR(PTR)"\t1b, 4b\n\t"               \
45*4882a593Smuzhiyun 		STR(PTR)"\t2b, 4b\n\t"               \
46*4882a593Smuzhiyun 		".previous"                         \
47*4882a593Smuzhiyun 		: "=&r" (value), "=r" (res)         \
48*4882a593Smuzhiyun 		: "r" (addr), "i" (-EFAULT));       \
49*4882a593Smuzhiyun } while (0)
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun #else /* CONFIG_CPU_NO_LOAD_STORE_LR */
52*4882a593Smuzhiyun /* For CPUs without lwl instruction */
53*4882a593Smuzhiyun #define  _LoadW(addr, value, res, type) \
54*4882a593Smuzhiyun do {                                                \
55*4882a593Smuzhiyun 	__asm__ __volatile__ (			    \
56*4882a593Smuzhiyun 		".set\tpush\n"			    \
57*4882a593Smuzhiyun 		".set\tnoat\n\t"		    \
58*4882a593Smuzhiyun 		"1:"type##_lb("%0", "0(%2)")"\n\t"  \
59*4882a593Smuzhiyun 		"2:"type##_lbu("$1", "1(%2)")"\n\t" \
60*4882a593Smuzhiyun 		"sll\t%0, 0x8\n\t"		    \
61*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
62*4882a593Smuzhiyun 		"3:"type##_lbu("$1", "2(%2)")"\n\t" \
63*4882a593Smuzhiyun 		"sll\t%0, 0x8\n\t"		    \
64*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
65*4882a593Smuzhiyun 		"4:"type##_lbu("$1", "3(%2)")"\n\t" \
66*4882a593Smuzhiyun 		"sll\t%0, 0x8\n\t"		    \
67*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
68*4882a593Smuzhiyun 		"li\t%1, 0\n"			    \
69*4882a593Smuzhiyun 		".set\tpop\n"			    \
70*4882a593Smuzhiyun 		"10:\n\t"			    \
71*4882a593Smuzhiyun 		".insn\n\t"			    \
72*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"	    \
73*4882a593Smuzhiyun 		"11:\tli\t%1, %3\n\t"		    \
74*4882a593Smuzhiyun 		"j\t10b\n\t"			    \
75*4882a593Smuzhiyun 		".previous\n\t"			    \
76*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
77*4882a593Smuzhiyun 		STR(PTR)"\t1b, 11b\n\t"		    \
78*4882a593Smuzhiyun 		STR(PTR)"\t2b, 11b\n\t"		    \
79*4882a593Smuzhiyun 		STR(PTR)"\t3b, 11b\n\t"		    \
80*4882a593Smuzhiyun 		STR(PTR)"\t4b, 11b\n\t"		    \
81*4882a593Smuzhiyun 		".previous"			    \
82*4882a593Smuzhiyun 		: "=&r" (value), "=r" (res)	    \
83*4882a593Smuzhiyun 		: "r" (addr), "i" (-EFAULT));       \
84*4882a593Smuzhiyun } while (0)
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun #define  _LoadHWU(addr, value, res, type) \
89*4882a593Smuzhiyun do {                                                \
90*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
91*4882a593Smuzhiyun 		".set\tnoat\n"                      \
92*4882a593Smuzhiyun 		"1:\t"type##_lbu("%0", "0(%2)")"\n" \
93*4882a593Smuzhiyun 		"2:\t"type##_lbu("$1", "1(%2)")"\n\t"\
94*4882a593Smuzhiyun 		"sll\t%0, 0x8\n\t"                  \
95*4882a593Smuzhiyun 		"or\t%0, $1\n\t"                    \
96*4882a593Smuzhiyun 		"li\t%1, 0\n"                       \
97*4882a593Smuzhiyun 		"3:\n\t"                            \
98*4882a593Smuzhiyun 		".insn\n\t"                         \
99*4882a593Smuzhiyun 		".set\tat\n\t"                      \
100*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"       \
101*4882a593Smuzhiyun 		"4:\tli\t%1, %3\n\t"                \
102*4882a593Smuzhiyun 		"j\t3b\n\t"                         \
103*4882a593Smuzhiyun 		".previous\n\t"                     \
104*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
105*4882a593Smuzhiyun 		STR(PTR)"\t1b, 4b\n\t"               \
106*4882a593Smuzhiyun 		STR(PTR)"\t2b, 4b\n\t"               \
107*4882a593Smuzhiyun 		".previous"                         \
108*4882a593Smuzhiyun 		: "=&r" (value), "=r" (res)         \
109*4882a593Smuzhiyun 		: "r" (addr), "i" (-EFAULT));       \
110*4882a593Smuzhiyun } while (0)
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
113*4882a593Smuzhiyun #define  _LoadWU(addr, value, res, type)  \
114*4882a593Smuzhiyun do {                                                \
115*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
116*4882a593Smuzhiyun 		"1:\t"type##_lwl("%0", "(%2)")"\n"  \
117*4882a593Smuzhiyun 		"2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
118*4882a593Smuzhiyun 		"dsll\t%0, %0, 32\n\t"              \
119*4882a593Smuzhiyun 		"dsrl\t%0, %0, 32\n\t"              \
120*4882a593Smuzhiyun 		"li\t%1, 0\n"                       \
121*4882a593Smuzhiyun 		"3:\n\t"                            \
122*4882a593Smuzhiyun 		".insn\n\t"                         \
123*4882a593Smuzhiyun 		"\t.section\t.fixup,\"ax\"\n\t"     \
124*4882a593Smuzhiyun 		"4:\tli\t%1, %3\n\t"                \
125*4882a593Smuzhiyun 		"j\t3b\n\t"                         \
126*4882a593Smuzhiyun 		".previous\n\t"                     \
127*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
128*4882a593Smuzhiyun 		STR(PTR)"\t1b, 4b\n\t"               \
129*4882a593Smuzhiyun 		STR(PTR)"\t2b, 4b\n\t"               \
130*4882a593Smuzhiyun 		".previous"                         \
131*4882a593Smuzhiyun 		: "=&r" (value), "=r" (res)         \
132*4882a593Smuzhiyun 		: "r" (addr), "i" (-EFAULT));       \
133*4882a593Smuzhiyun } while (0)
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun #define  _LoadDW(addr, value, res)  \
136*4882a593Smuzhiyun do {                                                \
137*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
138*4882a593Smuzhiyun 		"1:\tldl\t%0, (%2)\n"               \
139*4882a593Smuzhiyun 		"2:\tldr\t%0, 7(%2)\n\t"            \
140*4882a593Smuzhiyun 		"li\t%1, 0\n"                       \
141*4882a593Smuzhiyun 		"3:\n\t"                            \
142*4882a593Smuzhiyun 		".insn\n\t"                         \
143*4882a593Smuzhiyun 		"\t.section\t.fixup,\"ax\"\n\t"     \
144*4882a593Smuzhiyun 		"4:\tli\t%1, %3\n\t"                \
145*4882a593Smuzhiyun 		"j\t3b\n\t"                         \
146*4882a593Smuzhiyun 		".previous\n\t"                     \
147*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
148*4882a593Smuzhiyun 		STR(PTR)"\t1b, 4b\n\t"               \
149*4882a593Smuzhiyun 		STR(PTR)"\t2b, 4b\n\t"               \
150*4882a593Smuzhiyun 		".previous"                         \
151*4882a593Smuzhiyun 		: "=&r" (value), "=r" (res)         \
152*4882a593Smuzhiyun 		: "r" (addr), "i" (-EFAULT));       \
153*4882a593Smuzhiyun } while (0)
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun #else /* CONFIG_CPU_NO_LOAD_STORE_LR */
156*4882a593Smuzhiyun /* For CPUs without lwl and ldl instructions */
157*4882a593Smuzhiyun #define  _LoadWU(addr, value, res, type) \
158*4882a593Smuzhiyun do {                                                \
159*4882a593Smuzhiyun 	__asm__ __volatile__ (			    \
160*4882a593Smuzhiyun 		".set\tpush\n\t"		    \
161*4882a593Smuzhiyun 		".set\tnoat\n\t"		    \
162*4882a593Smuzhiyun 		"1:"type##_lbu("%0", "0(%2)")"\n\t" \
163*4882a593Smuzhiyun 		"2:"type##_lbu("$1", "1(%2)")"\n\t" \
164*4882a593Smuzhiyun 		"sll\t%0, 0x8\n\t"		    \
165*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
166*4882a593Smuzhiyun 		"3:"type##_lbu("$1", "2(%2)")"\n\t" \
167*4882a593Smuzhiyun 		"sll\t%0, 0x8\n\t"		    \
168*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
169*4882a593Smuzhiyun 		"4:"type##_lbu("$1", "3(%2)")"\n\t" \
170*4882a593Smuzhiyun 		"sll\t%0, 0x8\n\t"		    \
171*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
172*4882a593Smuzhiyun 		"li\t%1, 0\n"			    \
173*4882a593Smuzhiyun 		".set\tpop\n"			    \
174*4882a593Smuzhiyun 		"10:\n\t"			    \
175*4882a593Smuzhiyun 		".insn\n\t"			    \
176*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"	    \
177*4882a593Smuzhiyun 		"11:\tli\t%1, %3\n\t"		    \
178*4882a593Smuzhiyun 		"j\t10b\n\t"			    \
179*4882a593Smuzhiyun 		".previous\n\t"			    \
180*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
181*4882a593Smuzhiyun 		STR(PTR)"\t1b, 11b\n\t"		    \
182*4882a593Smuzhiyun 		STR(PTR)"\t2b, 11b\n\t"		    \
183*4882a593Smuzhiyun 		STR(PTR)"\t3b, 11b\n\t"		    \
184*4882a593Smuzhiyun 		STR(PTR)"\t4b, 11b\n\t"		    \
185*4882a593Smuzhiyun 		".previous"			    \
186*4882a593Smuzhiyun 		: "=&r" (value), "=r" (res)	    \
187*4882a593Smuzhiyun 		: "r" (addr), "i" (-EFAULT));       \
188*4882a593Smuzhiyun } while (0)
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun #define  _LoadDW(addr, value, res)  \
191*4882a593Smuzhiyun do {                                                \
192*4882a593Smuzhiyun 	__asm__ __volatile__ (			    \
193*4882a593Smuzhiyun 		".set\tpush\n\t"		    \
194*4882a593Smuzhiyun 		".set\tnoat\n\t"		    \
195*4882a593Smuzhiyun 		"1:lb\t%0, 0(%2)\n\t"		    \
196*4882a593Smuzhiyun 		"2:lbu\t $1, 1(%2)\n\t"		    \
197*4882a593Smuzhiyun 		"dsll\t%0, 0x8\n\t"		    \
198*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
199*4882a593Smuzhiyun 		"3:lbu\t$1, 2(%2)\n\t"		    \
200*4882a593Smuzhiyun 		"dsll\t%0, 0x8\n\t"		    \
201*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
202*4882a593Smuzhiyun 		"4:lbu\t$1, 3(%2)\n\t"		    \
203*4882a593Smuzhiyun 		"dsll\t%0, 0x8\n\t"		    \
204*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
205*4882a593Smuzhiyun 		"5:lbu\t$1, 4(%2)\n\t"		    \
206*4882a593Smuzhiyun 		"dsll\t%0, 0x8\n\t"		    \
207*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
208*4882a593Smuzhiyun 		"6:lbu\t$1, 5(%2)\n\t"		    \
209*4882a593Smuzhiyun 		"dsll\t%0, 0x8\n\t"		    \
210*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
211*4882a593Smuzhiyun 		"7:lbu\t$1, 6(%2)\n\t"		    \
212*4882a593Smuzhiyun 		"dsll\t%0, 0x8\n\t"		    \
213*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
214*4882a593Smuzhiyun 		"8:lbu\t$1, 7(%2)\n\t"		    \
215*4882a593Smuzhiyun 		"dsll\t%0, 0x8\n\t"		    \
216*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
217*4882a593Smuzhiyun 		"li\t%1, 0\n"			    \
218*4882a593Smuzhiyun 		".set\tpop\n\t"			    \
219*4882a593Smuzhiyun 		"10:\n\t"			    \
220*4882a593Smuzhiyun 		".insn\n\t"			    \
221*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"	    \
222*4882a593Smuzhiyun 		"11:\tli\t%1, %3\n\t"		    \
223*4882a593Smuzhiyun 		"j\t10b\n\t"			    \
224*4882a593Smuzhiyun 		".previous\n\t"			    \
225*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
226*4882a593Smuzhiyun 		STR(PTR)"\t1b, 11b\n\t"		    \
227*4882a593Smuzhiyun 		STR(PTR)"\t2b, 11b\n\t"		    \
228*4882a593Smuzhiyun 		STR(PTR)"\t3b, 11b\n\t"		    \
229*4882a593Smuzhiyun 		STR(PTR)"\t4b, 11b\n\t"		    \
230*4882a593Smuzhiyun 		STR(PTR)"\t5b, 11b\n\t"		    \
231*4882a593Smuzhiyun 		STR(PTR)"\t6b, 11b\n\t"		    \
232*4882a593Smuzhiyun 		STR(PTR)"\t7b, 11b\n\t"		    \
233*4882a593Smuzhiyun 		STR(PTR)"\t8b, 11b\n\t"		    \
234*4882a593Smuzhiyun 		".previous"			    \
235*4882a593Smuzhiyun 		: "=&r" (value), "=r" (res)	    \
236*4882a593Smuzhiyun 		: "r" (addr), "i" (-EFAULT));       \
237*4882a593Smuzhiyun } while (0)
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun #define  _StoreHW(addr, value, res, type) \
243*4882a593Smuzhiyun do {                                                \
244*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
245*4882a593Smuzhiyun 		".set\tnoat\n"                      \
246*4882a593Smuzhiyun 		"1:\t"type##_sb("%1", "1(%2)")"\n"  \
247*4882a593Smuzhiyun 		"srl\t$1, %1, 0x8\n"                \
248*4882a593Smuzhiyun 		"2:\t"type##_sb("$1", "0(%2)")"\n"  \
249*4882a593Smuzhiyun 		".set\tat\n\t"                      \
250*4882a593Smuzhiyun 		"li\t%0, 0\n"                       \
251*4882a593Smuzhiyun 		"3:\n\t"                            \
252*4882a593Smuzhiyun 		".insn\n\t"                         \
253*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"       \
254*4882a593Smuzhiyun 		"4:\tli\t%0, %3\n\t"                \
255*4882a593Smuzhiyun 		"j\t3b\n\t"                         \
256*4882a593Smuzhiyun 		".previous\n\t"                     \
257*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
258*4882a593Smuzhiyun 		STR(PTR)"\t1b, 4b\n\t"              \
259*4882a593Smuzhiyun 		STR(PTR)"\t2b, 4b\n\t"              \
260*4882a593Smuzhiyun 		".previous"                         \
261*4882a593Smuzhiyun 		: "=r" (res)                        \
262*4882a593Smuzhiyun 		: "r" (value), "r" (addr), "i" (-EFAULT));\
263*4882a593Smuzhiyun } while (0)
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
266*4882a593Smuzhiyun #define  _StoreW(addr, value, res, type)  \
267*4882a593Smuzhiyun do {                                                \
268*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
269*4882a593Smuzhiyun 		"1:\t"type##_swl("%1", "(%2)")"\n"  \
270*4882a593Smuzhiyun 		"2:\t"type##_swr("%1", "3(%2)")"\n\t"\
271*4882a593Smuzhiyun 		"li\t%0, 0\n"                       \
272*4882a593Smuzhiyun 		"3:\n\t"                            \
273*4882a593Smuzhiyun 		".insn\n\t"                         \
274*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"       \
275*4882a593Smuzhiyun 		"4:\tli\t%0, %3\n\t"                \
276*4882a593Smuzhiyun 		"j\t3b\n\t"                         \
277*4882a593Smuzhiyun 		".previous\n\t"                     \
278*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
279*4882a593Smuzhiyun 		STR(PTR)"\t1b, 4b\n\t"               \
280*4882a593Smuzhiyun 		STR(PTR)"\t2b, 4b\n\t"               \
281*4882a593Smuzhiyun 		".previous"                         \
282*4882a593Smuzhiyun 		: "=r" (res)                                \
283*4882a593Smuzhiyun 		: "r" (value), "r" (addr), "i" (-EFAULT));  \
284*4882a593Smuzhiyun } while (0)
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun #define  _StoreDW(addr, value, res) \
287*4882a593Smuzhiyun do {                                                \
288*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
289*4882a593Smuzhiyun 		"1:\tsdl\t%1,(%2)\n"                \
290*4882a593Smuzhiyun 		"2:\tsdr\t%1, 7(%2)\n\t"            \
291*4882a593Smuzhiyun 		"li\t%0, 0\n"                       \
292*4882a593Smuzhiyun 		"3:\n\t"                            \
293*4882a593Smuzhiyun 		".insn\n\t"                         \
294*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"       \
295*4882a593Smuzhiyun 		"4:\tli\t%0, %3\n\t"                \
296*4882a593Smuzhiyun 		"j\t3b\n\t"                         \
297*4882a593Smuzhiyun 		".previous\n\t"                     \
298*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
299*4882a593Smuzhiyun 		STR(PTR)"\t1b, 4b\n\t"               \
300*4882a593Smuzhiyun 		STR(PTR)"\t2b, 4b\n\t"               \
301*4882a593Smuzhiyun 		".previous"                         \
302*4882a593Smuzhiyun 		: "=r" (res)                                \
303*4882a593Smuzhiyun 		: "r" (value), "r" (addr), "i" (-EFAULT));  \
304*4882a593Smuzhiyun } while (0)
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun #else /* CONFIG_CPU_NO_LOAD_STORE_LR */
307*4882a593Smuzhiyun #define  _StoreW(addr, value, res, type)  \
308*4882a593Smuzhiyun do {                                                \
309*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
310*4882a593Smuzhiyun 		".set\tpush\n\t"		    \
311*4882a593Smuzhiyun 		".set\tnoat\n\t"		    \
312*4882a593Smuzhiyun 		"1:"type##_sb("%1", "3(%2)")"\n\t"  \
313*4882a593Smuzhiyun 		"srl\t$1, %1, 0x8\n\t"		    \
314*4882a593Smuzhiyun 		"2:"type##_sb("$1", "2(%2)")"\n\t"  \
315*4882a593Smuzhiyun 		"srl\t$1, $1,  0x8\n\t"		    \
316*4882a593Smuzhiyun 		"3:"type##_sb("$1", "1(%2)")"\n\t"  \
317*4882a593Smuzhiyun 		"srl\t$1, $1, 0x8\n\t"		    \
318*4882a593Smuzhiyun 		"4:"type##_sb("$1", "0(%2)")"\n\t"  \
319*4882a593Smuzhiyun 		".set\tpop\n\t"			    \
320*4882a593Smuzhiyun 		"li\t%0, 0\n"			    \
321*4882a593Smuzhiyun 		"10:\n\t"			    \
322*4882a593Smuzhiyun 		".insn\n\t"			    \
323*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"	    \
324*4882a593Smuzhiyun 		"11:\tli\t%0, %3\n\t"		    \
325*4882a593Smuzhiyun 		"j\t10b\n\t"			    \
326*4882a593Smuzhiyun 		".previous\n\t"			    \
327*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
328*4882a593Smuzhiyun 		STR(PTR)"\t1b, 11b\n\t"		    \
329*4882a593Smuzhiyun 		STR(PTR)"\t2b, 11b\n\t"		    \
330*4882a593Smuzhiyun 		STR(PTR)"\t3b, 11b\n\t"		    \
331*4882a593Smuzhiyun 		STR(PTR)"\t4b, 11b\n\t"		    \
332*4882a593Smuzhiyun 		".previous"			    \
333*4882a593Smuzhiyun 		: "=&r" (res)				    \
334*4882a593Smuzhiyun 		: "r" (value), "r" (addr), "i" (-EFAULT)    \
335*4882a593Smuzhiyun 		: "memory");                                \
336*4882a593Smuzhiyun } while (0)
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun #define  _StoreDW(addr, value, res) \
339*4882a593Smuzhiyun do {                                                \
340*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
341*4882a593Smuzhiyun 		".set\tpush\n\t"		    \
342*4882a593Smuzhiyun 		".set\tnoat\n\t"		    \
343*4882a593Smuzhiyun 		"1:sb\t%1, 7(%2)\n\t"		    \
344*4882a593Smuzhiyun 		"dsrl\t$1, %1, 0x8\n\t"		    \
345*4882a593Smuzhiyun 		"2:sb\t$1, 6(%2)\n\t"		    \
346*4882a593Smuzhiyun 		"dsrl\t$1, $1, 0x8\n\t"		    \
347*4882a593Smuzhiyun 		"3:sb\t$1, 5(%2)\n\t"		    \
348*4882a593Smuzhiyun 		"dsrl\t$1, $1, 0x8\n\t"		    \
349*4882a593Smuzhiyun 		"4:sb\t$1, 4(%2)\n\t"		    \
350*4882a593Smuzhiyun 		"dsrl\t$1, $1, 0x8\n\t"		    \
351*4882a593Smuzhiyun 		"5:sb\t$1, 3(%2)\n\t"		    \
352*4882a593Smuzhiyun 		"dsrl\t$1, $1, 0x8\n\t"		    \
353*4882a593Smuzhiyun 		"6:sb\t$1, 2(%2)\n\t"		    \
354*4882a593Smuzhiyun 		"dsrl\t$1, $1, 0x8\n\t"		    \
355*4882a593Smuzhiyun 		"7:sb\t$1, 1(%2)\n\t"		    \
356*4882a593Smuzhiyun 		"dsrl\t$1, $1, 0x8\n\t"		    \
357*4882a593Smuzhiyun 		"8:sb\t$1, 0(%2)\n\t"		    \
358*4882a593Smuzhiyun 		"dsrl\t$1, $1, 0x8\n\t"		    \
359*4882a593Smuzhiyun 		".set\tpop\n\t"			    \
360*4882a593Smuzhiyun 		"li\t%0, 0\n"			    \
361*4882a593Smuzhiyun 		"10:\n\t"			    \
362*4882a593Smuzhiyun 		".insn\n\t"			    \
363*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"	    \
364*4882a593Smuzhiyun 		"11:\tli\t%0, %3\n\t"		    \
365*4882a593Smuzhiyun 		"j\t10b\n\t"			    \
366*4882a593Smuzhiyun 		".previous\n\t"			    \
367*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
368*4882a593Smuzhiyun 		STR(PTR)"\t1b, 11b\n\t"		    \
369*4882a593Smuzhiyun 		STR(PTR)"\t2b, 11b\n\t"		    \
370*4882a593Smuzhiyun 		STR(PTR)"\t3b, 11b\n\t"		    \
371*4882a593Smuzhiyun 		STR(PTR)"\t4b, 11b\n\t"		    \
372*4882a593Smuzhiyun 		STR(PTR)"\t5b, 11b\n\t"		    \
373*4882a593Smuzhiyun 		STR(PTR)"\t6b, 11b\n\t"		    \
374*4882a593Smuzhiyun 		STR(PTR)"\t7b, 11b\n\t"		    \
375*4882a593Smuzhiyun 		STR(PTR)"\t8b, 11b\n\t"		    \
376*4882a593Smuzhiyun 		".previous"			    \
377*4882a593Smuzhiyun 		: "=&r" (res)				    \
378*4882a593Smuzhiyun 		: "r" (value), "r" (addr), "i" (-EFAULT)    \
379*4882a593Smuzhiyun 		: "memory");                                \
380*4882a593Smuzhiyun } while (0)
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun #else /* __BIG_ENDIAN */
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun #define  _LoadHW(addr, value, res, type)  \
387*4882a593Smuzhiyun do {                                                \
388*4882a593Smuzhiyun 	__asm__ __volatile__ (".set\tnoat\n"        \
389*4882a593Smuzhiyun 		"1:\t"type##_lb("%0", "1(%2)")"\n"  \
390*4882a593Smuzhiyun 		"2:\t"type##_lbu("$1", "0(%2)")"\n\t"\
391*4882a593Smuzhiyun 		"sll\t%0, 0x8\n\t"                  \
392*4882a593Smuzhiyun 		"or\t%0, $1\n\t"                    \
393*4882a593Smuzhiyun 		"li\t%1, 0\n"                       \
394*4882a593Smuzhiyun 		"3:\t.set\tat\n\t"                  \
395*4882a593Smuzhiyun 		".insn\n\t"                         \
396*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"       \
397*4882a593Smuzhiyun 		"4:\tli\t%1, %3\n\t"                \
398*4882a593Smuzhiyun 		"j\t3b\n\t"                         \
399*4882a593Smuzhiyun 		".previous\n\t"                     \
400*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
401*4882a593Smuzhiyun 		STR(PTR)"\t1b, 4b\n\t"               \
402*4882a593Smuzhiyun 		STR(PTR)"\t2b, 4b\n\t"               \
403*4882a593Smuzhiyun 		".previous"                         \
404*4882a593Smuzhiyun 		: "=&r" (value), "=r" (res)         \
405*4882a593Smuzhiyun 		: "r" (addr), "i" (-EFAULT));       \
406*4882a593Smuzhiyun } while (0)
407*4882a593Smuzhiyun 
408*4882a593Smuzhiyun #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
409*4882a593Smuzhiyun #define  _LoadW(addr, value, res, type)   \
410*4882a593Smuzhiyun do {                                                \
411*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
412*4882a593Smuzhiyun 		"1:\t"type##_lwl("%0", "3(%2)")"\n" \
413*4882a593Smuzhiyun 		"2:\t"type##_lwr("%0", "(%2)")"\n\t"\
414*4882a593Smuzhiyun 		"li\t%1, 0\n"                       \
415*4882a593Smuzhiyun 		"3:\n\t"                            \
416*4882a593Smuzhiyun 		".insn\n\t"                         \
417*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"       \
418*4882a593Smuzhiyun 		"4:\tli\t%1, %3\n\t"                \
419*4882a593Smuzhiyun 		"j\t3b\n\t"                         \
420*4882a593Smuzhiyun 		".previous\n\t"                     \
421*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
422*4882a593Smuzhiyun 		STR(PTR)"\t1b, 4b\n\t"               \
423*4882a593Smuzhiyun 		STR(PTR)"\t2b, 4b\n\t"               \
424*4882a593Smuzhiyun 		".previous"                         \
425*4882a593Smuzhiyun 		: "=&r" (value), "=r" (res)         \
426*4882a593Smuzhiyun 		: "r" (addr), "i" (-EFAULT));       \
427*4882a593Smuzhiyun } while (0)
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun #else /* CONFIG_CPU_NO_LOAD_STORE_LR */
430*4882a593Smuzhiyun /* For CPUs without lwl instruction */
431*4882a593Smuzhiyun #define  _LoadW(addr, value, res, type) \
432*4882a593Smuzhiyun do {                                                \
433*4882a593Smuzhiyun 	__asm__ __volatile__ (			    \
434*4882a593Smuzhiyun 		".set\tpush\n"			    \
435*4882a593Smuzhiyun 		".set\tnoat\n\t"		    \
436*4882a593Smuzhiyun 		"1:"type##_lb("%0", "3(%2)")"\n\t"  \
437*4882a593Smuzhiyun 		"2:"type##_lbu("$1", "2(%2)")"\n\t" \
438*4882a593Smuzhiyun 		"sll\t%0, 0x8\n\t"		    \
439*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
440*4882a593Smuzhiyun 		"3:"type##_lbu("$1", "1(%2)")"\n\t" \
441*4882a593Smuzhiyun 		"sll\t%0, 0x8\n\t"		    \
442*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
443*4882a593Smuzhiyun 		"4:"type##_lbu("$1", "0(%2)")"\n\t" \
444*4882a593Smuzhiyun 		"sll\t%0, 0x8\n\t"		    \
445*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
446*4882a593Smuzhiyun 		"li\t%1, 0\n"			    \
447*4882a593Smuzhiyun 		".set\tpop\n"			    \
448*4882a593Smuzhiyun 		"10:\n\t"			    \
449*4882a593Smuzhiyun 		".insn\n\t"			    \
450*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"	    \
451*4882a593Smuzhiyun 		"11:\tli\t%1, %3\n\t"		    \
452*4882a593Smuzhiyun 		"j\t10b\n\t"			    \
453*4882a593Smuzhiyun 		".previous\n\t"			    \
454*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
455*4882a593Smuzhiyun 		STR(PTR)"\t1b, 11b\n\t"		    \
456*4882a593Smuzhiyun 		STR(PTR)"\t2b, 11b\n\t"		    \
457*4882a593Smuzhiyun 		STR(PTR)"\t3b, 11b\n\t"		    \
458*4882a593Smuzhiyun 		STR(PTR)"\t4b, 11b\n\t"		    \
459*4882a593Smuzhiyun 		".previous"			    \
460*4882a593Smuzhiyun 		: "=&r" (value), "=r" (res)	    \
461*4882a593Smuzhiyun 		: "r" (addr), "i" (-EFAULT));       \
462*4882a593Smuzhiyun } while (0)
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun #define  _LoadHWU(addr, value, res, type) \
468*4882a593Smuzhiyun do {                                                \
469*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
470*4882a593Smuzhiyun 		".set\tnoat\n"                      \
471*4882a593Smuzhiyun 		"1:\t"type##_lbu("%0", "1(%2)")"\n" \
472*4882a593Smuzhiyun 		"2:\t"type##_lbu("$1", "0(%2)")"\n\t"\
473*4882a593Smuzhiyun 		"sll\t%0, 0x8\n\t"                  \
474*4882a593Smuzhiyun 		"or\t%0, $1\n\t"                    \
475*4882a593Smuzhiyun 		"li\t%1, 0\n"                       \
476*4882a593Smuzhiyun 		"3:\n\t"                            \
477*4882a593Smuzhiyun 		".insn\n\t"                         \
478*4882a593Smuzhiyun 		".set\tat\n\t"                      \
479*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"       \
480*4882a593Smuzhiyun 		"4:\tli\t%1, %3\n\t"                \
481*4882a593Smuzhiyun 		"j\t3b\n\t"                         \
482*4882a593Smuzhiyun 		".previous\n\t"                     \
483*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
484*4882a593Smuzhiyun 		STR(PTR)"\t1b, 4b\n\t"               \
485*4882a593Smuzhiyun 		STR(PTR)"\t2b, 4b\n\t"               \
486*4882a593Smuzhiyun 		".previous"                         \
487*4882a593Smuzhiyun 		: "=&r" (value), "=r" (res)         \
488*4882a593Smuzhiyun 		: "r" (addr), "i" (-EFAULT));       \
489*4882a593Smuzhiyun } while (0)
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
492*4882a593Smuzhiyun #define  _LoadWU(addr, value, res, type)  \
493*4882a593Smuzhiyun do {                                                \
494*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
495*4882a593Smuzhiyun 		"1:\t"type##_lwl("%0", "3(%2)")"\n" \
496*4882a593Smuzhiyun 		"2:\t"type##_lwr("%0", "(%2)")"\n\t"\
497*4882a593Smuzhiyun 		"dsll\t%0, %0, 32\n\t"              \
498*4882a593Smuzhiyun 		"dsrl\t%0, %0, 32\n\t"              \
499*4882a593Smuzhiyun 		"li\t%1, 0\n"                       \
500*4882a593Smuzhiyun 		"3:\n\t"                            \
501*4882a593Smuzhiyun 		".insn\n\t"                         \
502*4882a593Smuzhiyun 		"\t.section\t.fixup,\"ax\"\n\t"     \
503*4882a593Smuzhiyun 		"4:\tli\t%1, %3\n\t"                \
504*4882a593Smuzhiyun 		"j\t3b\n\t"                         \
505*4882a593Smuzhiyun 		".previous\n\t"                     \
506*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
507*4882a593Smuzhiyun 		STR(PTR)"\t1b, 4b\n\t"               \
508*4882a593Smuzhiyun 		STR(PTR)"\t2b, 4b\n\t"               \
509*4882a593Smuzhiyun 		".previous"                         \
510*4882a593Smuzhiyun 		: "=&r" (value), "=r" (res)         \
511*4882a593Smuzhiyun 		: "r" (addr), "i" (-EFAULT));       \
512*4882a593Smuzhiyun } while (0)
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun #define  _LoadDW(addr, value, res)  \
515*4882a593Smuzhiyun do {                                                \
516*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
517*4882a593Smuzhiyun 		"1:\tldl\t%0, 7(%2)\n"              \
518*4882a593Smuzhiyun 		"2:\tldr\t%0, (%2)\n\t"             \
519*4882a593Smuzhiyun 		"li\t%1, 0\n"                       \
520*4882a593Smuzhiyun 		"3:\n\t"                            \
521*4882a593Smuzhiyun 		".insn\n\t"                         \
522*4882a593Smuzhiyun 		"\t.section\t.fixup,\"ax\"\n\t"     \
523*4882a593Smuzhiyun 		"4:\tli\t%1, %3\n\t"                \
524*4882a593Smuzhiyun 		"j\t3b\n\t"                         \
525*4882a593Smuzhiyun 		".previous\n\t"                     \
526*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
527*4882a593Smuzhiyun 		STR(PTR)"\t1b, 4b\n\t"               \
528*4882a593Smuzhiyun 		STR(PTR)"\t2b, 4b\n\t"               \
529*4882a593Smuzhiyun 		".previous"                         \
530*4882a593Smuzhiyun 		: "=&r" (value), "=r" (res)         \
531*4882a593Smuzhiyun 		: "r" (addr), "i" (-EFAULT));       \
532*4882a593Smuzhiyun } while (0)
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun #else /* CONFIG_CPU_NO_LOAD_STORE_LR */
535*4882a593Smuzhiyun /* For CPUs without lwl and ldl instructions */
536*4882a593Smuzhiyun #define  _LoadWU(addr, value, res, type) \
537*4882a593Smuzhiyun do {                                                \
538*4882a593Smuzhiyun 	__asm__ __volatile__ (			    \
539*4882a593Smuzhiyun 		".set\tpush\n\t"		    \
540*4882a593Smuzhiyun 		".set\tnoat\n\t"		    \
541*4882a593Smuzhiyun 		"1:"type##_lbu("%0", "3(%2)")"\n\t" \
542*4882a593Smuzhiyun 		"2:"type##_lbu("$1", "2(%2)")"\n\t" \
543*4882a593Smuzhiyun 		"sll\t%0, 0x8\n\t"		    \
544*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
545*4882a593Smuzhiyun 		"3:"type##_lbu("$1", "1(%2)")"\n\t" \
546*4882a593Smuzhiyun 		"sll\t%0, 0x8\n\t"		    \
547*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
548*4882a593Smuzhiyun 		"4:"type##_lbu("$1", "0(%2)")"\n\t" \
549*4882a593Smuzhiyun 		"sll\t%0, 0x8\n\t"		    \
550*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
551*4882a593Smuzhiyun 		"li\t%1, 0\n"			    \
552*4882a593Smuzhiyun 		".set\tpop\n"			    \
553*4882a593Smuzhiyun 		"10:\n\t"			    \
554*4882a593Smuzhiyun 		".insn\n\t"			    \
555*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"	    \
556*4882a593Smuzhiyun 		"11:\tli\t%1, %3\n\t"		    \
557*4882a593Smuzhiyun 		"j\t10b\n\t"			    \
558*4882a593Smuzhiyun 		".previous\n\t"			    \
559*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
560*4882a593Smuzhiyun 		STR(PTR)"\t1b, 11b\n\t"		    \
561*4882a593Smuzhiyun 		STR(PTR)"\t2b, 11b\n\t"		    \
562*4882a593Smuzhiyun 		STR(PTR)"\t3b, 11b\n\t"		    \
563*4882a593Smuzhiyun 		STR(PTR)"\t4b, 11b\n\t"		    \
564*4882a593Smuzhiyun 		".previous"			    \
565*4882a593Smuzhiyun 		: "=&r" (value), "=r" (res)	    \
566*4882a593Smuzhiyun 		: "r" (addr), "i" (-EFAULT));       \
567*4882a593Smuzhiyun } while (0)
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun #define  _LoadDW(addr, value, res)  \
570*4882a593Smuzhiyun do {                                                \
571*4882a593Smuzhiyun 	__asm__ __volatile__ (			    \
572*4882a593Smuzhiyun 		".set\tpush\n\t"		    \
573*4882a593Smuzhiyun 		".set\tnoat\n\t"		    \
574*4882a593Smuzhiyun 		"1:lb\t%0, 7(%2)\n\t"		    \
575*4882a593Smuzhiyun 		"2:lbu\t$1, 6(%2)\n\t"		    \
576*4882a593Smuzhiyun 		"dsll\t%0, 0x8\n\t"		    \
577*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
578*4882a593Smuzhiyun 		"3:lbu\t$1, 5(%2)\n\t"		    \
579*4882a593Smuzhiyun 		"dsll\t%0, 0x8\n\t"		    \
580*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
581*4882a593Smuzhiyun 		"4:lbu\t$1, 4(%2)\n\t"		    \
582*4882a593Smuzhiyun 		"dsll\t%0, 0x8\n\t"		    \
583*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
584*4882a593Smuzhiyun 		"5:lbu\t$1, 3(%2)\n\t"		    \
585*4882a593Smuzhiyun 		"dsll\t%0, 0x8\n\t"		    \
586*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
587*4882a593Smuzhiyun 		"6:lbu\t$1, 2(%2)\n\t"		    \
588*4882a593Smuzhiyun 		"dsll\t%0, 0x8\n\t"		    \
589*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
590*4882a593Smuzhiyun 		"7:lbu\t$1, 1(%2)\n\t"		    \
591*4882a593Smuzhiyun 		"dsll\t%0, 0x8\n\t"		    \
592*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
593*4882a593Smuzhiyun 		"8:lbu\t$1, 0(%2)\n\t"		    \
594*4882a593Smuzhiyun 		"dsll\t%0, 0x8\n\t"		    \
595*4882a593Smuzhiyun 		"or\t%0, $1\n\t"		    \
596*4882a593Smuzhiyun 		"li\t%1, 0\n"			    \
597*4882a593Smuzhiyun 		".set\tpop\n\t"			    \
598*4882a593Smuzhiyun 		"10:\n\t"			    \
599*4882a593Smuzhiyun 		".insn\n\t"			    \
600*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"	    \
601*4882a593Smuzhiyun 		"11:\tli\t%1, %3\n\t"		    \
602*4882a593Smuzhiyun 		"j\t10b\n\t"			    \
603*4882a593Smuzhiyun 		".previous\n\t"			    \
604*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
605*4882a593Smuzhiyun 		STR(PTR)"\t1b, 11b\n\t"		    \
606*4882a593Smuzhiyun 		STR(PTR)"\t2b, 11b\n\t"		    \
607*4882a593Smuzhiyun 		STR(PTR)"\t3b, 11b\n\t"		    \
608*4882a593Smuzhiyun 		STR(PTR)"\t4b, 11b\n\t"		    \
609*4882a593Smuzhiyun 		STR(PTR)"\t5b, 11b\n\t"		    \
610*4882a593Smuzhiyun 		STR(PTR)"\t6b, 11b\n\t"		    \
611*4882a593Smuzhiyun 		STR(PTR)"\t7b, 11b\n\t"		    \
612*4882a593Smuzhiyun 		STR(PTR)"\t8b, 11b\n\t"		    \
613*4882a593Smuzhiyun 		".previous"			    \
614*4882a593Smuzhiyun 		: "=&r" (value), "=r" (res)	    \
615*4882a593Smuzhiyun 		: "r" (addr), "i" (-EFAULT));       \
616*4882a593Smuzhiyun } while (0)
617*4882a593Smuzhiyun #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
618*4882a593Smuzhiyun 
619*4882a593Smuzhiyun #define  _StoreHW(addr, value, res, type) \
620*4882a593Smuzhiyun do {                                                 \
621*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
622*4882a593Smuzhiyun 		".set\tnoat\n"                      \
623*4882a593Smuzhiyun 		"1:\t"type##_sb("%1", "0(%2)")"\n"  \
624*4882a593Smuzhiyun 		"srl\t$1,%1, 0x8\n"                 \
625*4882a593Smuzhiyun 		"2:\t"type##_sb("$1", "1(%2)")"\n"  \
626*4882a593Smuzhiyun 		".set\tat\n\t"                      \
627*4882a593Smuzhiyun 		"li\t%0, 0\n"                       \
628*4882a593Smuzhiyun 		"3:\n\t"                            \
629*4882a593Smuzhiyun 		".insn\n\t"                         \
630*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"       \
631*4882a593Smuzhiyun 		"4:\tli\t%0, %3\n\t"                \
632*4882a593Smuzhiyun 		"j\t3b\n\t"                         \
633*4882a593Smuzhiyun 		".previous\n\t"                     \
634*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
635*4882a593Smuzhiyun 		STR(PTR)"\t1b, 4b\n\t"               \
636*4882a593Smuzhiyun 		STR(PTR)"\t2b, 4b\n\t"               \
637*4882a593Smuzhiyun 		".previous"                         \
638*4882a593Smuzhiyun 		: "=r" (res)                        \
639*4882a593Smuzhiyun 		: "r" (value), "r" (addr), "i" (-EFAULT));\
640*4882a593Smuzhiyun } while (0)
641*4882a593Smuzhiyun 
642*4882a593Smuzhiyun #ifndef CONFIG_CPU_NO_LOAD_STORE_LR
643*4882a593Smuzhiyun #define  _StoreW(addr, value, res, type)  \
644*4882a593Smuzhiyun do {                                                \
645*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
646*4882a593Smuzhiyun 		"1:\t"type##_swl("%1", "3(%2)")"\n" \
647*4882a593Smuzhiyun 		"2:\t"type##_swr("%1", "(%2)")"\n\t"\
648*4882a593Smuzhiyun 		"li\t%0, 0\n"                       \
649*4882a593Smuzhiyun 		"3:\n\t"                            \
650*4882a593Smuzhiyun 		".insn\n\t"                         \
651*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"       \
652*4882a593Smuzhiyun 		"4:\tli\t%0, %3\n\t"                \
653*4882a593Smuzhiyun 		"j\t3b\n\t"                         \
654*4882a593Smuzhiyun 		".previous\n\t"                     \
655*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
656*4882a593Smuzhiyun 		STR(PTR)"\t1b, 4b\n\t"               \
657*4882a593Smuzhiyun 		STR(PTR)"\t2b, 4b\n\t"               \
658*4882a593Smuzhiyun 		".previous"                         \
659*4882a593Smuzhiyun 		: "=r" (res)                                \
660*4882a593Smuzhiyun 		: "r" (value), "r" (addr), "i" (-EFAULT));  \
661*4882a593Smuzhiyun } while (0)
662*4882a593Smuzhiyun 
663*4882a593Smuzhiyun #define  _StoreDW(addr, value, res) \
664*4882a593Smuzhiyun do {                                                \
665*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
666*4882a593Smuzhiyun 		"1:\tsdl\t%1, 7(%2)\n"              \
667*4882a593Smuzhiyun 		"2:\tsdr\t%1, (%2)\n\t"             \
668*4882a593Smuzhiyun 		"li\t%0, 0\n"                       \
669*4882a593Smuzhiyun 		"3:\n\t"                            \
670*4882a593Smuzhiyun 		".insn\n\t"                         \
671*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"       \
672*4882a593Smuzhiyun 		"4:\tli\t%0, %3\n\t"                \
673*4882a593Smuzhiyun 		"j\t3b\n\t"                         \
674*4882a593Smuzhiyun 		".previous\n\t"                     \
675*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
676*4882a593Smuzhiyun 		STR(PTR)"\t1b, 4b\n\t"               \
677*4882a593Smuzhiyun 		STR(PTR)"\t2b, 4b\n\t"               \
678*4882a593Smuzhiyun 		".previous"                         \
679*4882a593Smuzhiyun 		: "=r" (res)                                \
680*4882a593Smuzhiyun 		: "r" (value), "r" (addr), "i" (-EFAULT));  \
681*4882a593Smuzhiyun } while (0)
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun #else /* CONFIG_CPU_NO_LOAD_STORE_LR */
684*4882a593Smuzhiyun /* For CPUs without swl and sdl instructions */
685*4882a593Smuzhiyun #define  _StoreW(addr, value, res, type)  \
686*4882a593Smuzhiyun do {                                                \
687*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
688*4882a593Smuzhiyun 		".set\tpush\n\t"		    \
689*4882a593Smuzhiyun 		".set\tnoat\n\t"		    \
690*4882a593Smuzhiyun 		"1:"type##_sb("%1", "0(%2)")"\n\t"  \
691*4882a593Smuzhiyun 		"srl\t$1, %1, 0x8\n\t"		    \
692*4882a593Smuzhiyun 		"2:"type##_sb("$1", "1(%2)")"\n\t"  \
693*4882a593Smuzhiyun 		"srl\t$1, $1,  0x8\n\t"		    \
694*4882a593Smuzhiyun 		"3:"type##_sb("$1", "2(%2)")"\n\t"  \
695*4882a593Smuzhiyun 		"srl\t$1, $1, 0x8\n\t"		    \
696*4882a593Smuzhiyun 		"4:"type##_sb("$1", "3(%2)")"\n\t"  \
697*4882a593Smuzhiyun 		".set\tpop\n\t"			    \
698*4882a593Smuzhiyun 		"li\t%0, 0\n"			    \
699*4882a593Smuzhiyun 		"10:\n\t"			    \
700*4882a593Smuzhiyun 		".insn\n\t"			    \
701*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"	    \
702*4882a593Smuzhiyun 		"11:\tli\t%0, %3\n\t"		    \
703*4882a593Smuzhiyun 		"j\t10b\n\t"			    \
704*4882a593Smuzhiyun 		".previous\n\t"			    \
705*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
706*4882a593Smuzhiyun 		STR(PTR)"\t1b, 11b\n\t"		    \
707*4882a593Smuzhiyun 		STR(PTR)"\t2b, 11b\n\t"		    \
708*4882a593Smuzhiyun 		STR(PTR)"\t3b, 11b\n\t"		    \
709*4882a593Smuzhiyun 		STR(PTR)"\t4b, 11b\n\t"		    \
710*4882a593Smuzhiyun 		".previous"			    \
711*4882a593Smuzhiyun 		: "=&r" (res)				    \
712*4882a593Smuzhiyun 		: "r" (value), "r" (addr), "i" (-EFAULT)    \
713*4882a593Smuzhiyun 		: "memory");                                \
714*4882a593Smuzhiyun } while (0)
715*4882a593Smuzhiyun 
716*4882a593Smuzhiyun #define  _StoreDW(addr, value, res) \
717*4882a593Smuzhiyun do {                                                \
718*4882a593Smuzhiyun 	__asm__ __volatile__ (                      \
719*4882a593Smuzhiyun 		".set\tpush\n\t"		    \
720*4882a593Smuzhiyun 		".set\tnoat\n\t"		    \
721*4882a593Smuzhiyun 		"1:sb\t%1, 0(%2)\n\t"		    \
722*4882a593Smuzhiyun 		"dsrl\t$1, %1, 0x8\n\t"		    \
723*4882a593Smuzhiyun 		"2:sb\t$1, 1(%2)\n\t"		    \
724*4882a593Smuzhiyun 		"dsrl\t$1, $1, 0x8\n\t"		    \
725*4882a593Smuzhiyun 		"3:sb\t$1, 2(%2)\n\t"		    \
726*4882a593Smuzhiyun 		"dsrl\t$1, $1, 0x8\n\t"		    \
727*4882a593Smuzhiyun 		"4:sb\t$1, 3(%2)\n\t"		    \
728*4882a593Smuzhiyun 		"dsrl\t$1, $1, 0x8\n\t"		    \
729*4882a593Smuzhiyun 		"5:sb\t$1, 4(%2)\n\t"		    \
730*4882a593Smuzhiyun 		"dsrl\t$1, $1, 0x8\n\t"		    \
731*4882a593Smuzhiyun 		"6:sb\t$1, 5(%2)\n\t"		    \
732*4882a593Smuzhiyun 		"dsrl\t$1, $1, 0x8\n\t"		    \
733*4882a593Smuzhiyun 		"7:sb\t$1, 6(%2)\n\t"		    \
734*4882a593Smuzhiyun 		"dsrl\t$1, $1, 0x8\n\t"		    \
735*4882a593Smuzhiyun 		"8:sb\t$1, 7(%2)\n\t"		    \
736*4882a593Smuzhiyun 		"dsrl\t$1, $1, 0x8\n\t"		    \
737*4882a593Smuzhiyun 		".set\tpop\n\t"			    \
738*4882a593Smuzhiyun 		"li\t%0, 0\n"			    \
739*4882a593Smuzhiyun 		"10:\n\t"			    \
740*4882a593Smuzhiyun 		".insn\n\t"			    \
741*4882a593Smuzhiyun 		".section\t.fixup,\"ax\"\n\t"	    \
742*4882a593Smuzhiyun 		"11:\tli\t%0, %3\n\t"		    \
743*4882a593Smuzhiyun 		"j\t10b\n\t"			    \
744*4882a593Smuzhiyun 		".previous\n\t"			    \
745*4882a593Smuzhiyun 		".section\t__ex_table,\"a\"\n\t"    \
746*4882a593Smuzhiyun 		STR(PTR)"\t1b, 11b\n\t"		    \
747*4882a593Smuzhiyun 		STR(PTR)"\t2b, 11b\n\t"		    \
748*4882a593Smuzhiyun 		STR(PTR)"\t3b, 11b\n\t"		    \
749*4882a593Smuzhiyun 		STR(PTR)"\t4b, 11b\n\t"		    \
750*4882a593Smuzhiyun 		STR(PTR)"\t5b, 11b\n\t"		    \
751*4882a593Smuzhiyun 		STR(PTR)"\t6b, 11b\n\t"		    \
752*4882a593Smuzhiyun 		STR(PTR)"\t7b, 11b\n\t"		    \
753*4882a593Smuzhiyun 		STR(PTR)"\t8b, 11b\n\t"		    \
754*4882a593Smuzhiyun 		".previous"			    \
755*4882a593Smuzhiyun 		: "=&r" (res)				    \
756*4882a593Smuzhiyun 		: "r" (value), "r" (addr), "i" (-EFAULT)    \
757*4882a593Smuzhiyun 		: "memory");                                \
758*4882a593Smuzhiyun } while (0)
759*4882a593Smuzhiyun 
760*4882a593Smuzhiyun #endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
761*4882a593Smuzhiyun #endif
762*4882a593Smuzhiyun 
763*4882a593Smuzhiyun #define LoadHWU(addr, value, res)	_LoadHWU(addr, value, res, kernel)
764*4882a593Smuzhiyun #define LoadHWUE(addr, value, res)	_LoadHWU(addr, value, res, user)
765*4882a593Smuzhiyun #define LoadWU(addr, value, res)	_LoadWU(addr, value, res, kernel)
766*4882a593Smuzhiyun #define LoadWUE(addr, value, res)	_LoadWU(addr, value, res, user)
767*4882a593Smuzhiyun #define LoadHW(addr, value, res)	_LoadHW(addr, value, res, kernel)
768*4882a593Smuzhiyun #define LoadHWE(addr, value, res)	_LoadHW(addr, value, res, user)
769*4882a593Smuzhiyun #define LoadW(addr, value, res)		_LoadW(addr, value, res, kernel)
770*4882a593Smuzhiyun #define LoadWE(addr, value, res)	_LoadW(addr, value, res, user)
771*4882a593Smuzhiyun #define LoadDW(addr, value, res)	_LoadDW(addr, value, res)
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun #define StoreHW(addr, value, res)	_StoreHW(addr, value, res, kernel)
774*4882a593Smuzhiyun #define StoreHWE(addr, value, res)	_StoreHW(addr, value, res, user)
775*4882a593Smuzhiyun #define StoreW(addr, value, res)	_StoreW(addr, value, res, kernel)
776*4882a593Smuzhiyun #define StoreWE(addr, value, res)	_StoreW(addr, value, res, user)
777*4882a593Smuzhiyun #define StoreDW(addr, value, res)	_StoreDW(addr, value, res)
778*4882a593Smuzhiyun 
779*4882a593Smuzhiyun #endif /* _ASM_MIPS_UNALIGNED_EMUL_H */
780