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