return 0;
}
-static int t32_b1110_100x_x1(thumb_insn_t insn, struct decode_info *info)
+/* load/store multiple */
+static int t32_1110_100x_x0(thumb_insn_t insn, struct decode_info *info)
+{
+ return thumb_not_implement(insn, info);
+}
+
+/* load/store dual, load/store exclusive, table branch */
+static int t32_1110_100x_x1(thumb_insn_t insn, struct decode_info *info)
{
/* check PW bits */
if (insn.hw1 & 0x120)
return thumb_not_implement(insn, info);
}
-static int t32_b1110_100(thumb_insn_t insn, struct decode_info *info)
+/* data-processing (shifled register) */
+static int t32_1110_101(thumb_insn_t insn, struct decode_info *info)
{
- if (GET_BIT(insn.hw1, 6))
- return t32_b1110_100x_x1(insn, info);
+ return thumb_not_implement(insn, info);
+}
+/* coprocessor, advanced SIMD, and floating-point instructions */
+static int t32_1110_11(thumb_insn_t insn, struct decode_info *info)
+{
return thumb_not_implement(insn, info);
}
return 0;
}
-static decode_handler_t table_branches[8] = {
- /* hw2[14 12 0] */
- /* Bc 0 0 0 */ thumb_not_implement,
- /* Bc 0 0 1 */ thumb_not_implement,
- /* B 0 1 0 */ t32_branch,
- /* B 0 1 1 */ t32_branch,
- /* BLX 1 0 0 */ t32_branch,
- /* res 1 0 1 */ thumb_unpredictable,
- /* BL 1 1 0 */ t32_branch,
- /* BL 1 1 1 */ t32_branch,
+/* data-processing (modified immediate) */
+static int t32_1111_0x0x_xxxx_xxxx_0(thumb_insn_t insn,
+ struct decode_info *info)
+{
+ return thumb_not_implement(insn, info);
+}
+
+/* data-processing (plain binary immediate) */
+static int t32_1111_0x1x_xxxx_xxxx_0(thumb_insn_t insn,
+ struct decode_info *info)
+{
+ return thumb_not_implement(insn, info);
+}
+
+/* conditional branch, move to blanked or special register */
+static int t32_1111_0011_100x_xxxx_10x0(thumb_insn_t insn,
+ struct decode_info *info)
+{
+ return thumb_not_implement(insn, info);
+}
+
+/* change processor state, and hints */
+static int t32_1111_0011_1010_xxxx_10x0(thumb_insn_t insn,
+ struct decode_info *info)
+{
+ return thumb_not_implement(insn, info);
+}
+
+/* miscellaneous control instructions */
+static int t32_1111_0011_1011_xxxx_10x0(thumb_insn_t insn,
+ struct decode_info *info)
+{
+ return thumb_not_implement(insn, info);
+}
+
+/* branch and exchange jazelle */
+static int t32_1111_0011_1100_xxxx_10x0(thumb_insn_t insn,
+ struct decode_info *info)
+{
+ return thumb_not_implement(insn, info);
+}
+
+/* exeption return */
+static int t32_1111_0011_1101_xxxx_10x0(thumb_insn_t insn,
+ struct decode_info *info)
+{
+ return thumb_not_implement(insn, info);
+}
+
+/* move from banked or special register */
+static int t32_1111_0011_111x_xxxx_10x0(thumb_insn_t insn,
+ struct decode_info *info)
+{
+ return thumb_not_implement(insn, info);
+}
+
+static decode_handler_t t32_1111_0011_1XXX_xxxx_10x0[8] = {
+ /* 000 */ t32_1111_0011_100x_xxxx_10x0,
+ /* 001 */ t32_1111_0011_100x_xxxx_10x0,
+ /* 010 */ t32_1111_0011_1010_xxxx_10x0,
+ /* 011 */ t32_1111_0011_1011_xxxx_10x0,
+ /* 100 */ t32_1111_0011_1100_xxxx_10x0,
+ /* 101 */ t32_1111_0011_1101_xxxx_10x0,
+ /* 110 */ t32_1111_0011_111x_xxxx_10x0,
+ /* 111 */ t32_1111_0011_111x_xxxx_10x0,
};
+static int t32_1111_0xxx_xxxx_xxxx_10x0(thumb_insn_t insn,
+ struct decode_info *info)
+{
+ unsigned char op = GET_FIELD(insn.hw1, 4, 7);
+
+ if (GET_FIELD(op, 3, 3) == 0x7) {
+ if (GET_BIT(op, 6) == 0) {
+ unsigned char val = GET_FIELD(op, 0, 3);
-static int t32_b1111_0xxx_xxxx_xxxx_1(thumb_insn_t insn,
+ return t32_1111_0011_1XXX_xxxx_10x0[val](insn, info);
+ } else {
+ /* hypervisor call and secure monitor call */
+ return thumb_not_implement(insn, info);
+ }
+ } else {
+ /* conditional branch */
+ return thumb_not_implement(insn, info);
+ }
+}
+
+static int t32_1111_0xxx_xxxx_xxxx_10x1(thumb_insn_t insn,
+ struct decode_info *info)
+{
+ return t32_branch(insn, info);
+}
+
+static int t32_1111_0xxx_xxxx_xxxx_11x0(thumb_insn_t insn,
+ struct decode_info *info)
+{
+ return t32_branch(insn, info);
+}
+
+static int t32_1111_0xxx_xxxx_xxxx_11x1(thumb_insn_t insn,
+ struct decode_info *info)
+{
+ return t32_branch(insn, info);
+}
+
+static decode_handler_t table_1111_0xxx_xxxx_xxxx_1XXX[8] = {
+ /* 000 */ t32_1111_0xxx_xxxx_xxxx_10x0,
+ /* 001 */ t32_1111_0xxx_xxxx_xxxx_10x1,
+ /* 010 */ t32_1111_0xxx_xxxx_xxxx_10x0,
+ /* 011 */ t32_1111_0xxx_xxxx_xxxx_10x1,
+ /* 100 */ t32_1111_0xxx_xxxx_xxxx_11x0,
+ /* 101 */ t32_1111_0xxx_xxxx_xxxx_11x1,
+ /* 110 */ t32_1111_0xxx_xxxx_xxxx_11x0,
+ /* 111 */ t32_1111_0xxx_xxxx_xxxx_11x1,
+};
+
+/* branches and miscellaneous control */
+static int t32_1111_0xxx_xxxx_xxxx_1(thumb_insn_t insn,
struct decode_info *info)
{
- u32 s = GET_BIT(insn.hw2, 14) << 2 |
- GET_BIT(insn.hw2, 12) << 1 |
- GET_BIT(insn.hw2, 0);
+ unsigned char op1 = GET_FIELD(insn.hw2, 12, 3);
- return table_branches[s](insn, info);
+ /* check op1 bits hw1[1111 0??? ???? ???? 1xxx] */
+ return table_1111_0xxx_xxxx_xxxx_1XXX[op1](insn, info);
}
-static int b111(thumb_insn_t insn, struct decode_info *info)
+static int t32_1110_1(thumb_insn_t insn, struct decode_info *info)
{
- /* hw1[111x xxx? ???? ????] */
- switch (GET_FIELD(insn.hw1, 9, 4)) {
- case 0b0100:
- return t32_b1110_100(insn, info);
+ unsigned char op2 = GET_FIELD(insn.hw1, 4, 7);
+
+ if (GET_BIT(op2, 6) == 0) {
+ if (GET_BIT(op2, 5) == 0) {
+ if (GET_BIT(op2, 2) == 0)
+ return t32_1110_100x_x0(insn, info);
+ else
+ return t32_1110_100x_x1(insn, info);
+ } else {
+ return t32_1110_101(insn, info);
+ }
+ } else {
+ return t32_1110_11(insn, info);
}
- /* [1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx] */
- if (GET_FIELD(insn.hw1, 11, 2) == 0b10 && GET_BIT(insn.hw2, 15) == 1)
- return t32_b1111_0xxx_xxxx_xxxx_1(insn, info);
+ return thumb_not_implement(insn, info);
+}
+
+static int t32_1111_0(thumb_insn_t insn, struct decode_info *info)
+{
+ if (GET_BIT(insn.hw2, 15) == 0) {
+ if (GET_BIT(insn.hw1, 9) == 0)
+ return t32_1111_0x0x_xxxx_xxxx_0(insn, info);
+ else
+ return t32_1111_0x1x_xxxx_xxxx_0(insn, info);
+ } else {
+ /* [1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx] */
+ return t32_1111_0xxx_xxxx_xxxx_1(insn, info);
+ }
return thumb_not_implement(insn, info);
}
+decode_handler_t table_111x_x[4] = {
+ /* 00 | 16-bit */ thumb_not_implement,
+ /* 01 | 32-bit */ t32_1110_1,
+ /* 10 | 32-bit */ t32_1111_0,
+ /* 11 | 32-bit */ thumb_not_implement,
+};
+
+static int b111(thumb_insn_t insn, struct decode_info *info)
+{
+ unsigned char op1 = GET_FIELD(insn.hw1, 11, 2);
+
+ /* check op1 bits hw1[111x x??? ???? ????] */
+ return table_111x_x[op1](insn, info);
+}
decode_handler_t table_xxx[8] = {
/* 000 */ thumb_not_implement,