unaligned.c (42249094f79422fbf5ed4b54eeb48ff096809b8f) unaligned.c (9d8e573683ca85e2bd3cade8b5c42e195e6390ad)
1/*
2 * Handle unaligned accesses by emulation.
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, 1998, 1999, 2002 by Ralf Baechle
9 * Copyright (C) 1999 Silicon Graphics, Inc.
1/*
2 * Handle unaligned accesses by emulation.
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, 1998, 1999, 2002 by Ralf Baechle
9 * Copyright (C) 1999 Silicon Graphics, Inc.
10 * Copyright (C) 2014 Imagination Technologies Ltd.
10 *
11 * This file contains exception handler for address error exception with the
12 * special capability to execute faulting instructions in software. The
13 * handler does not try to handle the case when the program counter points
14 * to an address not aligned to a word boundary.
15 *
16 * Putting data to unaligned addresses is a bad practice even on Intel where
17 * only the performance is affected. Much worse is that such code is non-

--- 87 unchanged lines hidden (view full) ---

105#else
106#define unaligned_action UNALIGNED_ACTION_QUIET
107#endif
108extern void show_registers(struct pt_regs *regs);
109
110#ifdef __BIG_ENDIAN
111#define LoadHW(addr, value, res) \
112 __asm__ __volatile__ (".set\tnoat\n" \
11 *
12 * This file contains exception handler for address error exception with the
13 * special capability to execute faulting instructions in software. The
14 * handler does not try to handle the case when the program counter points
15 * to an address not aligned to a word boundary.
16 *
17 * Putting data to unaligned addresses is a bad practice even on Intel where
18 * only the performance is affected. Much worse is that such code is non-

--- 87 unchanged lines hidden (view full) ---

106#else
107#define unaligned_action UNALIGNED_ACTION_QUIET
108#endif
109extern void show_registers(struct pt_regs *regs);
110
111#ifdef __BIG_ENDIAN
112#define LoadHW(addr, value, res) \
113 __asm__ __volatile__ (".set\tnoat\n" \
113 "1:\tlb\t%0, 0(%2)\n" \
114 "2:\tlbu\t$1, 1(%2)\n\t" \
114 "1:\t"user_lb("%0", "0(%2)")"\n" \
115 "2:\t"user_lbu("$1", "1(%2)")"\n\t" \
115 "sll\t%0, 0x8\n\t" \
116 "or\t%0, $1\n\t" \
117 "li\t%1, 0\n" \
118 "3:\t.set\tat\n\t" \
119 ".insn\n\t" \
120 ".section\t.fixup,\"ax\"\n\t" \
121 "4:\tli\t%1, %3\n\t" \
122 "j\t3b\n\t" \
123 ".previous\n\t" \
124 ".section\t__ex_table,\"a\"\n\t" \
125 STR(PTR)"\t1b, 4b\n\t" \
126 STR(PTR)"\t2b, 4b\n\t" \
127 ".previous" \
128 : "=&r" (value), "=r" (res) \
129 : "r" (addr), "i" (-EFAULT));
130
131#define LoadW(addr, value, res) \
132 __asm__ __volatile__ ( \
116 "sll\t%0, 0x8\n\t" \
117 "or\t%0, $1\n\t" \
118 "li\t%1, 0\n" \
119 "3:\t.set\tat\n\t" \
120 ".insn\n\t" \
121 ".section\t.fixup,\"ax\"\n\t" \
122 "4:\tli\t%1, %3\n\t" \
123 "j\t3b\n\t" \
124 ".previous\n\t" \
125 ".section\t__ex_table,\"a\"\n\t" \
126 STR(PTR)"\t1b, 4b\n\t" \
127 STR(PTR)"\t2b, 4b\n\t" \
128 ".previous" \
129 : "=&r" (value), "=r" (res) \
130 : "r" (addr), "i" (-EFAULT));
131
132#define LoadW(addr, value, res) \
133 __asm__ __volatile__ ( \
133 "1:\tlwl\t%0, (%2)\n" \
134 "2:\tlwr\t%0, 3(%2)\n\t" \
134 "1:\t"user_lwl("%0", "(%2)")"\n" \
135 "2:\t"user_lwr("%0", "3(%2)")"\n\t" \
135 "li\t%1, 0\n" \
136 "3:\n\t" \
137 ".insn\n\t" \
138 ".section\t.fixup,\"ax\"\n\t" \
139 "4:\tli\t%1, %3\n\t" \
140 "j\t3b\n\t" \
141 ".previous\n\t" \
142 ".section\t__ex_table,\"a\"\n\t" \
143 STR(PTR)"\t1b, 4b\n\t" \
144 STR(PTR)"\t2b, 4b\n\t" \
145 ".previous" \
146 : "=&r" (value), "=r" (res) \
147 : "r" (addr), "i" (-EFAULT));
148
149#define LoadHWU(addr, value, res) \
150 __asm__ __volatile__ ( \
151 ".set\tnoat\n" \
136 "li\t%1, 0\n" \
137 "3:\n\t" \
138 ".insn\n\t" \
139 ".section\t.fixup,\"ax\"\n\t" \
140 "4:\tli\t%1, %3\n\t" \
141 "j\t3b\n\t" \
142 ".previous\n\t" \
143 ".section\t__ex_table,\"a\"\n\t" \
144 STR(PTR)"\t1b, 4b\n\t" \
145 STR(PTR)"\t2b, 4b\n\t" \
146 ".previous" \
147 : "=&r" (value), "=r" (res) \
148 : "r" (addr), "i" (-EFAULT));
149
150#define LoadHWU(addr, value, res) \
151 __asm__ __volatile__ ( \
152 ".set\tnoat\n" \
152 "1:\tlbu\t%0, 0(%2)\n" \
153 "2:\tlbu\t$1, 1(%2)\n\t" \
153 "1:\t"user_lbu("%0", "0(%2)")"\n" \
154 "2:\t"user_lbu("$1", "1(%2)")"\n\t" \
154 "sll\t%0, 0x8\n\t" \
155 "or\t%0, $1\n\t" \
156 "li\t%1, 0\n" \
157 "3:\n\t" \
158 ".insn\n\t" \
159 ".set\tat\n\t" \
160 ".section\t.fixup,\"ax\"\n\t" \
161 "4:\tli\t%1, %3\n\t" \
162 "j\t3b\n\t" \
163 ".previous\n\t" \
164 ".section\t__ex_table,\"a\"\n\t" \
165 STR(PTR)"\t1b, 4b\n\t" \
166 STR(PTR)"\t2b, 4b\n\t" \
167 ".previous" \
168 : "=&r" (value), "=r" (res) \
169 : "r" (addr), "i" (-EFAULT));
170
171#define LoadWU(addr, value, res) \
172 __asm__ __volatile__ ( \
155 "sll\t%0, 0x8\n\t" \
156 "or\t%0, $1\n\t" \
157 "li\t%1, 0\n" \
158 "3:\n\t" \
159 ".insn\n\t" \
160 ".set\tat\n\t" \
161 ".section\t.fixup,\"ax\"\n\t" \
162 "4:\tli\t%1, %3\n\t" \
163 "j\t3b\n\t" \
164 ".previous\n\t" \
165 ".section\t__ex_table,\"a\"\n\t" \
166 STR(PTR)"\t1b, 4b\n\t" \
167 STR(PTR)"\t2b, 4b\n\t" \
168 ".previous" \
169 : "=&r" (value), "=r" (res) \
170 : "r" (addr), "i" (-EFAULT));
171
172#define LoadWU(addr, value, res) \
173 __asm__ __volatile__ ( \
173 "1:\tlwl\t%0, (%2)\n" \
174 "2:\tlwr\t%0, 3(%2)\n\t" \
174 "1:\t"user_lwl("%0", "(%2)")"\n" \
175 "2:\t"user_lwr("%0", "3(%2)")"\n\t" \
175 "dsll\t%0, %0, 32\n\t" \
176 "dsrl\t%0, %0, 32\n\t" \
177 "li\t%1, 0\n" \
178 "3:\n\t" \
179 ".insn\n\t" \
180 "\t.section\t.fixup,\"ax\"\n\t" \
181 "4:\tli\t%1, %3\n\t" \
182 "j\t3b\n\t" \

--- 21 unchanged lines hidden (view full) ---

204 STR(PTR)"\t2b, 4b\n\t" \
205 ".previous" \
206 : "=&r" (value), "=r" (res) \
207 : "r" (addr), "i" (-EFAULT));
208
209#define StoreHW(addr, value, res) \
210 __asm__ __volatile__ ( \
211 ".set\tnoat\n" \
176 "dsll\t%0, %0, 32\n\t" \
177 "dsrl\t%0, %0, 32\n\t" \
178 "li\t%1, 0\n" \
179 "3:\n\t" \
180 ".insn\n\t" \
181 "\t.section\t.fixup,\"ax\"\n\t" \
182 "4:\tli\t%1, %3\n\t" \
183 "j\t3b\n\t" \

--- 21 unchanged lines hidden (view full) ---

205 STR(PTR)"\t2b, 4b\n\t" \
206 ".previous" \
207 : "=&r" (value), "=r" (res) \
208 : "r" (addr), "i" (-EFAULT));
209
210#define StoreHW(addr, value, res) \
211 __asm__ __volatile__ ( \
212 ".set\tnoat\n" \
212 "1:\tsb\t%1, 1(%2)\n\t" \
213 "1:\t"user_sb("%1", "1(%2)")"\n" \
213 "srl\t$1, %1, 0x8\n" \
214 "srl\t$1, %1, 0x8\n" \
214 "2:\tsb\t$1, 0(%2)\n\t" \
215 "2:\t"user_sb("$1", "0(%2)")"\n" \
215 ".set\tat\n\t" \
216 "li\t%0, 0\n" \
217 "3:\n\t" \
218 ".insn\n\t" \
219 ".section\t.fixup,\"ax\"\n\t" \
220 "4:\tli\t%0, %3\n\t" \
221 "j\t3b\n\t" \
222 ".previous\n\t" \
223 ".section\t__ex_table,\"a\"\n\t" \
224 STR(PTR)"\t1b, 4b\n\t" \
225 STR(PTR)"\t2b, 4b\n\t" \
226 ".previous" \
227 : "=r" (res) \
228 : "r" (value), "r" (addr), "i" (-EFAULT));
229
230#define StoreW(addr, value, res) \
231 __asm__ __volatile__ ( \
216 ".set\tat\n\t" \
217 "li\t%0, 0\n" \
218 "3:\n\t" \
219 ".insn\n\t" \
220 ".section\t.fixup,\"ax\"\n\t" \
221 "4:\tli\t%0, %3\n\t" \
222 "j\t3b\n\t" \
223 ".previous\n\t" \
224 ".section\t__ex_table,\"a\"\n\t" \
225 STR(PTR)"\t1b, 4b\n\t" \
226 STR(PTR)"\t2b, 4b\n\t" \
227 ".previous" \
228 : "=r" (res) \
229 : "r" (value), "r" (addr), "i" (-EFAULT));
230
231#define StoreW(addr, value, res) \
232 __asm__ __volatile__ ( \
232 "1:\tswl\t%1,(%2)\n" \
233 "2:\tswr\t%1, 3(%2)\n\t" \
233 "1:\t"user_swl("%1", "(%2)")"\n" \
234 "2:\t"user_swr("%1", "3(%2)")"\n\t" \
234 "li\t%0, 0\n" \
235 "3:\n\t" \
236 ".insn\n\t" \
237 ".section\t.fixup,\"ax\"\n\t" \
238 "4:\tli\t%0, %3\n\t" \
239 "j\t3b\n\t" \
240 ".previous\n\t" \
241 ".section\t__ex_table,\"a\"\n\t" \

--- 20 unchanged lines hidden (view full) ---

262 ".previous" \
263 : "=r" (res) \
264 : "r" (value), "r" (addr), "i" (-EFAULT));
265#endif
266
267#ifdef __LITTLE_ENDIAN
268#define LoadHW(addr, value, res) \
269 __asm__ __volatile__ (".set\tnoat\n" \
235 "li\t%0, 0\n" \
236 "3:\n\t" \
237 ".insn\n\t" \
238 ".section\t.fixup,\"ax\"\n\t" \
239 "4:\tli\t%0, %3\n\t" \
240 "j\t3b\n\t" \
241 ".previous\n\t" \
242 ".section\t__ex_table,\"a\"\n\t" \

--- 20 unchanged lines hidden (view full) ---

263 ".previous" \
264 : "=r" (res) \
265 : "r" (value), "r" (addr), "i" (-EFAULT));
266#endif
267
268#ifdef __LITTLE_ENDIAN
269#define LoadHW(addr, value, res) \
270 __asm__ __volatile__ (".set\tnoat\n" \
270 "1:\tlb\t%0, 1(%2)\n" \
271 "2:\tlbu\t$1, 0(%2)\n\t" \
271 "1:\t"user_lb("%0", "1(%2)")"\n" \
272 "2:\t"user_lbu("$1", "0(%2)")"\n\t" \
272 "sll\t%0, 0x8\n\t" \
273 "or\t%0, $1\n\t" \
274 "li\t%1, 0\n" \
275 "3:\t.set\tat\n\t" \
276 ".insn\n\t" \
277 ".section\t.fixup,\"ax\"\n\t" \
278 "4:\tli\t%1, %3\n\t" \
279 "j\t3b\n\t" \
280 ".previous\n\t" \
281 ".section\t__ex_table,\"a\"\n\t" \
282 STR(PTR)"\t1b, 4b\n\t" \
283 STR(PTR)"\t2b, 4b\n\t" \
284 ".previous" \
285 : "=&r" (value), "=r" (res) \
286 : "r" (addr), "i" (-EFAULT));
287
288#define LoadW(addr, value, res) \
289 __asm__ __volatile__ ( \
273 "sll\t%0, 0x8\n\t" \
274 "or\t%0, $1\n\t" \
275 "li\t%1, 0\n" \
276 "3:\t.set\tat\n\t" \
277 ".insn\n\t" \
278 ".section\t.fixup,\"ax\"\n\t" \
279 "4:\tli\t%1, %3\n\t" \
280 "j\t3b\n\t" \
281 ".previous\n\t" \
282 ".section\t__ex_table,\"a\"\n\t" \
283 STR(PTR)"\t1b, 4b\n\t" \
284 STR(PTR)"\t2b, 4b\n\t" \
285 ".previous" \
286 : "=&r" (value), "=r" (res) \
287 : "r" (addr), "i" (-EFAULT));
288
289#define LoadW(addr, value, res) \
290 __asm__ __volatile__ ( \
290 "1:\tlwl\t%0, 3(%2)\n" \
291 "2:\tlwr\t%0, (%2)\n\t" \
291 "1:\t"user_lwl("%0", "3(%2)")"\n" \
292 "2:\t"user_lwr("%0", "(%2)")"\n\t" \
292 "li\t%1, 0\n" \
293 "3:\n\t" \
294 ".insn\n\t" \
295 ".section\t.fixup,\"ax\"\n\t" \
296 "4:\tli\t%1, %3\n\t" \
297 "j\t3b\n\t" \
298 ".previous\n\t" \
299 ".section\t__ex_table,\"a\"\n\t" \
300 STR(PTR)"\t1b, 4b\n\t" \
301 STR(PTR)"\t2b, 4b\n\t" \
302 ".previous" \
303 : "=&r" (value), "=r" (res) \
304 : "r" (addr), "i" (-EFAULT));
305
306#define LoadHWU(addr, value, res) \
307 __asm__ __volatile__ ( \
308 ".set\tnoat\n" \
293 "li\t%1, 0\n" \
294 "3:\n\t" \
295 ".insn\n\t" \
296 ".section\t.fixup,\"ax\"\n\t" \
297 "4:\tli\t%1, %3\n\t" \
298 "j\t3b\n\t" \
299 ".previous\n\t" \
300 ".section\t__ex_table,\"a\"\n\t" \
301 STR(PTR)"\t1b, 4b\n\t" \
302 STR(PTR)"\t2b, 4b\n\t" \
303 ".previous" \
304 : "=&r" (value), "=r" (res) \
305 : "r" (addr), "i" (-EFAULT));
306
307#define LoadHWU(addr, value, res) \
308 __asm__ __volatile__ ( \
309 ".set\tnoat\n" \
309 "1:\tlbu\t%0, 1(%2)\n" \
310 "2:\tlbu\t$1, 0(%2)\n\t" \
310 "1:\t"user_lbu("%0", "1(%2)")"\n" \
311 "2:\t"user_lbu("$1", "0(%2)")"\n\t" \
311 "sll\t%0, 0x8\n\t" \
312 "or\t%0, $1\n\t" \
313 "li\t%1, 0\n" \
314 "3:\n\t" \
315 ".insn\n\t" \
316 ".set\tat\n\t" \
317 ".section\t.fixup,\"ax\"\n\t" \
318 "4:\tli\t%1, %3\n\t" \
319 "j\t3b\n\t" \
320 ".previous\n\t" \
321 ".section\t__ex_table,\"a\"\n\t" \
322 STR(PTR)"\t1b, 4b\n\t" \
323 STR(PTR)"\t2b, 4b\n\t" \
324 ".previous" \
325 : "=&r" (value), "=r" (res) \
326 : "r" (addr), "i" (-EFAULT));
327
328#define LoadWU(addr, value, res) \
329 __asm__ __volatile__ ( \
312 "sll\t%0, 0x8\n\t" \
313 "or\t%0, $1\n\t" \
314 "li\t%1, 0\n" \
315 "3:\n\t" \
316 ".insn\n\t" \
317 ".set\tat\n\t" \
318 ".section\t.fixup,\"ax\"\n\t" \
319 "4:\tli\t%1, %3\n\t" \
320 "j\t3b\n\t" \
321 ".previous\n\t" \
322 ".section\t__ex_table,\"a\"\n\t" \
323 STR(PTR)"\t1b, 4b\n\t" \
324 STR(PTR)"\t2b, 4b\n\t" \
325 ".previous" \
326 : "=&r" (value), "=r" (res) \
327 : "r" (addr), "i" (-EFAULT));
328
329#define LoadWU(addr, value, res) \
330 __asm__ __volatile__ ( \
330 "1:\tlwl\t%0, 3(%2)\n" \
331 "2:\tlwr\t%0, (%2)\n\t" \
331 "1:\t"user_lwl("%0", "3(%2)")"\n" \
332 "2:\t"user_lwr("%0", "(%2)")"\n\t" \
332 "dsll\t%0, %0, 32\n\t" \
333 "dsrl\t%0, %0, 32\n\t" \
334 "li\t%1, 0\n" \
335 "3:\n\t" \
336 ".insn\n\t" \
337 "\t.section\t.fixup,\"ax\"\n\t" \
338 "4:\tli\t%1, %3\n\t" \
339 "j\t3b\n\t" \

--- 21 unchanged lines hidden (view full) ---

361 STR(PTR)"\t2b, 4b\n\t" \
362 ".previous" \
363 : "=&r" (value), "=r" (res) \
364 : "r" (addr), "i" (-EFAULT));
365
366#define StoreHW(addr, value, res) \
367 __asm__ __volatile__ ( \
368 ".set\tnoat\n" \
333 "dsll\t%0, %0, 32\n\t" \
334 "dsrl\t%0, %0, 32\n\t" \
335 "li\t%1, 0\n" \
336 "3:\n\t" \
337 ".insn\n\t" \
338 "\t.section\t.fixup,\"ax\"\n\t" \
339 "4:\tli\t%1, %3\n\t" \
340 "j\t3b\n\t" \

--- 21 unchanged lines hidden (view full) ---

362 STR(PTR)"\t2b, 4b\n\t" \
363 ".previous" \
364 : "=&r" (value), "=r" (res) \
365 : "r" (addr), "i" (-EFAULT));
366
367#define StoreHW(addr, value, res) \
368 __asm__ __volatile__ ( \
369 ".set\tnoat\n" \
369 "1:\tsb\t%1, 0(%2)\n\t" \
370 "1:\t"user_sb("%1", "0(%2)")"\n" \
370 "srl\t$1,%1, 0x8\n" \
371 "srl\t$1,%1, 0x8\n" \
371 "2:\tsb\t$1, 1(%2)\n\t" \
372 "2:\t"user_sb("$1", "1(%2)")"\n" \
372 ".set\tat\n\t" \
373 "li\t%0, 0\n" \
374 "3:\n\t" \
375 ".insn\n\t" \
376 ".section\t.fixup,\"ax\"\n\t" \
377 "4:\tli\t%0, %3\n\t" \
378 "j\t3b\n\t" \
379 ".previous\n\t" \
380 ".section\t__ex_table,\"a\"\n\t" \
381 STR(PTR)"\t1b, 4b\n\t" \
382 STR(PTR)"\t2b, 4b\n\t" \
383 ".previous" \
384 : "=r" (res) \
385 : "r" (value), "r" (addr), "i" (-EFAULT));
386
387#define StoreW(addr, value, res) \
388 __asm__ __volatile__ ( \
373 ".set\tat\n\t" \
374 "li\t%0, 0\n" \
375 "3:\n\t" \
376 ".insn\n\t" \
377 ".section\t.fixup,\"ax\"\n\t" \
378 "4:\tli\t%0, %3\n\t" \
379 "j\t3b\n\t" \
380 ".previous\n\t" \
381 ".section\t__ex_table,\"a\"\n\t" \
382 STR(PTR)"\t1b, 4b\n\t" \
383 STR(PTR)"\t2b, 4b\n\t" \
384 ".previous" \
385 : "=r" (res) \
386 : "r" (value), "r" (addr), "i" (-EFAULT));
387
388#define StoreW(addr, value, res) \
389 __asm__ __volatile__ ( \
389 "1:\tswl\t%1, 3(%2)\n" \
390 "2:\tswr\t%1, (%2)\n\t" \
390 "1:\t"user_swl("%1", "3(%2)")"\n" \
391 "2:\t"user_swr("%1", "(%2)")"\n\t" \
391 "li\t%0, 0\n" \
392 "3:\n\t" \
393 ".insn\n\t" \
394 ".section\t.fixup,\"ax\"\n\t" \
395 "4:\tli\t%0, %3\n\t" \
396 "j\t3b\n\t" \
397 ".previous\n\t" \
398 ".section\t__ex_table,\"a\"\n\t" \

--- 1260 unchanged lines hidden ---
392 "li\t%0, 0\n" \
393 "3:\n\t" \
394 ".insn\n\t" \
395 ".section\t.fixup,\"ax\"\n\t" \
396 "4:\tli\t%0, %3\n\t" \
397 "j\t3b\n\t" \
398 ".previous\n\t" \
399 ".section\t__ex_table,\"a\"\n\t" \

--- 1260 unchanged lines hidden ---