Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / kernel / kprobes-arm.c
CommitLineData
35aa1df4
QB
1/*
2 * arch/arm/kernel/kprobes-decode.c
3 *
4 * Copyright (C) 2006, 2007 Motorola Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 */
15
16/*
17 * We do not have hardware single-stepping on ARM, This
18 * effort is further complicated by the ARM not having a
19 * "next PC" register. Instructions that change the PC
20 * can't be safely single-stepped in a MP environment, so
21 * we have a lot of work to do:
22 *
23 * In the prepare phase:
24 * *) If it is an instruction that does anything
25 * with the CPU mode, we reject it for a kprobe.
26 * (This is out of laziness rather than need. The
27 * instructions could be simulated.)
28 *
29 * *) Otherwise, decode the instruction rewriting its
30 * registers to take fixed, ordered registers and
31 * setting a handler for it to run the instruction.
32 *
33 * In the execution phase by an instruction's handler:
34 *
35 * *) If the PC is written to by the instruction, the
36 * instruction must be fully simulated in software.
35aa1df4
QB
37 *
38 * *) Otherwise, a modified form of the instruction is
39 * directly executed. Its handler calls the
40 * instruction in insn[0]. In insn[1] is a
41 * "mov pc, lr" to return.
42 *
43 * Before calling, load up the reordered registers
44 * from the original instruction's registers. If one
45 * of the original input registers is the PC, compute
46 * and adjust the appropriate input register.
47 *
48 * After call completes, copy the output registers to
49 * the original instruction's original registers.
50 *
51 * We don't use a real breakpoint instruction since that
52 * would have us in the kernel go from SVC mode to SVC
53 * mode losing the link register. Instead we use an
54 * undefined instruction. To simplify processing, the
55 * undefined instruction used for kprobes must be reserved
56 * exclusively for kprobes use.
57 *
58 * TODO: ifdef out some instruction decoding based on architecture.
59 */
60
61#include <linux/kernel.h>
62#include <linux/kprobes.h>
2c89240b 63#include <linux/module.h>
35aa1df4 64
221bf15f
JM
65#include "kprobes.h"
66
35aa1df4
QB
67#define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
68
69#define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25)
70
7be7ee2d
JM
71#if __LINUX_ARM_ARCH__ >= 6
72#define BLX(reg) "blx "reg" \n\t"
73#else
74#define BLX(reg) "mov lr, pc \n\t" \
75 "mov pc, "reg" \n\t"
76#endif
77
35aa1df4
QB
78/*
79 * To avoid the complications of mimicing single-stepping on a
80 * processor without a Next-PC or a single-step mode, and to
81 * avoid having to deal with the side-effects of boosting, we
82 * simulate or emulate (almost) all ARM instructions.
83 *
84 * "Simulation" is where the instruction's behavior is duplicated in
85 * C code. "Emulation" is where the original instruction is rewritten
86 * and executed, often by altering its registers.
87 *
88 * By having all behavior of the kprobe'd instruction completed before
89 * returning from the kprobe_handler(), all locks (scheduler and
90 * interrupt) can safely be released. There is no need for secondary
91 * breakpoints, no race with MP or preemptable kernels, nor having to
92 * clean up resources counts at a later time impacting overall system
93 * performance. By rewriting the instruction, only the minimum registers
94 * need to be loaded and saved back optimizing performance.
95 *
96 * Calling the insnslot_*_rwflags version of a function doesn't hurt
97 * anything even when the CPSR flags aren't updated by the
98 * instruction. It's just a little slower in return for saving
99 * a little space by not having a duplicate function that doesn't
100 * update the flags. (The same optimization can be said for
101 * instructions that do or don't perform register writeback)
102 * Also, instructions can either read the flags, only write the
103 * flags, or read and write the flags. To save combinations
104 * rather than for sheer performance, flag functions just assume
105 * read and write of flags.
106 */
107
108static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs)
109{
35aa1df4
QB
110 kprobe_opcode_t insn = p->opcode;
111 long iaddr = (long)p->addr;
112 int disp = branch_displacement(insn);
113
35aa1df4
QB
114 if (insn & (1 << 24))
115 regs->ARM_lr = iaddr + 4;
116
117 regs->ARM_pc = iaddr + 8 + disp;
118}
119
120static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs)
121{
122 kprobe_opcode_t insn = p->opcode;
123 long iaddr = (long)p->addr;
124 int disp = branch_displacement(insn);
125
126 regs->ARM_lr = iaddr + 4;
127 regs->ARM_pc = iaddr + 8 + disp + ((insn >> 23) & 0x2);
128 regs->ARM_cpsr |= PSR_T_BIT;
129}
130
131static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
132{
35aa1df4
QB
133 kprobe_opcode_t insn = p->opcode;
134 int rm = insn & 0xf;
135 long rmv = regs->uregs[rm];
136
35aa1df4
QB
137 if (insn & (1 << 5))
138 regs->ARM_lr = (long)p->addr + 4;
139
140 regs->ARM_pc = rmv & ~0x1;
141 regs->ARM_cpsr &= ~PSR_T_BIT;
142 if (rmv & 0x1)
143 regs->ARM_cpsr |= PSR_T_BIT;
144}
145
c412aba2
JM
146static void __kprobes simulate_mrs(struct kprobe *p, struct pt_regs *regs)
147{
148 kprobe_opcode_t insn = p->opcode;
149 int rd = (insn >> 12) & 0xf;
150 unsigned long mask = 0xf8ff03df; /* Mask out execution state */
151 regs->uregs[rd] = regs->ARM_cpsr & mask;
152}
153
35aa1df4
QB
154static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs)
155{
156 regs->uregs[12] = regs->uregs[13];
157}
158
8723942f
JM
159static void __kprobes
160emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
161{
162 kprobe_opcode_t insn = p->opcode;
163 unsigned long pc = (unsigned long)p->addr + 8;
164 int rt = (insn >> 12) & 0xf;
165 int rn = (insn >> 16) & 0xf;
166 int rm = insn & 0xf;
167
168 register unsigned long rtv asm("r0") = regs->uregs[rt];
169 register unsigned long rt2v asm("r1") = regs->uregs[rt+1];
170 register unsigned long rnv asm("r2") = (rn == 15) ? pc
171 : regs->uregs[rn];
172 register unsigned long rmv asm("r3") = regs->uregs[rm];
173
174 __asm__ __volatile__ (
175 BLX("%[fn]")
176 : "=r" (rtv), "=r" (rt2v), "=r" (rnv)
177 : "0" (rtv), "1" (rt2v), "2" (rnv), "r" (rmv),
178 [fn] "r" (p->ainsn.insn_fn)
179 : "lr", "memory", "cc"
180 );
181
182 regs->uregs[rt] = rtv;
183 regs->uregs[rt+1] = rt2v;
184 if (is_writeback(insn))
185 regs->uregs[rn] = rnv;
186}
187
3c48fbb1
JM
188static void __kprobes
189emulate_ldr(struct kprobe *p, struct pt_regs *regs)
190{
191 kprobe_opcode_t insn = p->opcode;
192 unsigned long pc = (unsigned long)p->addr + 8;
193 int rt = (insn >> 12) & 0xf;
194 int rn = (insn >> 16) & 0xf;
195 int rm = insn & 0xf;
196
197 register unsigned long rtv asm("r0");
198 register unsigned long rnv asm("r2") = (rn == 15) ? pc
199 : regs->uregs[rn];
200 register unsigned long rmv asm("r3") = regs->uregs[rm];
201
202 __asm__ __volatile__ (
203 BLX("%[fn]")
204 : "=r" (rtv), "=r" (rnv)
205 : "1" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn)
206 : "lr", "memory", "cc"
207 );
208
209 if (rt == 15)
210 load_write_pc(rtv, regs);
211 else
212 regs->uregs[rt] = rtv;
213
214 if (is_writeback(insn))
215 regs->uregs[rn] = rnv;
216}
217
218static void __kprobes
219emulate_str(struct kprobe *p, struct pt_regs *regs)
220{
221 kprobe_opcode_t insn = p->opcode;
222 unsigned long rtpc = (unsigned long)p->addr + str_pc_offset;
223 unsigned long rnpc = (unsigned long)p->addr + 8;
224 int rt = (insn >> 12) & 0xf;
225 int rn = (insn >> 16) & 0xf;
226 int rm = insn & 0xf;
227
228 register unsigned long rtv asm("r0") = (rt == 15) ? rtpc
229 : regs->uregs[rt];
230 register unsigned long rnv asm("r2") = (rn == 15) ? rnpc
231 : regs->uregs[rn];
232 register unsigned long rmv asm("r3") = regs->uregs[rm];
233
234 __asm__ __volatile__ (
235 BLX("%[fn]")
236 : "=r" (rnv)
237 : "r" (rtv), "0" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn)
238 : "lr", "memory", "cc"
239 );
240
241 if (is_writeback(insn))
242 regs->uregs[rn] = rnv;
243}
244
9f596e51
JM
245static void __kprobes
246emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs)
247{
248 kprobe_opcode_t insn = p->opcode;
249 unsigned long pc = (unsigned long)p->addr + 8;
250 int rd = (insn >> 12) & 0xf;
251 int rn = (insn >> 16) & 0xf;
252 int rm = insn & 0xf;
253 int rs = (insn >> 8) & 0xf;
254
255 register unsigned long rdv asm("r0") = regs->uregs[rd];
256 register unsigned long rnv asm("r2") = (rn == 15) ? pc
257 : regs->uregs[rn];
258 register unsigned long rmv asm("r3") = (rm == 15) ? pc
259 : regs->uregs[rm];
260 register unsigned long rsv asm("r1") = regs->uregs[rs];
261 unsigned long cpsr = regs->ARM_cpsr;
262
263 __asm__ __volatile__ (
264 "msr cpsr_fs, %[cpsr] \n\t"
265 BLX("%[fn]")
266 "mrs %[cpsr], cpsr \n\t"
267 : "=r" (rdv), [cpsr] "=r" (cpsr)
268 : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
269 "1" (cpsr), [fn] "r" (p->ainsn.insn_fn)
270 : "lr", "memory", "cc"
271 );
272
273 if (rd == 15)
274 alu_write_pc(rdv, regs);
275 else
276 regs->uregs[rd] = rdv;
277 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
278}
279
0e44e9a0
JM
280static void __kprobes
281emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
282{
283 kprobe_opcode_t insn = p->opcode;
284 int rd = (insn >> 12) & 0xf;
285 int rn = (insn >> 16) & 0xf;
286 int rm = insn & 0xf;
287
288 register unsigned long rdv asm("r0") = regs->uregs[rd];
289 register unsigned long rnv asm("r2") = regs->uregs[rn];
290 register unsigned long rmv asm("r3") = regs->uregs[rm];
291 unsigned long cpsr = regs->ARM_cpsr;
292
293 __asm__ __volatile__ (
294 "msr cpsr_fs, %[cpsr] \n\t"
295 BLX("%[fn]")
296 "mrs %[cpsr], cpsr \n\t"
297 : "=r" (rdv), [cpsr] "=r" (cpsr)
298 : "0" (rdv), "r" (rnv), "r" (rmv),
299 "1" (cpsr), [fn] "r" (p->ainsn.insn_fn)
300 : "lr", "memory", "cc"
301 );
302
303 regs->uregs[rd] = rdv;
304 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
305}
306
6091dfae
JM
307static void __kprobes
308emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
309{
310 kprobe_opcode_t insn = p->opcode;
311 int rd = (insn >> 16) & 0xf;
312 int rn = (insn >> 12) & 0xf;
313 int rm = insn & 0xf;
314 int rs = (insn >> 8) & 0xf;
315
316 register unsigned long rdv asm("r2") = regs->uregs[rd];
317 register unsigned long rnv asm("r0") = regs->uregs[rn];
318 register unsigned long rmv asm("r3") = regs->uregs[rm];
319 register unsigned long rsv asm("r1") = regs->uregs[rs];
320 unsigned long cpsr = regs->ARM_cpsr;
321
322 __asm__ __volatile__ (
323 "msr cpsr_fs, %[cpsr] \n\t"
324 BLX("%[fn]")
325 "mrs %[cpsr], cpsr \n\t"
326 : "=r" (rdv), [cpsr] "=r" (cpsr)
327 : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
328 "1" (cpsr), [fn] "r" (p->ainsn.insn_fn)
329 : "lr", "memory", "cc"
330 );
331
332 regs->uregs[rd] = rdv;
333 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
334}
335
c82584eb
JM
336static void __kprobes
337emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs)
338{
339 kprobe_opcode_t insn = p->opcode;
340 int rd = (insn >> 12) & 0xf;
341 int rm = insn & 0xf;
342
343 register unsigned long rdv asm("r0") = regs->uregs[rd];
344 register unsigned long rmv asm("r3") = regs->uregs[rm];
345
346 __asm__ __volatile__ (
347 BLX("%[fn]")
348 : "=r" (rdv)
349 : "0" (rdv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn)
350 : "lr", "memory", "cc"
351 );
352
353 regs->uregs[rd] = rdv;
354}
355
12ce5d33
JM
356static void __kprobes
357emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
358{
359 kprobe_opcode_t insn = p->opcode;
360 int rdlo = (insn >> 12) & 0xf;
361 int rdhi = (insn >> 16) & 0xf;
362 int rn = insn & 0xf;
363 int rm = (insn >> 8) & 0xf;
364
365 register unsigned long rdlov asm("r0") = regs->uregs[rdlo];
366 register unsigned long rdhiv asm("r2") = regs->uregs[rdhi];
367 register unsigned long rnv asm("r3") = regs->uregs[rn];
368 register unsigned long rmv asm("r1") = regs->uregs[rm];
369 unsigned long cpsr = regs->ARM_cpsr;
370
371 __asm__ __volatile__ (
372 "msr cpsr_fs, %[cpsr] \n\t"
373 BLX("%[fn]")
374 "mrs %[cpsr], cpsr \n\t"
375 : "=r" (rdlov), "=r" (rdhiv), [cpsr] "=r" (cpsr)
376 : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv),
377 "2" (cpsr), [fn] "r" (p->ainsn.insn_fn)
378 : "lr", "memory", "cc"
379 );
380
381 regs->uregs[rdlo] = rdlov;
382 regs->uregs[rdhi] = rdhiv;
383 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
384}
385
35aa1df4
QB
386/*
387 * For the instruction masking and comparisons in all the "space_*"
388 * functions below, Do _not_ rearrange the order of tests unless
389 * you're very, very sure of what you are doing. For the sake of
390 * efficiency, the masks for some tests sometimes assume other test
391 * have been done prior to them so the number of patterns to test
392 * for an instruction set can be as broad as possible to reduce the
393 * number of tests needed.
394 */
395
9a5c1284
JM
396static const union decode_item arm_1111_table[] = {
397 /* Unconditional instructions */
35aa1df4 398
9a5c1284
JM
399 /* memory hint 1111 0100 x001 xxxx xxxx xxxx xxxx xxxx */
400 /* PLDI (immediate) 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx */
401 /* PLDW (immediate) 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx */
402 /* PLD (immediate) 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx */
403 DECODE_SIMULATE (0xfe300000, 0xf4100000, kprobe_simulate_nop),
35aa1df4 404
0239269d
JM
405 /* memory hint 1111 0110 x001 xxxx xxxx xxxx xxx0 xxxx */
406 /* PLDI (register) 1111 0110 x101 xxxx xxxx xxxx xxx0 xxxx */
407 /* PLDW (register) 1111 0111 x001 xxxx xxxx xxxx xxx0 xxxx */
408 /* PLD (register) 1111 0111 x101 xxxx xxxx xxxx xxx0 xxxx */
409 DECODE_SIMULATE (0xfe300010, 0xf6100000, kprobe_simulate_nop),
410
9a5c1284
JM
411 /* BLX (immediate) 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx */
412 DECODE_SIMULATE (0xfe000000, 0xfa000000, simulate_blx1),
72c2bab2 413
9a5c1284
JM
414 /* CPS 1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */
415 /* SETEND 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */
416 /* SRS 1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
417 /* RFE 1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
35aa1df4 418
fa1a03b4 419 /* Coprocessor instructions... */
9a5c1284
JM
420 /* MCRR2 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx */
421 /* MRRC2 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx */
422 /* LDC2 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
423 /* STC2 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
424 /* CDP2 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
425 /* MCR2 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
426 /* MRC2 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
427
428 /* Other unallocated instructions... */
429 DECODE_END
430};
35aa1df4 431
75f115c0
JM
432static const union decode_item arm_cccc_0001_0xx0____0xxx_table[] = {
433 /* Miscellaneous instructions */
434
435 /* MRS cpsr cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */
436 DECODE_SIMULATEX(0x0ff000f0, 0x01000000, simulate_mrs,
437 REGS(0, NOPC, 0, 0, 0)),
438
439 /* BX cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
440 DECODE_SIMULATE (0x0ff000f0, 0x01200010, simulate_blx2bx),
441
442 /* BLX (register) cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
443 DECODE_SIMULATEX(0x0ff000f0, 0x01200030, simulate_blx2bx,
444 REGS(0, 0, 0, 0, NOPC)),
445
446 /* CLZ cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
c82584eb
JM
447 DECODE_EMULATEX (0x0ff000f0, 0x01600010, emulate_rd12rm0_noflags_nopc,
448 REGS(0, NOPC, 0, 0, NOPC)),
75f115c0
JM
449
450 /* QADD cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx */
451 /* QSUB cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx */
452 /* QDADD cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx */
453 /* QDSUB cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx */
35fab774
JM
454 DECODE_EMULATEX (0x0f9000f0, 0x01000050, emulate_rd12rn16rm0_rwflags_nopc,
455 REGS(NOPC, NOPC, 0, 0, NOPC)),
75f115c0
JM
456
457 /* BXJ cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
458 /* MSR cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
459 /* MRS spsr cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */
460 /* BKPT 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
461 /* SMC cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */
462 /* And unallocated instructions... */
463 DECODE_END
464};
465
466static const union decode_item arm_cccc_0001_0xx0____1xx0_table[] = {
467 /* Halfword multiply and multiply-accumulate */
468
469 /* SMLALxy cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
12ce5d33
JM
470 DECODE_EMULATEX (0x0ff00090, 0x01400080, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc,
471 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
75f115c0
JM
472
473 /* SMULWy cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
474 DECODE_OR (0x0ff000b0, 0x012000a0),
475 /* SMULxy cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
6091dfae
JM
476 DECODE_EMULATEX (0x0ff00090, 0x01600080, emulate_rd16rn12rm0rs8_rwflags_nopc,
477 REGS(NOPC, 0, NOPC, 0, NOPC)),
75f115c0
JM
478
479 /* SMLAxy cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx */
480 DECODE_OR (0x0ff00090, 0x01000080),
481 /* SMLAWy cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx */
6091dfae
JM
482 DECODE_EMULATEX (0x0ff000b0, 0x01200080, emulate_rd16rn12rm0rs8_rwflags_nopc,
483 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
75f115c0
JM
484
485 DECODE_END
486};
487
488static const union decode_item arm_cccc_0000_____1001_table[] = {
489 /* Multiply and multiply-accumulate */
490
491 /* MUL cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx */
492 /* MULS cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx */
6091dfae
JM
493 DECODE_EMULATEX (0x0fe000f0, 0x00000090, emulate_rd16rn12rm0rs8_rwflags_nopc,
494 REGS(NOPC, 0, NOPC, 0, NOPC)),
75f115c0
JM
495
496 /* MLA cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx */
497 /* MLAS cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx */
498 DECODE_OR (0x0fe000f0, 0x00200090),
499 /* MLS cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx */
6091dfae
JM
500 DECODE_EMULATEX (0x0ff000f0, 0x00600090, emulate_rd16rn12rm0rs8_rwflags_nopc,
501 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
75f115c0
JM
502
503 /* UMAAL cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx */
504 DECODE_OR (0x0ff000f0, 0x00400090),
505 /* UMULL cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx */
506 /* UMULLS cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx */
507 /* UMLAL cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx */
508 /* UMLALS cccc 0000 1011 xxxx xxxx xxxx 1001 xxxx */
509 /* SMULL cccc 0000 1100 xxxx xxxx xxxx 1001 xxxx */
510 /* SMULLS cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx */
511 /* SMLAL cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx */
512 /* SMLALS cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx */
12ce5d33
JM
513 DECODE_EMULATEX (0x0f8000f0, 0x00800090, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc,
514 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
75f115c0
JM
515
516 DECODE_END
517};
518
519static const union decode_item arm_cccc_0001_____1001_table[] = {
520 /* Synchronization primitives */
521
b5bed7fe
JMT
522#if __LINUX_ARM_ARCH__ < 6
523 /* Deprecated on ARMv6 and may be UNDEFINED on v7 */
75f115c0 524 /* SMP/SWPB cccc 0001 0x00 xxxx xxxx xxxx 1001 xxxx */
35fab774
JM
525 DECODE_EMULATEX (0x0fb000f0, 0x01000090, emulate_rd12rn16rm0_rwflags_nopc,
526 REGS(NOPC, NOPC, 0, 0, NOPC)),
b5bed7fe 527#endif
75f115c0
JM
528 /* LDREX/STREX{,D,B,H} cccc 0001 1xxx xxxx xxxx xxxx 1001 xxxx */
529 /* And unallocated instructions... */
530 DECODE_END
531};
532
6c8a1929 533static const union decode_item arm_cccc_000x_____1xx1_table[] = {
75f115c0
JM
534 /* Extra load/store instructions */
535
465f1ea5
JM
536 /* STRHT cccc 0000 xx10 xxxx xxxx xxxx 1011 xxxx */
537 /* ??? cccc 0000 xx10 xxxx xxxx xxxx 11x1 xxxx */
538 /* LDRHT cccc 0000 xx11 xxxx xxxx xxxx 1011 xxxx */
539 /* LDRSBT cccc 0000 xx11 xxxx xxxx xxxx 1101 xxxx */
540 /* LDRSHT cccc 0000 xx11 xxxx xxxx xxxx 1111 xxxx */
541 DECODE_REJECT (0x0f200090, 0x00200090),
542
6c8a1929
JM
543 /* LDRD/STRD lr,pc,{... cccc 000x x0x0 xxxx 111x xxxx 1101 xxxx */
544 DECODE_REJECT (0x0e10e0d0, 0x0000e0d0),
545
546 /* LDRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx */
547 /* STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx */
548 DECODE_EMULATEX (0x0e5000d0, 0x000000d0, emulate_ldrdstrd,
549 REGS(NOPCWB, NOPCX, 0, 0, NOPC)),
550
551 /* LDRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx */
552 /* STRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx */
553 DECODE_EMULATEX (0x0e5000d0, 0x004000d0, emulate_ldrdstrd,
554 REGS(NOPCWB, NOPCX, 0, 0, 0)),
555
75f115c0 556 /* STRH (register) cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx */
711bf106
JM
557 DECODE_EMULATEX (0x0e5000f0, 0x000000b0, emulate_str,
558 REGS(NOPCWB, NOPC, 0, 0, NOPC)),
559
75f115c0
JM
560 /* LDRH (register) cccc 000x x0x1 xxxx xxxx xxxx 1011 xxxx */
561 /* LDRSB (register) cccc 000x x0x1 xxxx xxxx xxxx 1101 xxxx */
562 /* LDRSH (register) cccc 000x x0x1 xxxx xxxx xxxx 1111 xxxx */
711bf106
JM
563 DECODE_EMULATEX (0x0e500090, 0x00100090, emulate_ldr,
564 REGS(NOPCWB, NOPC, 0, 0, NOPC)),
565
75f115c0 566 /* STRH (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1011 xxxx */
711bf106
JM
567 DECODE_EMULATEX (0x0e5000f0, 0x004000b0, emulate_str,
568 REGS(NOPCWB, NOPC, 0, 0, 0)),
569
75f115c0
JM
570 /* LDRH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1011 xxxx */
571 /* LDRSB (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1101 xxxx */
572 /* LDRSH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1111 xxxx */
711bf106
JM
573 DECODE_EMULATEX (0x0e500090, 0x00500090, emulate_ldr,
574 REGS(NOPCWB, NOPC, 0, 0, 0)),
75f115c0 575
6c8a1929
JM
576 DECODE_END
577};
578
3535a89a
JM
579static const union decode_item arm_cccc_000x_table[] = {
580 /* Data-processing (register) */
581
582 /* <op>S PC, ... cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx */
583 DECODE_REJECT (0x0e10f000, 0x0010f000),
584
585 /* MOV IP, SP 1110 0001 1010 0000 1100 0000 0000 1101 */
586 DECODE_SIMULATE (0xffffffff, 0xe1a0c00d, simulate_mov_ipsp),
587
588 /* TST (register) cccc 0001 0001 xxxx xxxx xxxx xxx0 xxxx */
589 /* TEQ (register) cccc 0001 0011 xxxx xxxx xxxx xxx0 xxxx */
590 /* CMP (register) cccc 0001 0101 xxxx xxxx xxxx xxx0 xxxx */
591 /* CMN (register) cccc 0001 0111 xxxx xxxx xxxx xxx0 xxxx */
592 DECODE_EMULATEX (0x0f900010, 0x01100000, emulate_rd12rn16rm0rs8_rwflags,
593 REGS(ANY, 0, 0, 0, ANY)),
594
595 /* MOV (register) cccc 0001 101x xxxx xxxx xxxx xxx0 xxxx */
596 /* MVN (register) cccc 0001 111x xxxx xxxx xxxx xxx0 xxxx */
597 DECODE_EMULATEX (0x0fa00010, 0x01a00000, emulate_rd12rn16rm0rs8_rwflags,
598 REGS(0, ANY, 0, 0, ANY)),
599
600 /* AND (register) cccc 0000 000x xxxx xxxx xxxx xxx0 xxxx */
601 /* EOR (register) cccc 0000 001x xxxx xxxx xxxx xxx0 xxxx */
602 /* SUB (register) cccc 0000 010x xxxx xxxx xxxx xxx0 xxxx */
603 /* RSB (register) cccc 0000 011x xxxx xxxx xxxx xxx0 xxxx */
604 /* ADD (register) cccc 0000 100x xxxx xxxx xxxx xxx0 xxxx */
605 /* ADC (register) cccc 0000 101x xxxx xxxx xxxx xxx0 xxxx */
606 /* SBC (register) cccc 0000 110x xxxx xxxx xxxx xxx0 xxxx */
607 /* RSC (register) cccc 0000 111x xxxx xxxx xxxx xxx0 xxxx */
608 /* ORR (register) cccc 0001 100x xxxx xxxx xxxx xxx0 xxxx */
609 /* BIC (register) cccc 0001 110x xxxx xxxx xxxx xxx0 xxxx */
610 DECODE_EMULATEX (0x0e000010, 0x00000000, emulate_rd12rn16rm0rs8_rwflags,
611 REGS(ANY, ANY, 0, 0, ANY)),
612
613 /* TST (reg-shift reg) cccc 0001 0001 xxxx xxxx xxxx 0xx1 xxxx */
614 /* TEQ (reg-shift reg) cccc 0001 0011 xxxx xxxx xxxx 0xx1 xxxx */
615 /* CMP (reg-shift reg) cccc 0001 0101 xxxx xxxx xxxx 0xx1 xxxx */
616 /* CMN (reg-shift reg) cccc 0001 0111 xxxx xxxx xxxx 0xx1 xxxx */
617 DECODE_EMULATEX (0x0f900090, 0x01100010, emulate_rd12rn16rm0rs8_rwflags,
618 REGS(ANY, 0, NOPC, 0, ANY)),
619
620 /* MOV (reg-shift reg) cccc 0001 101x xxxx xxxx xxxx 0xx1 xxxx */
621 /* MVN (reg-shift reg) cccc 0001 111x xxxx xxxx xxxx 0xx1 xxxx */
622 DECODE_EMULATEX (0x0fa00090, 0x01a00010, emulate_rd12rn16rm0rs8_rwflags,
623 REGS(0, ANY, NOPC, 0, ANY)),
624
625 /* AND (reg-shift reg) cccc 0000 000x xxxx xxxx xxxx 0xx1 xxxx */
626 /* EOR (reg-shift reg) cccc 0000 001x xxxx xxxx xxxx 0xx1 xxxx */
627 /* SUB (reg-shift reg) cccc 0000 010x xxxx xxxx xxxx 0xx1 xxxx */
628 /* RSB (reg-shift reg) cccc 0000 011x xxxx xxxx xxxx 0xx1 xxxx */
629 /* ADD (reg-shift reg) cccc 0000 100x xxxx xxxx xxxx 0xx1 xxxx */
630 /* ADC (reg-shift reg) cccc 0000 101x xxxx xxxx xxxx 0xx1 xxxx */
631 /* SBC (reg-shift reg) cccc 0000 110x xxxx xxxx xxxx 0xx1 xxxx */
632 /* RSC (reg-shift reg) cccc 0000 111x xxxx xxxx xxxx 0xx1 xxxx */
633 /* ORR (reg-shift reg) cccc 0001 100x xxxx xxxx xxxx 0xx1 xxxx */
634 /* BIC (reg-shift reg) cccc 0001 110x xxxx xxxx xxxx 0xx1 xxxx */
635 DECODE_EMULATEX (0x0e000090, 0x00000010, emulate_rd12rn16rm0rs8_rwflags,
636 REGS(ANY, ANY, NOPC, 0, ANY)),
637
638 DECODE_END
639};
640
c038f3af
JM
641static const union decode_item arm_cccc_001x_table[] = {
642 /* Data-processing (immediate) */
643
644 /* MOVW cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
645 /* MOVT cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
c82584eb
JM
646 DECODE_EMULATEX (0x0fb00000, 0x03000000, emulate_rd12rm0_noflags_nopc,
647 REGS(0, NOPC, 0, 0, 0)),
c038f3af
JM
648
649 /* YIELD cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
650 DECODE_OR (0x0fff00ff, 0x03200001),
651 /* SEV cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
652 DECODE_EMULATE (0x0fff00ff, 0x03200004, kprobe_emulate_none),
653 /* NOP cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
654 /* WFE cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
655 /* WFI cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
656 DECODE_SIMULATE (0x0fff00fc, 0x03200000, kprobe_simulate_nop),
657 /* DBG cccc 0011 0010 0000 xxxx xxxx ffff xxxx */
658 /* unallocated hints cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
659 /* MSR (immediate) cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */
660 DECODE_REJECT (0x0fb00000, 0x03200000),
661
662 /* <op>S PC, ... cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx */
663 DECODE_REJECT (0x0e10f000, 0x0210f000),
664
665 /* TST (immediate) cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx */
666 /* TEQ (immediate) cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx */
667 /* CMP (immediate) cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx */
668 /* CMN (immediate) cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx */
669 DECODE_EMULATEX (0x0f900000, 0x03100000, emulate_rd12rn16rm0rs8_rwflags,
670 REGS(ANY, 0, 0, 0, 0)),
671
672 /* MOV (immediate) cccc 0011 101x xxxx xxxx xxxx xxxx xxxx */
673 /* MVN (immediate) cccc 0011 111x xxxx xxxx xxxx xxxx xxxx */
674 DECODE_EMULATEX (0x0fa00000, 0x03a00000, emulate_rd12rn16rm0rs8_rwflags,
675 REGS(0, ANY, 0, 0, 0)),
676
677 /* AND (immediate) cccc 0010 000x xxxx xxxx xxxx xxxx xxxx */
678 /* EOR (immediate) cccc 0010 001x xxxx xxxx xxxx xxxx xxxx */
679 /* SUB (immediate) cccc 0010 010x xxxx xxxx xxxx xxxx xxxx */
680 /* RSB (immediate) cccc 0010 011x xxxx xxxx xxxx xxxx xxxx */
681 /* ADD (immediate) cccc 0010 100x xxxx xxxx xxxx xxxx xxxx */
682 /* ADC (immediate) cccc 0010 101x xxxx xxxx xxxx xxxx xxxx */
683 /* SBC (immediate) cccc 0010 110x xxxx xxxx xxxx xxxx xxxx */
684 /* RSC (immediate) cccc 0010 111x xxxx xxxx xxxx xxxx xxxx */
685 /* ORR (immediate) cccc 0011 100x xxxx xxxx xxxx xxxx xxxx */
686 /* BIC (immediate) cccc 0011 110x xxxx xxxx xxxx xxxx xxxx */
687 DECODE_EMULATEX (0x0e000000, 0x02000000, emulate_rd12rn16rm0rs8_rwflags,
688 REGS(ANY, ANY, 0, 0, 0)),
94254930 689
c038f3af
JM
690 DECODE_END
691};
35aa1df4 692
2ce5d033
JM
693static const union decode_item arm_cccc_0110_____xxx1_table[] = {
694 /* Media instructions */
695
696 /* SEL cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx */
697 DECODE_EMULATEX (0x0ff000f0, 0x068000b0, emulate_rd12rn16rm0_rwflags_nopc,
698 REGS(NOPC, NOPC, 0, 0, NOPC)),
699
700 /* SSAT cccc 0110 101x xxxx xxxx xxxx xx01 xxxx */
701 /* USAT cccc 0110 111x xxxx xxxx xxxx xx01 xxxx */
702 DECODE_OR(0x0fa00030, 0x06a00010),
703 /* SSAT16 cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx */
704 /* USAT16 cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx */
705 DECODE_EMULATEX (0x0fb000f0, 0x06a00030, emulate_rd12rn16rm0_rwflags_nopc,
706 REGS(0, NOPC, 0, 0, NOPC)),
707
708 /* REV cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */
709 /* REV16 cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
710 /* RBIT cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */
711 /* REVSH cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
c82584eb
JM
712 DECODE_EMULATEX (0x0fb00070, 0x06b00030, emulate_rd12rm0_noflags_nopc,
713 REGS(0, NOPC, 0, 0, NOPC)),
2ce5d033
JM
714
715 /* ??? cccc 0110 0x00 xxxx xxxx xxxx xxx1 xxxx */
716 DECODE_REJECT (0x0fb00010, 0x06000010),
717 /* ??? cccc 0110 0xxx xxxx xxxx xxxx 1011 xxxx */
718 DECODE_REJECT (0x0f8000f0, 0x060000b0),
719 /* ??? cccc 0110 0xxx xxxx xxxx xxxx 1101 xxxx */
720 DECODE_REJECT (0x0f8000f0, 0x060000d0),
721 /* SADD16 cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx */
722 /* SADDSUBX cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx */
723 /* SSUBADDX cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx */
724 /* SSUB16 cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx */
725 /* SADD8 cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx */
726 /* SSUB8 cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx */
727 /* QADD16 cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx */
728 /* QADDSUBX cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx */
729 /* QSUBADDX cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx */
730 /* QSUB16 cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx */
731 /* QADD8 cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx */
732 /* QSUB8 cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx */
733 /* SHADD16 cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx */
734 /* SHADDSUBX cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx */
735 /* SHSUBADDX cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx */
736 /* SHSUB16 cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx */
737 /* SHADD8 cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx */
738 /* SHSUB8 cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx */
739 /* UADD16 cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx */
740 /* UADDSUBX cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx */
741 /* USUBADDX cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx */
742 /* USUB16 cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx */
743 /* UADD8 cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx */
744 /* USUB8 cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx */
745 /* UQADD16 cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx */
746 /* UQADDSUBX cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx */
747 /* UQSUBADDX cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx */
748 /* UQSUB16 cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx */
749 /* UQADD8 cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx */
750 /* UQSUB8 cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx */
751 /* UHADD16 cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx */
752 /* UHADDSUBX cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx */
753 /* UHSUBADDX cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx */
754 /* UHSUB16 cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx */
755 /* UHADD8 cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx */
756 /* UHSUB8 cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx */
35fab774
JM
757 DECODE_EMULATEX (0x0f800010, 0x06000010, emulate_rd12rn16rm0_rwflags_nopc,
758 REGS(NOPC, NOPC, 0, 0, NOPC)),
2ce5d033
JM
759
760 /* PKHBT cccc 0110 1000 xxxx xxxx xxxx x001 xxxx */
761 /* PKHTB cccc 0110 1000 xxxx xxxx xxxx x101 xxxx */
35fab774
JM
762 DECODE_EMULATEX (0x0ff00030, 0x06800010, emulate_rd12rn16rm0_rwflags_nopc,
763 REGS(NOPC, NOPC, 0, 0, NOPC)),
2ce5d033
JM
764
765 /* ??? cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx */
766 /* ??? cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx */
767 DECODE_REJECT (0x0fb000f0, 0x06900070),
768
769 /* SXTB16 cccc 0110 1000 1111 xxxx xxxx 0111 xxxx */
770 /* SXTB cccc 0110 1010 1111 xxxx xxxx 0111 xxxx */
771 /* SXTH cccc 0110 1011 1111 xxxx xxxx 0111 xxxx */
772 /* UXTB16 cccc 0110 1100 1111 xxxx xxxx 0111 xxxx */
773 /* UXTB cccc 0110 1110 1111 xxxx xxxx 0111 xxxx */
774 /* UXTH cccc 0110 1111 1111 xxxx xxxx 0111 xxxx */
c82584eb
JM
775 DECODE_EMULATEX (0x0f8f00f0, 0x068f0070, emulate_rd12rm0_noflags_nopc,
776 REGS(0, NOPC, 0, 0, NOPC)),
2ce5d033
JM
777
778 /* SXTAB16 cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx */
779 /* SXTAB cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx */
780 /* SXTAH cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx */
781 /* UXTAB16 cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx */
782 /* UXTAB cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx */
783 /* UXTAH cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx */
35fab774
JM
784 DECODE_EMULATEX (0x0f8000f0, 0x06800070, emulate_rd12rn16rm0_rwflags_nopc,
785 REGS(NOPCX, NOPC, 0, 0, NOPC)),
780b5c11 786
2ce5d033
JM
787 DECODE_END
788};
35aa1df4 789
ad2e81a7
JM
790static const union decode_item arm_cccc_0111_____xxx1_table[] = {
791 /* Media instructions */
35aa1df4 792
ad2e81a7
JM
793 /* UNDEFINED cccc 0111 1111 xxxx xxxx xxxx 1111 xxxx */
794 DECODE_REJECT (0x0ff000f0, 0x07f000f0),
038c3839 795
ad2e81a7
JM
796 /* SMLALD cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
797 /* SMLSLD cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
12ce5d33
JM
798 DECODE_EMULATEX (0x0ff00090, 0x07400010, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc,
799 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
35aa1df4 800
ad2e81a7
JM
801 /* SMUAD cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx */
802 /* SMUSD cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx */
803 DECODE_OR (0x0ff0f090, 0x0700f010),
804 /* SMMUL cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx */
805 DECODE_OR (0x0ff0f0d0, 0x0750f010),
806 /* USAD8 cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */
6091dfae
JM
807 DECODE_EMULATEX (0x0ff0f0f0, 0x0780f010, emulate_rd16rn12rm0rs8_rwflags_nopc,
808 REGS(NOPC, 0, NOPC, 0, NOPC)),
20e8155e 809
ad2e81a7
JM
810 /* SMLAD cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx */
811 /* SMLSD cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx */
812 DECODE_OR (0x0ff00090, 0x07000010),
813 /* SMMLA cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx */
814 DECODE_OR (0x0ff000d0, 0x07500010),
815 /* USADA8 cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */
6091dfae
JM
816 DECODE_EMULATEX (0x0ff000f0, 0x07800010, emulate_rd16rn12rm0rs8_rwflags_nopc,
817 REGS(NOPC, NOPCX, NOPC, 0, NOPC)),
20e8155e 818
ad2e81a7 819 /* SMMLS cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx */
6091dfae
JM
820 DECODE_EMULATEX (0x0ff000d0, 0x075000d0, emulate_rd16rn12rm0rs8_rwflags_nopc,
821 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
20e8155e 822
ad2e81a7
JM
823 /* SBFX cccc 0111 101x xxxx xxxx xxxx x101 xxxx */
824 /* UBFX cccc 0111 111x xxxx xxxx xxxx x101 xxxx */
c82584eb
JM
825 DECODE_EMULATEX (0x0fa00070, 0x07a00050, emulate_rd12rm0_noflags_nopc,
826 REGS(0, NOPC, 0, 0, NOPC)),
ad2e81a7
JM
827
828 /* BFC cccc 0111 110x xxxx xxxx xxxx x001 1111 */
c82584eb
JM
829 DECODE_EMULATEX (0x0fe0007f, 0x07c0001f, emulate_rd12rm0_noflags_nopc,
830 REGS(0, NOPC, 0, 0, 0)),
ad2e81a7
JM
831
832 /* BFI cccc 0111 110x xxxx xxxx xxxx x001 xxxx */
c82584eb
JM
833 DECODE_EMULATEX (0x0fe00070, 0x07c00010, emulate_rd12rm0_noflags_nopc,
834 REGS(0, NOPC, 0, 0, NOPCX)),
ad2e81a7
JM
835
836 DECODE_END
837};
35aa1df4 838
56d8fbdd
JM
839static const union decode_item arm_cccc_01xx_table[] = {
840 /* Load/store word and unsigned byte */
841
842 /* LDRB/STRB pc,[...] cccc 01xx x0xx xxxx xxxx xxxx xxxx xxxx */
843 DECODE_REJECT (0x0c40f000, 0x0440f000),
844
465f1ea5
JM
845 /* STRT cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
846 /* LDRT cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */
847 /* STRBT cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
848 /* LDRBT cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */
849 DECODE_REJECT (0x0d200000, 0x04200000),
850
711bf106
JM
851 /* STR (immediate) cccc 010x x0x0 xxxx xxxx xxxx xxxx xxxx */
852 /* STRB (immediate) cccc 010x x1x0 xxxx xxxx xxxx xxxx xxxx */
853 DECODE_EMULATEX (0x0e100000, 0x04000000, emulate_str,
854 REGS(NOPCWB, ANY, 0, 0, 0)),
855
856 /* LDR (immediate) cccc 010x x0x1 xxxx xxxx xxxx xxxx xxxx */
857 /* LDRB (immediate) cccc 010x x1x1 xxxx xxxx xxxx xxxx xxxx */
858 DECODE_EMULATEX (0x0e100000, 0x04100000, emulate_ldr,
859 REGS(NOPCWB, ANY, 0, 0, 0)),
860
861 /* STR (register) cccc 011x x0x0 xxxx xxxx xxxx xxxx xxxx */
862 /* STRB (register) cccc 011x x1x0 xxxx xxxx xxxx xxxx xxxx */
863 DECODE_EMULATEX (0x0e100000, 0x06000000, emulate_str,
864 REGS(NOPCWB, ANY, 0, 0, NOPC)),
865
866 /* LDR (register) cccc 011x x0x1 xxxx xxxx xxxx xxxx xxxx */
867 /* LDRB (register) cccc 011x x1x1 xxxx xxxx xxxx xxxx xxxx */
868 DECODE_EMULATEX (0x0e100000, 0x06100000, emulate_ldr,
869 REGS(NOPCWB, ANY, 0, 0, NOPC)),
56d8fbdd
JM
870
871 DECODE_END
872};
35aa1df4 873
0d32e7d1
JM
874static const union decode_item arm_cccc_100x_table[] = {
875 /* Block data transfer instructions */
876
877 /* LDM cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
878 /* STM cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
879 DECODE_CUSTOM (0x0e400000, 0x08000000, kprobe_decode_ldmstm),
880
881 /* STM (user registers) cccc 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
882 /* LDM (user registers) cccc 100x x1x1 xxxx 0xxx xxxx xxxx xxxx */
883 /* LDM (exception ret) cccc 100x x1x1 xxxx 1xxx xxxx xxxx xxxx */
884 DECODE_END
885};
35aa1df4 886
e9a92859
JM
887const union decode_item kprobe_decode_arm_table[] = {
888 /*
889 * Unconditional instructions
890 * 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx
891 */
892 DECODE_TABLE (0xf0000000, 0xf0000000, arm_1111_table),
893
894 /*
895 * Miscellaneous instructions
896 * cccc 0001 0xx0 xxxx xxxx xxxx 0xxx xxxx
897 */
898 DECODE_TABLE (0x0f900080, 0x01000000, arm_cccc_0001_0xx0____0xxx_table),
899
900 /*
901 * Halfword multiply and multiply-accumulate
902 * cccc 0001 0xx0 xxxx xxxx xxxx 1xx0 xxxx
903 */
904 DECODE_TABLE (0x0f900090, 0x01000080, arm_cccc_0001_0xx0____1xx0_table),
905
906 /*
907 * Multiply and multiply-accumulate
908 * cccc 0000 xxxx xxxx xxxx xxxx 1001 xxxx
909 */
910 DECODE_TABLE (0x0f0000f0, 0x00000090, arm_cccc_0000_____1001_table),
911
912 /*
913 * Synchronization primitives
914 * cccc 0001 xxxx xxxx xxxx xxxx 1001 xxxx
915 */
916 DECODE_TABLE (0x0f0000f0, 0x01000090, arm_cccc_0001_____1001_table),
917
918 /*
919 * Extra load/store instructions
920 * cccc 000x xxxx xxxx xxxx xxxx 1xx1 xxxx
921 */
922 DECODE_TABLE (0x0e000090, 0x00000090, arm_cccc_000x_____1xx1_table),
923
924 /*
925 * Data-processing (register)
926 * cccc 000x xxxx xxxx xxxx xxxx xxx0 xxxx
927 * Data-processing (register-shifted register)
928 * cccc 000x xxxx xxxx xxxx xxxx 0xx1 xxxx
929 */
930 DECODE_TABLE (0x0e000000, 0x00000000, arm_cccc_000x_table),
931
932 /*
933 * Data-processing (immediate)
934 * cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx
935 */
936 DECODE_TABLE (0x0e000000, 0x02000000, arm_cccc_001x_table),
937
938 /*
939 * Media instructions
940 * cccc 011x xxxx xxxx xxxx xxxx xxx1 xxxx
941 */
942 DECODE_TABLE (0x0f000010, 0x06000010, arm_cccc_0110_____xxx1_table),
943 DECODE_TABLE (0x0f000010, 0x07000010, arm_cccc_0111_____xxx1_table),
944
945 /*
946 * Load/store word and unsigned byte
947 * cccc 01xx xxxx xxxx xxxx xxxx xxxx xxxx
948 */
949 DECODE_TABLE (0x0c000000, 0x04000000, arm_cccc_01xx_table),
950
951 /*
952 * Block data transfer instructions
953 * cccc 100x xxxx xxxx xxxx xxxx xxxx xxxx
954 */
955 DECODE_TABLE (0x0e000000, 0x08000000, arm_cccc_100x_table),
956
957 /* B cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
958 /* BL cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
959 DECODE_SIMULATE (0x0e000000, 0x0a000000, simulate_bbl),
960
961 /*
962 * Supervisor Call, and coprocessor instructions
963 */
964
965 /* MCRR cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx */
966 /* MRRC cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx */
967 /* LDC cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
968 /* STC cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
969 /* CDP cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
970 /* MCR cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
971 /* MRC cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
972 /* SVC cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
973 DECODE_REJECT (0x0c000000, 0x0c000000),
35aa1df4 974
e9a92859
JM
975 DECODE_END
976};
2c89240b
JM
977#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
978EXPORT_SYMBOL_GPL(kprobe_decode_arm_table);
979#endif
35aa1df4 980
c6a7d97d
JM
981static void __kprobes arm_singlestep(struct kprobe *p, struct pt_regs *regs)
982{
983 regs->ARM_pc += 4;
984 p->ainsn.insn_handler(p, regs);
985}
986
35aa1df4
QB
987/* Return:
988 * INSN_REJECTED If instruction is one not allowed to kprobe,
989 * INSN_GOOD If instruction is supported and uses instruction slot,
990 * INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot.
991 *
992 * For instructions we don't want to kprobe (INSN_REJECTED return result):
993 * These are generally ones that modify the processor state making
994 * them "hard" to simulate such as switches processor modes or
995 * make accesses in alternate modes. Any of these could be simulated
996 * if the work was put into it, but low return considering they
997 * should also be very rare.
998 */
999enum kprobe_insn __kprobes
1000arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1001{
c6a7d97d 1002 asi->insn_singlestep = arm_singlestep;
0ab4c02d 1003 asi->insn_check_cc = kprobe_condition_checks[insn>>28];
e9a92859 1004 return kprobe_decode_insn(insn, asi, kprobe_decode_arm_table, false);
35aa1df4 1005}