2019-06-04 11:11:33 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2014-03-06 06:06:29 +04:00
/*
2015-01-09 05:19:49 +03:00
* arch / arm / probes / decode - thumb . c
2014-03-06 06:06:29 +04:00
*
* Copyright ( C ) 2011 Jon Medhurst < tixy @ yxit . co . uk > .
*/
# include <linux/stddef.h>
# include <linux/kernel.h>
# include <linux/module.h>
2015-01-09 05:19:49 +03:00
# include "decode.h"
# include "decode-thumb.h"
2014-03-06 06:06:29 +04:00
static const union decode_item t32_table_1110_100x_x0xx [ ] = {
/* Load/store multiple instructions */
/* Rn is PC 1110 100x x0xx 1111 xxxx xxxx xxxx xxxx */
DECODE_REJECT ( 0xfe4f0000 , 0xe80f0000 ) ,
/* SRS 1110 1000 00x0 xxxx xxxx xxxx xxxx xxxx */
/* RFE 1110 1000 00x1 xxxx xxxx xxxx xxxx xxxx */
DECODE_REJECT ( 0xffc00000 , 0xe8000000 ) ,
/* SRS 1110 1001 10x0 xxxx xxxx xxxx xxxx xxxx */
/* RFE 1110 1001 10x1 xxxx xxxx xxxx xxxx xxxx */
DECODE_REJECT ( 0xffc00000 , 0xe9800000 ) ,
/* STM Rn, {...pc} 1110 100x x0x0 xxxx 1xxx xxxx xxxx xxxx */
DECODE_REJECT ( 0xfe508000 , 0xe8008000 ) ,
/* LDM Rn, {...lr,pc} 1110 100x x0x1 xxxx 11xx xxxx xxxx xxxx */
DECODE_REJECT ( 0xfe50c000 , 0xe810c000 ) ,
/* LDM/STM Rn, {...sp} 1110 100x x0xx xxxx xx1x xxxx xxxx xxxx */
DECODE_REJECT ( 0xfe402000 , 0xe8002000 ) ,
/* STMIA 1110 1000 10x0 xxxx xxxx xxxx xxxx xxxx */
/* LDMIA 1110 1000 10x1 xxxx xxxx xxxx xxxx xxxx */
/* STMDB 1110 1001 00x0 xxxx xxxx xxxx xxxx xxxx */
/* LDMDB 1110 1001 00x1 xxxx xxxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_CUSTOM ( 0xfe400000 , 0xe8000000 , PROBES_T32_LDMSTM ) ,
2014-03-06 06:06:29 +04:00
DECODE_END
} ;
static const union decode_item t32_table_1110_100x_x1xx [ ] = {
/* Load/store dual, load/store exclusive, table branch */
/* STRD (immediate) 1110 1000 x110 xxxx xxxx xxxx xxxx xxxx */
/* LDRD (immediate) 1110 1000 x111 xxxx xxxx xxxx xxxx xxxx */
DECODE_OR ( 0xff600000 , 0xe8600000 ) ,
/* STRD (immediate) 1110 1001 x1x0 xxxx xxxx xxxx xxxx xxxx */
/* LDRD (immediate) 1110 1001 x1x1 xxxx xxxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xff400000 , 0xe9400000 , PROBES_T32_LDRDSTRD ,
2014-03-06 06:06:29 +04:00
REGS ( NOPCWB , NOSPPC , NOSPPC , 0 , 0 ) ) ,
/* TBB 1110 1000 1101 xxxx xxxx xxxx 0000 xxxx */
/* TBH 1110 1000 1101 xxxx xxxx xxxx 0001 xxxx */
2014-03-07 03:06:43 +04:00
DECODE_SIMULATEX ( 0xfff000e0 , 0xe8d00000 , PROBES_T32_TABLE_BRANCH ,
2014-03-06 06:06:29 +04:00
REGS ( NOSP , 0 , 0 , 0 , NOSPPC ) ) ,
/* STREX 1110 1000 0100 xxxx xxxx xxxx xxxx xxxx */
/* LDREX 1110 1000 0101 xxxx xxxx xxxx xxxx xxxx */
/* STREXB 1110 1000 1100 xxxx xxxx xxxx 0100 xxxx */
/* STREXH 1110 1000 1100 xxxx xxxx xxxx 0101 xxxx */
/* STREXD 1110 1000 1100 xxxx xxxx xxxx 0111 xxxx */
/* LDREXB 1110 1000 1101 xxxx xxxx xxxx 0100 xxxx */
/* LDREXH 1110 1000 1101 xxxx xxxx xxxx 0101 xxxx */
/* LDREXD 1110 1000 1101 xxxx xxxx xxxx 0111 xxxx */
/* And unallocated instructions... */
DECODE_END
} ;
static const union decode_item t32_table_1110_101x [ ] = {
/* Data-processing (shifted register) */
/* TST 1110 1010 0001 xxxx xxxx 1111 xxxx xxxx */
/* TEQ 1110 1010 1001 xxxx xxxx 1111 xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xff700f00 , 0xea100f00 , PROBES_T32_TST ,
2014-03-06 06:06:29 +04:00
REGS ( NOSPPC , 0 , 0 , 0 , NOSPPC ) ) ,
/* CMN 1110 1011 0001 xxxx xxxx 1111 xxxx xxxx */
DECODE_OR ( 0xfff00f00 , 0xeb100f00 ) ,
/* CMP 1110 1011 1011 xxxx xxxx 1111 xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfff00f00 , 0xebb00f00 , PROBES_T32_TST ,
2014-03-06 06:06:29 +04:00
REGS ( NOPC , 0 , 0 , 0 , NOSPPC ) ) ,
/* MOV 1110 1010 010x 1111 xxxx xxxx xxxx xxxx */
/* MVN 1110 1010 011x 1111 xxxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xffcf0000 , 0xea4f0000 , PROBES_T32_MOV ,
2014-03-06 06:06:29 +04:00
REGS ( 0 , 0 , NOSPPC , 0 , NOSPPC ) ) ,
/* ??? 1110 1010 101x xxxx xxxx xxxx xxxx xxxx */
/* ??? 1110 1010 111x xxxx xxxx xxxx xxxx xxxx */
DECODE_REJECT ( 0xffa00000 , 0xeaa00000 ) ,
/* ??? 1110 1011 001x xxxx xxxx xxxx xxxx xxxx */
DECODE_REJECT ( 0xffe00000 , 0xeb200000 ) ,
/* ??? 1110 1011 100x xxxx xxxx xxxx xxxx xxxx */
DECODE_REJECT ( 0xffe00000 , 0xeb800000 ) ,
/* ??? 1110 1011 111x xxxx xxxx xxxx xxxx xxxx */
DECODE_REJECT ( 0xffe00000 , 0xebe00000 ) ,
/* ADD/SUB SP, SP, Rm, LSL #0..3 */
/* 1110 1011 x0xx 1101 x000 1101 xx00 xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xff4f7f30 , 0xeb0d0d00 , PROBES_T32_ADDSUB ,
2014-03-06 06:06:29 +04:00
REGS ( SP , 0 , SP , 0 , NOSPPC ) ) ,
/* ADD/SUB SP, SP, Rm, shift */
/* 1110 1011 x0xx 1101 xxxx 1101 xxxx xxxx */
DECODE_REJECT ( 0xff4f0f00 , 0xeb0d0d00 ) ,
/* ADD/SUB Rd, SP, Rm, shift */
/* 1110 1011 x0xx 1101 xxxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xff4f0000 , 0xeb0d0000 , PROBES_T32_ADDSUB ,
2014-03-06 06:06:29 +04:00
REGS ( SP , 0 , NOPC , 0 , NOSPPC ) ) ,
/* AND 1110 1010 000x xxxx xxxx xxxx xxxx xxxx */
/* BIC 1110 1010 001x xxxx xxxx xxxx xxxx xxxx */
/* ORR 1110 1010 010x xxxx xxxx xxxx xxxx xxxx */
/* ORN 1110 1010 011x xxxx xxxx xxxx xxxx xxxx */
/* EOR 1110 1010 100x xxxx xxxx xxxx xxxx xxxx */
/* PKH 1110 1010 110x xxxx xxxx xxxx xxxx xxxx */
/* ADD 1110 1011 000x xxxx xxxx xxxx xxxx xxxx */
/* ADC 1110 1011 010x xxxx xxxx xxxx xxxx xxxx */
/* SBC 1110 1011 011x xxxx xxxx xxxx xxxx xxxx */
/* SUB 1110 1011 101x xxxx xxxx xxxx xxxx xxxx */
/* RSB 1110 1011 110x xxxx xxxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfe000000 , 0xea000000 , PROBES_T32_LOGICAL ,
2014-03-06 06:06:29 +04:00
REGS ( NOSPPC , 0 , NOSPPC , 0 , NOSPPC ) ) ,
DECODE_END
} ;
static const union decode_item t32_table_1111_0x0x___0 [ ] = {
/* Data-processing (modified immediate) */
/* TST 1111 0x00 0001 xxxx 0xxx 1111 xxxx xxxx */
/* TEQ 1111 0x00 1001 xxxx 0xxx 1111 xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfb708f00 , 0xf0100f00 , PROBES_T32_TST ,
2014-03-06 06:06:29 +04:00
REGS ( NOSPPC , 0 , 0 , 0 , 0 ) ) ,
/* CMN 1111 0x01 0001 xxxx 0xxx 1111 xxxx xxxx */
DECODE_OR ( 0xfbf08f00 , 0xf1100f00 ) ,
/* CMP 1111 0x01 1011 xxxx 0xxx 1111 xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfbf08f00 , 0xf1b00f00 , PROBES_T32_CMP ,
2014-03-06 06:06:29 +04:00
REGS ( NOPC , 0 , 0 , 0 , 0 ) ) ,
/* MOV 1111 0x00 010x 1111 0xxx xxxx xxxx xxxx */
/* MVN 1111 0x00 011x 1111 0xxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfbcf8000 , 0xf04f0000 , PROBES_T32_MOV ,
2014-03-06 06:06:29 +04:00
REGS ( 0 , 0 , NOSPPC , 0 , 0 ) ) ,
/* ??? 1111 0x00 101x xxxx 0xxx xxxx xxxx xxxx */
DECODE_REJECT ( 0xfbe08000 , 0xf0a00000 ) ,
/* ??? 1111 0x00 110x xxxx 0xxx xxxx xxxx xxxx */
/* ??? 1111 0x00 111x xxxx 0xxx xxxx xxxx xxxx */
DECODE_REJECT ( 0xfbc08000 , 0xf0c00000 ) ,
/* ??? 1111 0x01 001x xxxx 0xxx xxxx xxxx xxxx */
DECODE_REJECT ( 0xfbe08000 , 0xf1200000 ) ,
/* ??? 1111 0x01 100x xxxx 0xxx xxxx xxxx xxxx */
DECODE_REJECT ( 0xfbe08000 , 0xf1800000 ) ,
/* ??? 1111 0x01 111x xxxx 0xxx xxxx xxxx xxxx */
DECODE_REJECT ( 0xfbe08000 , 0xf1e00000 ) ,
/* ADD Rd, SP, #imm 1111 0x01 000x 1101 0xxx xxxx xxxx xxxx */
/* SUB Rd, SP, #imm 1111 0x01 101x 1101 0xxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfb4f8000 , 0xf10d0000 , PROBES_T32_ADDSUB ,
2014-03-06 06:06:29 +04:00
REGS ( SP , 0 , NOPC , 0 , 0 ) ) ,
/* AND 1111 0x00 000x xxxx 0xxx xxxx xxxx xxxx */
/* BIC 1111 0x00 001x xxxx 0xxx xxxx xxxx xxxx */
/* ORR 1111 0x00 010x xxxx 0xxx xxxx xxxx xxxx */
/* ORN 1111 0x00 011x xxxx 0xxx xxxx xxxx xxxx */
/* EOR 1111 0x00 100x xxxx 0xxx xxxx xxxx xxxx */
/* ADD 1111 0x01 000x xxxx 0xxx xxxx xxxx xxxx */
/* ADC 1111 0x01 010x xxxx 0xxx xxxx xxxx xxxx */
/* SBC 1111 0x01 011x xxxx 0xxx xxxx xxxx xxxx */
/* SUB 1111 0x01 101x xxxx 0xxx xxxx xxxx xxxx */
/* RSB 1111 0x01 110x xxxx 0xxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfa008000 , 0xf0000000 , PROBES_T32_LOGICAL ,
2014-03-06 06:06:29 +04:00
REGS ( NOSPPC , 0 , NOSPPC , 0 , 0 ) ) ,
DECODE_END
} ;
static const union decode_item t32_table_1111_0x1x___0 [ ] = {
/* Data-processing (plain binary immediate) */
/* ADDW Rd, PC, #imm 1111 0x10 0000 1111 0xxx xxxx xxxx xxxx */
DECODE_OR ( 0xfbff8000 , 0xf20f0000 ) ,
/* SUBW Rd, PC, #imm 1111 0x10 1010 1111 0xxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfbff8000 , 0xf2af0000 , PROBES_T32_ADDWSUBW_PC ,
2014-03-06 06:06:29 +04:00
REGS ( PC , 0 , NOSPPC , 0 , 0 ) ) ,
/* ADDW SP, SP, #imm 1111 0x10 0000 1101 0xxx 1101 xxxx xxxx */
DECODE_OR ( 0xfbff8f00 , 0xf20d0d00 ) ,
/* SUBW SP, SP, #imm 1111 0x10 1010 1101 0xxx 1101 xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfbff8f00 , 0xf2ad0d00 , PROBES_T32_ADDWSUBW ,
2014-03-06 06:06:29 +04:00
REGS ( SP , 0 , SP , 0 , 0 ) ) ,
/* ADDW 1111 0x10 0000 xxxx 0xxx xxxx xxxx xxxx */
DECODE_OR ( 0xfbf08000 , 0xf2000000 ) ,
/* SUBW 1111 0x10 1010 xxxx 0xxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfbf08000 , 0xf2a00000 , PROBES_T32_ADDWSUBW ,
2014-03-06 06:06:29 +04:00
REGS ( NOPCX , 0 , NOSPPC , 0 , 0 ) ) ,
/* MOVW 1111 0x10 0100 xxxx 0xxx xxxx xxxx xxxx */
/* MOVT 1111 0x10 1100 xxxx 0xxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfb708000 , 0xf2400000 , PROBES_T32_MOVW ,
2014-03-06 06:06:29 +04:00
REGS ( 0 , 0 , NOSPPC , 0 , 0 ) ) ,
/* SSAT16 1111 0x11 0010 xxxx 0000 xxxx 00xx xxxx */
/* SSAT 1111 0x11 00x0 xxxx 0xxx xxxx xxxx xxxx */
/* USAT16 1111 0x11 1010 xxxx 0000 xxxx 00xx xxxx */
/* USAT 1111 0x11 10x0 xxxx 0xxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfb508000 , 0xf3000000 , PROBES_T32_SAT ,
2014-03-06 06:06:29 +04:00
REGS ( NOSPPC , 0 , NOSPPC , 0 , 0 ) ) ,
/* SFBX 1111 0x11 0100 xxxx 0xxx xxxx xxxx xxxx */
/* UFBX 1111 0x11 1100 xxxx 0xxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfb708000 , 0xf3400000 , PROBES_T32_BITFIELD ,
2014-03-06 06:06:29 +04:00
REGS ( NOSPPC , 0 , NOSPPC , 0 , 0 ) ) ,
/* BFC 1111 0x11 0110 1111 0xxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfbff8000 , 0xf36f0000 , PROBES_T32_BITFIELD ,
2014-03-06 06:06:29 +04:00
REGS ( 0 , 0 , NOSPPC , 0 , 0 ) ) ,
/* BFI 1111 0x11 0110 xxxx 0xxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfbf08000 , 0xf3600000 , PROBES_T32_BITFIELD ,
2014-03-06 06:06:29 +04:00
REGS ( NOSPPCX , 0 , NOSPPC , 0 , 0 ) ) ,
DECODE_END
} ;
static const union decode_item t32_table_1111_0xxx___1 [ ] = {
/* Branches and miscellaneous control */
/* YIELD 1111 0011 1010 xxxx 10x0 x000 0000 0001 */
DECODE_OR ( 0xfff0d7ff , 0xf3a08001 ) ,
/* SEV 1111 0011 1010 xxxx 10x0 x000 0000 0100 */
2014-03-07 03:06:43 +04:00
DECODE_EMULATE ( 0xfff0d7ff , 0xf3a08004 , PROBES_T32_SEV ) ,
2014-03-06 06:06:29 +04:00
/* NOP 1111 0011 1010 xxxx 10x0 x000 0000 0000 */
/* WFE 1111 0011 1010 xxxx 10x0 x000 0000 0010 */
/* WFI 1111 0011 1010 xxxx 10x0 x000 0000 0011 */
2014-03-07 03:06:43 +04:00
DECODE_SIMULATE ( 0xfff0d7fc , 0xf3a08000 , PROBES_T32_WFE ) ,
2014-03-06 06:06:29 +04:00
/* MRS Rd, CPSR 1111 0011 1110 xxxx 10x0 xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_SIMULATEX ( 0xfff0d000 , 0xf3e08000 , PROBES_T32_MRS ,
2014-03-06 06:06:29 +04:00
REGS ( 0 , 0 , NOSPPC , 0 , 0 ) ) ,
/*
* Unsupported instructions
* 1111 0x11 1 xxx xxxx 10 x0 xxxx xxxx xxxx
*
* MSR 1111 0011 100 x xxxx 10 x0 xxxx xxxx xxxx
* DBG hint 1111 0011 1010 xxxx 10 x0 x000 1111 xxxx
* Unallocated hints 1111 0011 1010 xxxx 10 x0 x000 xxxx xxxx
* CPS 1111 0011 1010 xxxx 10 x0 xxxx xxxx xxxx
* CLREX / DSB / DMB / ISB 1111 0011 1011 xxxx 10 x0 xxxx xxxx xxxx
* BXJ 1111 0011 1100 xxxx 10 x0 xxxx xxxx xxxx
* SUBS PC , LR , # < imm8 > 1111 0011 1101 xxxx 10 x0 xxxx xxxx xxxx
* MRS Rd , SPSR 1111 0011 1111 xxxx 10 x0 xxxx xxxx xxxx
* SMC 1111 0111 1111 xxxx 1000 xxxx xxxx xxxx
* UNDEFINED 1111 0111 1111 xxxx 1010 xxxx xxxx xxxx
* ? ? ? 1111 0111 1 xxx xxxx 1010 xxxx xxxx xxxx
*/
DECODE_REJECT ( 0xfb80d000 , 0xf3808000 ) ,
/* Bcc 1111 0xxx xxxx xxxx 10x0 xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_CUSTOM ( 0xf800d000 , 0xf0008000 , PROBES_T32_BRANCH_COND ) ,
2014-03-06 06:06:29 +04:00
/* BLX 1111 0xxx xxxx xxxx 11x0 xxxx xxxx xxx0 */
DECODE_OR ( 0xf800d001 , 0xf000c000 ) ,
/* B 1111 0xxx xxxx xxxx 10x1 xxxx xxxx xxxx */
/* BL 1111 0xxx xxxx xxxx 11x1 xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_SIMULATE ( 0xf8009000 , 0xf0009000 , PROBES_T32_BRANCH ) ,
2014-03-06 06:06:29 +04:00
DECODE_END
} ;
static const union decode_item t32_table_1111_100x_x0x1__1111 [ ] = {
/* Memory hints */
/* PLD (literal) 1111 1000 x001 1111 1111 xxxx xxxx xxxx */
/* PLI (literal) 1111 1001 x001 1111 1111 xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_SIMULATE ( 0xfe7ff000 , 0xf81ff000 , PROBES_T32_PLDI ) ,
2014-03-06 06:06:29 +04:00
/* PLD{W} (immediate) 1111 1000 10x1 xxxx 1111 xxxx xxxx xxxx */
DECODE_OR ( 0xffd0f000 , 0xf890f000 ) ,
/* PLD{W} (immediate) 1111 1000 00x1 xxxx 1111 1100 xxxx xxxx */
DECODE_OR ( 0xffd0ff00 , 0xf810fc00 ) ,
/* PLI (immediate) 1111 1001 1001 xxxx 1111 xxxx xxxx xxxx */
DECODE_OR ( 0xfff0f000 , 0xf990f000 ) ,
/* PLI (immediate) 1111 1001 0001 xxxx 1111 1100 xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_SIMULATEX ( 0xfff0ff00 , 0xf910fc00 , PROBES_T32_PLDI ,
2014-03-06 06:06:29 +04:00
REGS ( NOPCX , 0 , 0 , 0 , 0 ) ) ,
/* PLD{W} (register) 1111 1000 00x1 xxxx 1111 0000 00xx xxxx */
DECODE_OR ( 0xffd0ffc0 , 0xf810f000 ) ,
/* PLI (register) 1111 1001 0001 xxxx 1111 0000 00xx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_SIMULATEX ( 0xfff0ffc0 , 0xf910f000 , PROBES_T32_PLDI ,
2014-03-06 06:06:29 +04:00
REGS ( NOPCX , 0 , 0 , 0 , NOSPPC ) ) ,
/* Other unallocated instructions... */
DECODE_END
} ;
static const union decode_item t32_table_1111_100x [ ] = {
/* Store/Load single data item */
/* ??? 1111 100x x11x xxxx xxxx xxxx xxxx xxxx */
DECODE_REJECT ( 0xfe600000 , 0xf8600000 ) ,
/* ??? 1111 1001 0101 xxxx xxxx xxxx xxxx xxxx */
DECODE_REJECT ( 0xfff00000 , 0xf9500000 ) ,
/* ??? 1111 100x 0xxx xxxx xxxx 10x0 xxxx xxxx */
DECODE_REJECT ( 0xfe800d00 , 0xf8000800 ) ,
/* STRBT 1111 1000 0000 xxxx xxxx 1110 xxxx xxxx */
/* STRHT 1111 1000 0010 xxxx xxxx 1110 xxxx xxxx */
/* STRT 1111 1000 0100 xxxx xxxx 1110 xxxx xxxx */
/* LDRBT 1111 1000 0001 xxxx xxxx 1110 xxxx xxxx */
/* LDRSBT 1111 1001 0001 xxxx xxxx 1110 xxxx xxxx */
/* LDRHT 1111 1000 0011 xxxx xxxx 1110 xxxx xxxx */
/* LDRSHT 1111 1001 0011 xxxx xxxx 1110 xxxx xxxx */
/* LDRT 1111 1000 0101 xxxx xxxx 1110 xxxx xxxx */
DECODE_REJECT ( 0xfe800f00 , 0xf8000e00 ) ,
/* STR{,B,H} Rn,[PC...] 1111 1000 xxx0 1111 xxxx xxxx xxxx xxxx */
DECODE_REJECT ( 0xff1f0000 , 0xf80f0000 ) ,
/* STR{,B,H} PC,[Rn...] 1111 1000 xxx0 xxxx 1111 xxxx xxxx xxxx */
DECODE_REJECT ( 0xff10f000 , 0xf800f000 ) ,
/* LDR (literal) 1111 1000 x101 1111 xxxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_SIMULATEX ( 0xff7f0000 , 0xf85f0000 , PROBES_T32_LDR_LIT ,
2014-03-06 06:06:29 +04:00
REGS ( PC , ANY , 0 , 0 , 0 ) ) ,
/* STR (immediate) 1111 1000 0100 xxxx xxxx 1xxx xxxx xxxx */
/* LDR (immediate) 1111 1000 0101 xxxx xxxx 1xxx xxxx xxxx */
DECODE_OR ( 0xffe00800 , 0xf8400800 ) ,
/* STR (immediate) 1111 1000 1100 xxxx xxxx xxxx xxxx xxxx */
/* LDR (immediate) 1111 1000 1101 xxxx xxxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xffe00000 , 0xf8c00000 , PROBES_T32_LDRSTR ,
2014-03-06 06:06:29 +04:00
REGS ( NOPCX , ANY , 0 , 0 , 0 ) ) ,
/* STR (register) 1111 1000 0100 xxxx xxxx 0000 00xx xxxx */
/* LDR (register) 1111 1000 0101 xxxx xxxx 0000 00xx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xffe00fc0 , 0xf8400000 , PROBES_T32_LDRSTR ,
2014-03-06 06:06:29 +04:00
REGS ( NOPCX , ANY , 0 , 0 , NOSPPC ) ) ,
/* LDRB (literal) 1111 1000 x001 1111 xxxx xxxx xxxx xxxx */
/* LDRSB (literal) 1111 1001 x001 1111 xxxx xxxx xxxx xxxx */
/* LDRH (literal) 1111 1000 x011 1111 xxxx xxxx xxxx xxxx */
/* LDRSH (literal) 1111 1001 x011 1111 xxxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_SIMULATEX ( 0xfe5f0000 , 0xf81f0000 , PROBES_T32_LDR_LIT ,
2014-03-06 06:06:29 +04:00
REGS ( PC , NOSPPCX , 0 , 0 , 0 ) ) ,
/* STRB (immediate) 1111 1000 0000 xxxx xxxx 1xxx xxxx xxxx */
/* STRH (immediate) 1111 1000 0010 xxxx xxxx 1xxx xxxx xxxx */
/* LDRB (immediate) 1111 1000 0001 xxxx xxxx 1xxx xxxx xxxx */
/* LDRSB (immediate) 1111 1001 0001 xxxx xxxx 1xxx xxxx xxxx */
/* LDRH (immediate) 1111 1000 0011 xxxx xxxx 1xxx xxxx xxxx */
/* LDRSH (immediate) 1111 1001 0011 xxxx xxxx 1xxx xxxx xxxx */
DECODE_OR ( 0xfec00800 , 0xf8000800 ) ,
/* STRB (immediate) 1111 1000 1000 xxxx xxxx xxxx xxxx xxxx */
/* STRH (immediate) 1111 1000 1010 xxxx xxxx xxxx xxxx xxxx */
/* LDRB (immediate) 1111 1000 1001 xxxx xxxx xxxx xxxx xxxx */
/* LDRSB (immediate) 1111 1001 1001 xxxx xxxx xxxx xxxx xxxx */
/* LDRH (immediate) 1111 1000 1011 xxxx xxxx xxxx xxxx xxxx */
/* LDRSH (immediate) 1111 1001 1011 xxxx xxxx xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfec00000 , 0xf8800000 , PROBES_T32_LDRSTR ,
2014-03-06 06:06:29 +04:00
REGS ( NOPCX , NOSPPCX , 0 , 0 , 0 ) ) ,
/* STRB (register) 1111 1000 0000 xxxx xxxx 0000 00xx xxxx */
/* STRH (register) 1111 1000 0010 xxxx xxxx 0000 00xx xxxx */
/* LDRB (register) 1111 1000 0001 xxxx xxxx 0000 00xx xxxx */
/* LDRSB (register) 1111 1001 0001 xxxx xxxx 0000 00xx xxxx */
/* LDRH (register) 1111 1000 0011 xxxx xxxx 0000 00xx xxxx */
/* LDRSH (register) 1111 1001 0011 xxxx xxxx 0000 00xx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfe800fc0 , 0xf8000000 , PROBES_T32_LDRSTR ,
2014-03-06 06:06:29 +04:00
REGS ( NOPCX , NOSPPCX , 0 , 0 , NOSPPC ) ) ,
/* Other unallocated instructions... */
DECODE_END
} ;
static const union decode_item t32_table_1111_1010___1111 [ ] = {
/* Data-processing (register) */
/* ??? 1111 1010 011x xxxx 1111 xxxx 1xxx xxxx */
DECODE_REJECT ( 0xffe0f080 , 0xfa60f080 ) ,
/* SXTH 1111 1010 0000 1111 1111 xxxx 1xxx xxxx */
/* UXTH 1111 1010 0001 1111 1111 xxxx 1xxx xxxx */
/* SXTB16 1111 1010 0010 1111 1111 xxxx 1xxx xxxx */
/* UXTB16 1111 1010 0011 1111 1111 xxxx 1xxx xxxx */
/* SXTB 1111 1010 0100 1111 1111 xxxx 1xxx xxxx */
/* UXTB 1111 1010 0101 1111 1111 xxxx 1xxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xff8ff080 , 0xfa0ff080 , PROBES_T32_SIGN_EXTEND ,
2014-03-06 06:06:29 +04:00
REGS ( 0 , 0 , NOSPPC , 0 , NOSPPC ) ) ,
/* ??? 1111 1010 1xxx xxxx 1111 xxxx 0x11 xxxx */
DECODE_REJECT ( 0xff80f0b0 , 0xfa80f030 ) ,
/* ??? 1111 1010 1x11 xxxx 1111 xxxx 0xxx xxxx */
DECODE_REJECT ( 0xffb0f080 , 0xfab0f000 ) ,
/* SADD16 1111 1010 1001 xxxx 1111 xxxx 0000 xxxx */
/* SASX 1111 1010 1010 xxxx 1111 xxxx 0000 xxxx */
/* SSAX 1111 1010 1110 xxxx 1111 xxxx 0000 xxxx */
/* SSUB16 1111 1010 1101 xxxx 1111 xxxx 0000 xxxx */
/* SADD8 1111 1010 1000 xxxx 1111 xxxx 0000 xxxx */
/* SSUB8 1111 1010 1100 xxxx 1111 xxxx 0000 xxxx */
/* QADD16 1111 1010 1001 xxxx 1111 xxxx 0001 xxxx */
/* QASX 1111 1010 1010 xxxx 1111 xxxx 0001 xxxx */
/* QSAX 1111 1010 1110 xxxx 1111 xxxx 0001 xxxx */
/* QSUB16 1111 1010 1101 xxxx 1111 xxxx 0001 xxxx */
/* QADD8 1111 1010 1000 xxxx 1111 xxxx 0001 xxxx */
/* QSUB8 1111 1010 1100 xxxx 1111 xxxx 0001 xxxx */
/* SHADD16 1111 1010 1001 xxxx 1111 xxxx 0010 xxxx */
/* SHASX 1111 1010 1010 xxxx 1111 xxxx 0010 xxxx */
/* SHSAX 1111 1010 1110 xxxx 1111 xxxx 0010 xxxx */
/* SHSUB16 1111 1010 1101 xxxx 1111 xxxx 0010 xxxx */
/* SHADD8 1111 1010 1000 xxxx 1111 xxxx 0010 xxxx */
/* SHSUB8 1111 1010 1100 xxxx 1111 xxxx 0010 xxxx */
/* UADD16 1111 1010 1001 xxxx 1111 xxxx 0100 xxxx */
/* UASX 1111 1010 1010 xxxx 1111 xxxx 0100 xxxx */
/* USAX 1111 1010 1110 xxxx 1111 xxxx 0100 xxxx */
/* USUB16 1111 1010 1101 xxxx 1111 xxxx 0100 xxxx */
/* UADD8 1111 1010 1000 xxxx 1111 xxxx 0100 xxxx */
/* USUB8 1111 1010 1100 xxxx 1111 xxxx 0100 xxxx */
/* UQADD16 1111 1010 1001 xxxx 1111 xxxx 0101 xxxx */
/* UQASX 1111 1010 1010 xxxx 1111 xxxx 0101 xxxx */
/* UQSAX 1111 1010 1110 xxxx 1111 xxxx 0101 xxxx */
/* UQSUB16 1111 1010 1101 xxxx 1111 xxxx 0101 xxxx */
/* UQADD8 1111 1010 1000 xxxx 1111 xxxx 0101 xxxx */
/* UQSUB8 1111 1010 1100 xxxx 1111 xxxx 0101 xxxx */
/* UHADD16 1111 1010 1001 xxxx 1111 xxxx 0110 xxxx */
/* UHASX 1111 1010 1010 xxxx 1111 xxxx 0110 xxxx */
/* UHSAX 1111 1010 1110 xxxx 1111 xxxx 0110 xxxx */
/* UHSUB16 1111 1010 1101 xxxx 1111 xxxx 0110 xxxx */
/* UHADD8 1111 1010 1000 xxxx 1111 xxxx 0110 xxxx */
/* UHSUB8 1111 1010 1100 xxxx 1111 xxxx 0110 xxxx */
DECODE_OR ( 0xff80f080 , 0xfa80f000 ) ,
/* SXTAH 1111 1010 0000 xxxx 1111 xxxx 1xxx xxxx */
/* UXTAH 1111 1010 0001 xxxx 1111 xxxx 1xxx xxxx */
/* SXTAB16 1111 1010 0010 xxxx 1111 xxxx 1xxx xxxx */
/* UXTAB16 1111 1010 0011 xxxx 1111 xxxx 1xxx xxxx */
/* SXTAB 1111 1010 0100 xxxx 1111 xxxx 1xxx xxxx */
/* UXTAB 1111 1010 0101 xxxx 1111 xxxx 1xxx xxxx */
DECODE_OR ( 0xff80f080 , 0xfa00f080 ) ,
/* QADD 1111 1010 1000 xxxx 1111 xxxx 1000 xxxx */
/* QDADD 1111 1010 1000 xxxx 1111 xxxx 1001 xxxx */
/* QSUB 1111 1010 1000 xxxx 1111 xxxx 1010 xxxx */
/* QDSUB 1111 1010 1000 xxxx 1111 xxxx 1011 xxxx */
DECODE_OR ( 0xfff0f0c0 , 0xfa80f080 ) ,
/* SEL 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */
DECODE_OR ( 0xfff0f0f0 , 0xfaa0f080 ) ,
/* LSL 1111 1010 000x xxxx 1111 xxxx 0000 xxxx */
/* LSR 1111 1010 001x xxxx 1111 xxxx 0000 xxxx */
/* ASR 1111 1010 010x xxxx 1111 xxxx 0000 xxxx */
/* ROR 1111 1010 011x xxxx 1111 xxxx 0000 xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xff80f0f0 , 0xfa00f000 , PROBES_T32_MEDIA ,
2014-03-06 06:06:29 +04:00
REGS ( NOSPPC , 0 , NOSPPC , 0 , NOSPPC ) ) ,
/* CLZ 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */
DECODE_OR ( 0xfff0f0f0 , 0xfab0f080 ) ,
/* REV 1111 1010 1001 xxxx 1111 xxxx 1000 xxxx */
/* REV16 1111 1010 1001 xxxx 1111 xxxx 1001 xxxx */
/* RBIT 1111 1010 1001 xxxx 1111 xxxx 1010 xxxx */
/* REVSH 1111 1010 1001 xxxx 1111 xxxx 1011 xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xfff0f0c0 , 0xfa90f080 , PROBES_T32_REVERSE ,
2014-03-06 06:06:29 +04:00
REGS ( NOSPPC , 0 , NOSPPC , 0 , SAMEAS16 ) ) ,
/* Other unallocated instructions... */
DECODE_END
} ;
static const union decode_item t32_table_1111_1011_0 [ ] = {
/* Multiply, multiply accumulate, and absolute difference */
/* ??? 1111 1011 0000 xxxx 1111 xxxx 0001 xxxx */
DECODE_REJECT ( 0xfff0f0f0 , 0xfb00f010 ) ,
/* ??? 1111 1011 0111 xxxx 1111 xxxx 0001 xxxx */
DECODE_REJECT ( 0xfff0f0f0 , 0xfb70f010 ) ,
/* SMULxy 1111 1011 0001 xxxx 1111 xxxx 00xx xxxx */
DECODE_OR ( 0xfff0f0c0 , 0xfb10f000 ) ,
/* MUL 1111 1011 0000 xxxx 1111 xxxx 0000 xxxx */
/* SMUAD{X} 1111 1011 0010 xxxx 1111 xxxx 000x xxxx */
/* SMULWy 1111 1011 0011 xxxx 1111 xxxx 000x xxxx */
/* SMUSD{X} 1111 1011 0100 xxxx 1111 xxxx 000x xxxx */
/* SMMUL{R} 1111 1011 0101 xxxx 1111 xxxx 000x xxxx */
/* USAD8 1111 1011 0111 xxxx 1111 xxxx 0000 xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xff80f0e0 , 0xfb00f000 , PROBES_T32_MUL_ADD ,
2014-03-06 06:06:29 +04:00
REGS ( NOSPPC , 0 , NOSPPC , 0 , NOSPPC ) ) ,
/* ??? 1111 1011 0111 xxxx xxxx xxxx 0001 xxxx */
DECODE_REJECT ( 0xfff000f0 , 0xfb700010 ) ,
/* SMLAxy 1111 1011 0001 xxxx xxxx xxxx 00xx xxxx */
DECODE_OR ( 0xfff000c0 , 0xfb100000 ) ,
/* MLA 1111 1011 0000 xxxx xxxx xxxx 0000 xxxx */
/* MLS 1111 1011 0000 xxxx xxxx xxxx 0001 xxxx */
/* SMLAD{X} 1111 1011 0010 xxxx xxxx xxxx 000x xxxx */
/* SMLAWy 1111 1011 0011 xxxx xxxx xxxx 000x xxxx */
/* SMLSD{X} 1111 1011 0100 xxxx xxxx xxxx 000x xxxx */
/* SMMLA{R} 1111 1011 0101 xxxx xxxx xxxx 000x xxxx */
/* SMMLS{R} 1111 1011 0110 xxxx xxxx xxxx 000x xxxx */
/* USADA8 1111 1011 0111 xxxx xxxx xxxx 0000 xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xff8000c0 , 0xfb000000 , PROBES_T32_MUL_ADD2 ,
2014-03-06 06:06:29 +04:00
REGS ( NOSPPC , NOSPPCX , NOSPPC , 0 , NOSPPC ) ) ,
/* Other unallocated instructions... */
DECODE_END
} ;
static const union decode_item t32_table_1111_1011_1 [ ] = {
/* Long multiply, long multiply accumulate, and divide */
/* UMAAL 1111 1011 1110 xxxx xxxx xxxx 0110 xxxx */
DECODE_OR ( 0xfff000f0 , 0xfbe00060 ) ,
/* SMLALxy 1111 1011 1100 xxxx xxxx xxxx 10xx xxxx */
DECODE_OR ( 0xfff000c0 , 0xfbc00080 ) ,
/* SMLALD{X} 1111 1011 1100 xxxx xxxx xxxx 110x xxxx */
/* SMLSLD{X} 1111 1011 1101 xxxx xxxx xxxx 110x xxxx */
DECODE_OR ( 0xffe000e0 , 0xfbc000c0 ) ,
/* SMULL 1111 1011 1000 xxxx xxxx xxxx 0000 xxxx */
/* UMULL 1111 1011 1010 xxxx xxxx xxxx 0000 xxxx */
/* SMLAL 1111 1011 1100 xxxx xxxx xxxx 0000 xxxx */
/* UMLAL 1111 1011 1110 xxxx xxxx xxxx 0000 xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATEX ( 0xff9000f0 , 0xfb800000 , PROBES_T32_MUL_ADD_LONG ,
2014-03-06 06:06:29 +04:00
REGS ( NOSPPC , NOSPPC , NOSPPC , 0 , NOSPPC ) ) ,
/* SDIV 1111 1011 1001 xxxx xxxx xxxx 1111 xxxx */
/* UDIV 1111 1011 1011 xxxx xxxx xxxx 1111 xxxx */
/* Other unallocated instructions... */
DECODE_END
} ;
2014-03-07 03:12:07 +04:00
const union decode_item probes_decode_thumb32_table [ ] = {
2014-03-06 06:06:29 +04:00
/*
* Load / store multiple instructions
* 1110 100 x x0xx xxxx xxxx xxxx xxxx xxxx
*/
DECODE_TABLE ( 0xfe400000 , 0xe8000000 , t32_table_1110_100x_x0xx ) ,
/*
* Load / store dual , load / store exclusive , table branch
* 1110 100 x x1xx xxxx xxxx xxxx xxxx xxxx
*/
DECODE_TABLE ( 0xfe400000 , 0xe8400000 , t32_table_1110_100x_x1xx ) ,
/*
* Data - processing ( shifted register )
* 1110 101 x xxxx xxxx xxxx xxxx xxxx xxxx
*/
DECODE_TABLE ( 0xfe000000 , 0xea000000 , t32_table_1110_101x ) ,
/*
* Coprocessor instructions
* 1110 11 xx xxxx xxxx xxxx xxxx xxxx xxxx
*/
DECODE_REJECT ( 0xfc000000 , 0xec000000 ) ,
/*
* Data - processing ( modified immediate )
* 1111 0x0 x xxxx xxxx 0 xxx xxxx xxxx xxxx
*/
DECODE_TABLE ( 0xfa008000 , 0xf0000000 , t32_table_1111_0x0x___0 ) ,
/*
* Data - processing ( plain binary immediate )
* 1111 0x1 x xxxx xxxx 0 xxx xxxx xxxx xxxx
*/
DECODE_TABLE ( 0xfa008000 , 0xf2000000 , t32_table_1111_0x1x___0 ) ,
/*
* Branches and miscellaneous control
* 1111 0 xxx xxxx xxxx 1 xxx xxxx xxxx xxxx
*/
DECODE_TABLE ( 0xf8008000 , 0xf0008000 , t32_table_1111_0xxx___1 ) ,
/*
* Advanced SIMD element or structure load / store instructions
* 1111 1001 xxx0 xxxx xxxx xxxx xxxx xxxx
*/
DECODE_REJECT ( 0xff100000 , 0xf9000000 ) ,
/*
* Memory hints
* 1111 100 x x0x1 xxxx 1111 xxxx xxxx xxxx
*/
DECODE_TABLE ( 0xfe50f000 , 0xf810f000 , t32_table_1111_100x_x0x1__1111 ) ,
/*
* Store single data item
* 1111 1000 xxx0 xxxx xxxx xxxx xxxx xxxx
* Load single data items
* 1111 100 x xxx1 xxxx xxxx xxxx xxxx xxxx
*/
DECODE_TABLE ( 0xfe000000 , 0xf8000000 , t32_table_1111_100x ) ,
/*
* Data - processing ( register )
* 1111 1010 xxxx xxxx 1111 xxxx xxxx xxxx
*/
DECODE_TABLE ( 0xff00f000 , 0xfa00f000 , t32_table_1111_1010___1111 ) ,
/*
* Multiply , multiply accumulate , and absolute difference
* 1111 1011 0 xxx xxxx xxxx xxxx xxxx xxxx
*/
DECODE_TABLE ( 0xff800000 , 0xfb000000 , t32_table_1111_1011_0 ) ,
/*
* Long multiply , long multiply accumulate , and divide
* 1111 1011 1 xxx xxxx xxxx xxxx xxxx xxxx
*/
DECODE_TABLE ( 0xff800000 , 0xfb800000 , t32_table_1111_1011_1 ) ,
/*
* Coprocessor instructions
* 1111 11 xx xxxx xxxx xxxx xxxx xxxx xxxx
*/
DECODE_END
} ;
# ifdef CONFIG_ARM_KPROBES_TEST_MODULE
2014-03-07 03:12:07 +04:00
EXPORT_SYMBOL_GPL ( probes_decode_thumb32_table ) ;
2014-03-06 06:06:29 +04:00
# endif
static const union decode_item t16_table_1011 [ ] = {
/* Miscellaneous 16-bit instructions */
/* ADD (SP plus immediate) 1011 0000 0xxx xxxx */
/* SUB (SP minus immediate) 1011 0000 1xxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_SIMULATE ( 0xff00 , 0xb000 , PROBES_T16_ADD_SP ) ,
2014-03-06 06:06:29 +04:00
/* CBZ 1011 00x1 xxxx xxxx */
/* CBNZ 1011 10x1 xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_SIMULATE ( 0xf500 , 0xb100 , PROBES_T16_CBZ ) ,
2014-03-06 06:06:29 +04:00
/* SXTH 1011 0010 00xx xxxx */
/* SXTB 1011 0010 01xx xxxx */
/* UXTH 1011 0010 10xx xxxx */
/* UXTB 1011 0010 11xx xxxx */
/* REV 1011 1010 00xx xxxx */
/* REV16 1011 1010 01xx xxxx */
/* ??? 1011 1010 10xx xxxx */
/* REVSH 1011 1010 11xx xxxx */
DECODE_REJECT ( 0xffc0 , 0xba80 ) ,
2014-03-07 03:06:43 +04:00
DECODE_EMULATE ( 0xf500 , 0xb000 , PROBES_T16_SIGN_EXTEND ) ,
2014-03-06 06:06:29 +04:00
/* PUSH 1011 010x xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_CUSTOM ( 0xfe00 , 0xb400 , PROBES_T16_PUSH ) ,
2014-03-06 06:06:29 +04:00
/* POP 1011 110x xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_CUSTOM ( 0xfe00 , 0xbc00 , PROBES_T16_POP ) ,
2014-03-06 06:06:29 +04:00
/*
* If - Then , and hints
* 1011 1111 xxxx xxxx
*/
/* YIELD 1011 1111 0001 0000 */
DECODE_OR ( 0xffff , 0xbf10 ) ,
/* SEV 1011 1111 0100 0000 */
2014-03-07 03:06:43 +04:00
DECODE_EMULATE ( 0xffff , 0xbf40 , PROBES_T16_SEV ) ,
2014-03-06 06:06:29 +04:00
/* NOP 1011 1111 0000 0000 */
/* WFE 1011 1111 0010 0000 */
/* WFI 1011 1111 0011 0000 */
2014-03-07 03:06:43 +04:00
DECODE_SIMULATE ( 0xffcf , 0xbf00 , PROBES_T16_WFE ) ,
2014-03-06 06:06:29 +04:00
/* Unassigned hints 1011 1111 xxxx 0000 */
DECODE_REJECT ( 0xff0f , 0xbf00 ) ,
/* IT 1011 1111 xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_CUSTOM ( 0xff00 , 0xbf00 , PROBES_T16_IT ) ,
2014-03-06 06:06:29 +04:00
/* SETEND 1011 0110 010x xxxx */
/* CPS 1011 0110 011x xxxx */
/* BKPT 1011 1110 xxxx xxxx */
/* And unallocated instructions... */
DECODE_END
} ;
2014-03-07 03:12:07 +04:00
const union decode_item probes_decode_thumb16_table [ ] = {
2014-03-06 06:06:29 +04:00
/*
* Shift ( immediate ) , add , subtract , move , and compare
* 00 xx xxxx xxxx xxxx
*/
/* CMP (immediate) 0010 1xxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATE ( 0xf800 , 0x2800 , PROBES_T16_CMP ) ,
2014-03-06 06:06:29 +04:00
/* ADD (register) 0001 100x xxxx xxxx */
/* SUB (register) 0001 101x xxxx xxxx */
/* LSL (immediate) 0000 0xxx xxxx xxxx */
/* LSR (immediate) 0000 1xxx xxxx xxxx */
/* ASR (immediate) 0001 0xxx xxxx xxxx */
/* ADD (immediate, Thumb) 0001 110x xxxx xxxx */
/* SUB (immediate, Thumb) 0001 111x xxxx xxxx */
/* MOV (immediate) 0010 0xxx xxxx xxxx */
/* ADD (immediate, Thumb) 0011 0xxx xxxx xxxx */
/* SUB (immediate, Thumb) 0011 1xxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATE ( 0xc000 , 0x0000 , PROBES_T16_ADDSUB ) ,
2014-03-06 06:06:29 +04:00
/*
* 16 - bit Thumb data - processing instructions
* 0100 00 xx xxxx xxxx
*/
/* TST (register) 0100 0010 00xx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATE ( 0xffc0 , 0x4200 , PROBES_T16_CMP ) ,
2014-03-06 06:06:29 +04:00
/* CMP (register) 0100 0010 10xx xxxx */
/* CMN (register) 0100 0010 11xx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATE ( 0xff80 , 0x4280 , PROBES_T16_CMP ) ,
2014-03-06 06:06:29 +04:00
/* AND (register) 0100 0000 00xx xxxx */
/* EOR (register) 0100 0000 01xx xxxx */
/* LSL (register) 0100 0000 10xx xxxx */
/* LSR (register) 0100 0000 11xx xxxx */
/* ASR (register) 0100 0001 00xx xxxx */
/* ADC (register) 0100 0001 01xx xxxx */
/* SBC (register) 0100 0001 10xx xxxx */
/* ROR (register) 0100 0001 11xx xxxx */
/* RSB (immediate) 0100 0010 01xx xxxx */
/* ORR (register) 0100 0011 00xx xxxx */
/* MUL 0100 0011 00xx xxxx */
/* BIC (register) 0100 0011 10xx xxxx */
/* MVN (register) 0100 0011 10xx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATE ( 0xfc00 , 0x4000 , PROBES_T16_LOGICAL ) ,
2014-03-06 06:06:29 +04:00
/*
* Special data instructions and branch and exchange
* 0100 01 xx xxxx xxxx
*/
/* BLX pc 0100 0111 1111 1xxx */
DECODE_REJECT ( 0xfff8 , 0x47f8 ) ,
/* BX (register) 0100 0111 0xxx xxxx */
/* BLX (register) 0100 0111 1xxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_SIMULATE ( 0xff00 , 0x4700 , PROBES_T16_BLX ) ,
2014-03-06 06:06:29 +04:00
/* ADD pc, pc 0100 0100 1111 1111 */
DECODE_REJECT ( 0xffff , 0x44ff ) ,
/* ADD (register) 0100 0100 xxxx xxxx */
/* CMP (register) 0100 0101 xxxx xxxx */
/* MOV (register) 0100 0110 xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_CUSTOM ( 0xfc00 , 0x4400 , PROBES_T16_HIREGOPS ) ,
2014-03-06 06:06:29 +04:00
/*
* Load from Literal Pool
* LDR ( literal ) 0100 1 xxx xxxx xxxx
*/
2014-03-07 03:06:43 +04:00
DECODE_SIMULATE ( 0xf800 , 0x4800 , PROBES_T16_LDR_LIT ) ,
2014-03-06 06:06:29 +04:00
/*
* 16 - bit Thumb Load / store instructions
* 0101 xxxx xxxx xxxx
* 011 x xxxx xxxx xxxx
* 100 x xxxx xxxx xxxx
*/
/* STR (register) 0101 000x xxxx xxxx */
/* STRH (register) 0101 001x xxxx xxxx */
/* STRB (register) 0101 010x xxxx xxxx */
/* LDRSB (register) 0101 011x xxxx xxxx */
/* LDR (register) 0101 100x xxxx xxxx */
/* LDRH (register) 0101 101x xxxx xxxx */
/* LDRB (register) 0101 110x xxxx xxxx */
/* LDRSH (register) 0101 111x xxxx xxxx */
/* STR (immediate, Thumb) 0110 0xxx xxxx xxxx */
/* LDR (immediate, Thumb) 0110 1xxx xxxx xxxx */
/* STRB (immediate, Thumb) 0111 0xxx xxxx xxxx */
/* LDRB (immediate, Thumb) 0111 1xxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATE ( 0xc000 , 0x4000 , PROBES_T16_LDRHSTRH ) ,
2014-03-06 06:06:29 +04:00
/* STRH (immediate, Thumb) 1000 0xxx xxxx xxxx */
/* LDRH (immediate, Thumb) 1000 1xxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATE ( 0xf000 , 0x8000 , PROBES_T16_LDRHSTRH ) ,
2014-03-06 06:06:29 +04:00
/* STR (immediate, Thumb) 1001 0xxx xxxx xxxx */
/* LDR (immediate, Thumb) 1001 1xxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_SIMULATE ( 0xf000 , 0x9000 , PROBES_T16_LDRSTR ) ,
2014-03-06 06:06:29 +04:00
/*
* Generate PC - / SP - relative address
* ADR ( literal ) 1010 0 xxx xxxx xxxx
* ADD ( SP plus immediate ) 1010 1 xxx xxxx xxxx
*/
2014-03-07 03:06:43 +04:00
DECODE_SIMULATE ( 0xf000 , 0xa000 , PROBES_T16_ADR ) ,
2014-03-06 06:06:29 +04:00
/*
* Miscellaneous 16 - bit instructions
* 1011 xxxx xxxx xxxx
*/
DECODE_TABLE ( 0xf000 , 0xb000 , t16_table_1011 ) ,
/* STM 1100 0xxx xxxx xxxx */
/* LDM 1100 1xxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_EMULATE ( 0xf000 , 0xc000 , PROBES_T16_LDMSTM ) ,
2014-03-06 06:06:29 +04:00
/*
* Conditional branch , and Supervisor Call
*/
/* Permanently UNDEFINED 1101 1110 xxxx xxxx */
/* SVC 1101 1111 xxxx xxxx */
DECODE_REJECT ( 0xfe00 , 0xde00 ) ,
/* Conditional branch 1101 xxxx xxxx xxxx */
2014-03-07 03:06:43 +04:00
DECODE_CUSTOM ( 0xf000 , 0xd000 , PROBES_T16_BRANCH_COND ) ,
2014-03-06 06:06:29 +04:00
/*
* Unconditional branch
* B 1110 0 xxx xxxx xxxx
*/
2014-03-07 03:06:43 +04:00
DECODE_SIMULATE ( 0xf800 , 0xe000 , PROBES_T16_BRANCH ) ,
2014-03-06 06:06:29 +04:00
DECODE_END
} ;
# ifdef CONFIG_ARM_KPROBES_TEST_MODULE
2014-03-07 03:12:07 +04:00
EXPORT_SYMBOL_GPL ( probes_decode_thumb16_table ) ;
2014-03-06 06:06:29 +04:00
# endif
static unsigned long __kprobes thumb_check_cc ( unsigned long cpsr )
{
if ( unlikely ( in_it_block ( cpsr ) ) )
2014-03-06 06:17:23 +04:00
return probes_condition_checks [ current_cond ( cpsr ) ] ( cpsr ) ;
2014-03-06 06:06:29 +04:00
return true ;
}
2014-03-06 06:17:23 +04:00
static void __kprobes thumb16_singlestep ( probes_opcode_t opcode ,
2014-03-06 06:41:29 +04:00
struct arch_probes_insn * asi ,
2014-03-07 20:19:32 +04:00
struct pt_regs * regs )
2014-03-06 06:06:29 +04:00
{
regs - > ARM_pc + = 2 ;
2014-03-07 20:19:32 +04:00
asi - > insn_handler ( opcode , asi , regs ) ;
2014-03-06 06:06:29 +04:00
regs - > ARM_cpsr = it_advance ( regs - > ARM_cpsr ) ;
}
2014-03-06 06:17:23 +04:00
static void __kprobes thumb32_singlestep ( probes_opcode_t opcode ,
2014-03-06 06:41:29 +04:00
struct arch_probes_insn * asi ,
2014-03-07 20:19:32 +04:00
struct pt_regs * regs )
2014-03-06 06:06:29 +04:00
{
regs - > ARM_pc + = 4 ;
2014-03-07 20:19:32 +04:00
asi - > insn_handler ( opcode , asi , regs ) ;
2014-03-06 06:06:29 +04:00
regs - > ARM_cpsr = it_advance ( regs - > ARM_cpsr ) ;
}
2014-03-06 06:23:42 +04:00
enum probes_insn __kprobes
2014-03-06 06:41:29 +04:00
thumb16_probes_decode_insn ( probes_opcode_t insn , struct arch_probes_insn * asi ,
2015-01-05 14:29:18 +03:00
bool emulate , const union decode_action * actions ,
const struct decode_checker * checkers [ ] )
2014-03-06 06:06:29 +04:00
{
asi - > insn_singlestep = thumb16_singlestep ;
asi - > insn_check_cc = thumb_check_cc ;
2014-03-07 03:12:07 +04:00
return probes_decode_insn ( insn , asi , probes_decode_thumb16_table , true ,
2015-01-05 14:29:18 +03:00
emulate , actions , checkers ) ;
2014-03-06 06:06:29 +04:00
}
2014-03-06 06:23:42 +04:00
enum probes_insn __kprobes
2014-03-06 06:41:29 +04:00
thumb32_probes_decode_insn ( probes_opcode_t insn , struct arch_probes_insn * asi ,
2015-01-05 14:29:18 +03:00
bool emulate , const union decode_action * actions ,
const struct decode_checker * checkers [ ] )
2014-03-06 06:06:29 +04:00
{
asi - > insn_singlestep = thumb32_singlestep ;
asi - > insn_check_cc = thumb_check_cc ;
2014-03-07 03:12:07 +04:00
return probes_decode_insn ( insn , asi , probes_decode_thumb32_table , true ,
2015-01-05 14:29:18 +03:00
emulate , actions , checkers ) ;
2014-03-06 06:06:29 +04:00
}