diff options
Diffstat (limited to 'arch/s390/kernel/dis.c')
-rw-r--r-- | arch/s390/kernel/dis.c | 81 |
1 files changed, 27 insertions, 54 deletions
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c index be87d3e05a5b..993efe6a887c 100644 --- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/kdebug.h> | 23 | #include <linux/kdebug.h> |
24 | 24 | ||
25 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
26 | #include <asm/dis.h> | ||
26 | #include <asm/io.h> | 27 | #include <asm/io.h> |
27 | #include <linux/atomic.h> | 28 | #include <linux/atomic.h> |
28 | #include <asm/mathemu.h> | 29 | #include <asm/mathemu.h> |
@@ -37,17 +38,6 @@ | |||
37 | #define ONELONG "%016lx: " | 38 | #define ONELONG "%016lx: " |
38 | #endif /* CONFIG_64BIT */ | 39 | #endif /* CONFIG_64BIT */ |
39 | 40 | ||
40 | #define OPERAND_GPR 0x1 /* Operand printed as %rx */ | ||
41 | #define OPERAND_FPR 0x2 /* Operand printed as %fx */ | ||
42 | #define OPERAND_AR 0x4 /* Operand printed as %ax */ | ||
43 | #define OPERAND_CR 0x8 /* Operand printed as %cx */ | ||
44 | #define OPERAND_DISP 0x10 /* Operand printed as displacement */ | ||
45 | #define OPERAND_BASE 0x20 /* Operand printed as base register */ | ||
46 | #define OPERAND_INDEX 0x40 /* Operand printed as index register */ | ||
47 | #define OPERAND_PCREL 0x80 /* Operand printed as pc-relative symbol */ | ||
48 | #define OPERAND_SIGNED 0x100 /* Operand printed as signed value */ | ||
49 | #define OPERAND_LENGTH 0x200 /* Operand printed as length (+1) */ | ||
50 | |||
51 | enum { | 41 | enum { |
52 | UNUSED, /* Indicates the end of the operand list */ | 42 | UNUSED, /* Indicates the end of the operand list */ |
53 | R_8, /* GPR starting at position 8 */ | 43 | R_8, /* GPR starting at position 8 */ |
@@ -155,19 +145,7 @@ enum { | |||
155 | INSTR_S_00, INSTR_S_RD, | 145 | INSTR_S_00, INSTR_S_RD, |
156 | }; | 146 | }; |
157 | 147 | ||
158 | struct operand { | 148 | static const struct s390_operand operands[] = |
159 | int bits; /* The number of bits in the operand. */ | ||
160 | int shift; /* The number of bits to shift. */ | ||
161 | int flags; /* One bit syntax flags. */ | ||
162 | }; | ||
163 | |||
164 | struct insn { | ||
165 | const char name[5]; | ||
166 | unsigned char opfrag; | ||
167 | unsigned char format; | ||
168 | }; | ||
169 | |||
170 | static const struct operand operands[] = | ||
171 | { | 149 | { |
172 | [UNUSED] = { 0, 0, 0 }, | 150 | [UNUSED] = { 0, 0, 0 }, |
173 | [R_8] = { 4, 8, OPERAND_GPR }, | 151 | [R_8] = { 4, 8, OPERAND_GPR }, |
@@ -479,7 +457,7 @@ static char *long_insn_name[] = { | |||
479 | [LONG_INSN_PCISTB] = "pcistb", | 457 | [LONG_INSN_PCISTB] = "pcistb", |
480 | }; | 458 | }; |
481 | 459 | ||
482 | static struct insn opcode[] = { | 460 | static struct s390_insn opcode[] = { |
483 | #ifdef CONFIG_64BIT | 461 | #ifdef CONFIG_64BIT |
484 | { "bprp", 0xc5, INSTR_MII_UPI }, | 462 | { "bprp", 0xc5, INSTR_MII_UPI }, |
485 | { "bpp", 0xc7, INSTR_SMI_U0RDP }, | 463 | { "bpp", 0xc7, INSTR_SMI_U0RDP }, |
@@ -668,7 +646,7 @@ static struct insn opcode[] = { | |||
668 | { "", 0, INSTR_INVALID } | 646 | { "", 0, INSTR_INVALID } |
669 | }; | 647 | }; |
670 | 648 | ||
671 | static struct insn opcode_01[] = { | 649 | static struct s390_insn opcode_01[] = { |
672 | #ifdef CONFIG_64BIT | 650 | #ifdef CONFIG_64BIT |
673 | { "ptff", 0x04, INSTR_E }, | 651 | { "ptff", 0x04, INSTR_E }, |
674 | { "pfpo", 0x0a, INSTR_E }, | 652 | { "pfpo", 0x0a, INSTR_E }, |
@@ -684,7 +662,7 @@ static struct insn opcode_01[] = { | |||
684 | { "", 0, INSTR_INVALID } | 662 | { "", 0, INSTR_INVALID } |
685 | }; | 663 | }; |
686 | 664 | ||
687 | static struct insn opcode_a5[] = { | 665 | static struct s390_insn opcode_a5[] = { |
688 | #ifdef CONFIG_64BIT | 666 | #ifdef CONFIG_64BIT |
689 | { "iihh", 0x00, INSTR_RI_RU }, | 667 | { "iihh", 0x00, INSTR_RI_RU }, |
690 | { "iihl", 0x01, INSTR_RI_RU }, | 668 | { "iihl", 0x01, INSTR_RI_RU }, |
@@ -706,7 +684,7 @@ static struct insn opcode_a5[] = { | |||
706 | { "", 0, INSTR_INVALID } | 684 | { "", 0, INSTR_INVALID } |
707 | }; | 685 | }; |
708 | 686 | ||
709 | static struct insn opcode_a7[] = { | 687 | static struct s390_insn opcode_a7[] = { |
710 | #ifdef CONFIG_64BIT | 688 | #ifdef CONFIG_64BIT |
711 | { "tmhh", 0x02, INSTR_RI_RU }, | 689 | { "tmhh", 0x02, INSTR_RI_RU }, |
712 | { "tmhl", 0x03, INSTR_RI_RU }, | 690 | { "tmhl", 0x03, INSTR_RI_RU }, |
@@ -728,7 +706,7 @@ static struct insn opcode_a7[] = { | |||
728 | { "", 0, INSTR_INVALID } | 706 | { "", 0, INSTR_INVALID } |
729 | }; | 707 | }; |
730 | 708 | ||
731 | static struct insn opcode_aa[] = { | 709 | static struct s390_insn opcode_aa[] = { |
732 | #ifdef CONFIG_64BIT | 710 | #ifdef CONFIG_64BIT |
733 | { { 0, LONG_INSN_RINEXT }, 0x00, INSTR_RI_RI }, | 711 | { { 0, LONG_INSN_RINEXT }, 0x00, INSTR_RI_RI }, |
734 | { "rion", 0x01, INSTR_RI_RI }, | 712 | { "rion", 0x01, INSTR_RI_RI }, |
@@ -739,7 +717,7 @@ static struct insn opcode_aa[] = { | |||
739 | { "", 0, INSTR_INVALID } | 717 | { "", 0, INSTR_INVALID } |
740 | }; | 718 | }; |
741 | 719 | ||
742 | static struct insn opcode_b2[] = { | 720 | static struct s390_insn opcode_b2[] = { |
743 | #ifdef CONFIG_64BIT | 721 | #ifdef CONFIG_64BIT |
744 | { "stckf", 0x7c, INSTR_S_RD }, | 722 | { "stckf", 0x7c, INSTR_S_RD }, |
745 | { "lpp", 0x80, INSTR_S_RD }, | 723 | { "lpp", 0x80, INSTR_S_RD }, |
@@ -851,7 +829,7 @@ static struct insn opcode_b2[] = { | |||
851 | { "", 0, INSTR_INVALID } | 829 | { "", 0, INSTR_INVALID } |
852 | }; | 830 | }; |
853 | 831 | ||
854 | static struct insn opcode_b3[] = { | 832 | static struct s390_insn opcode_b3[] = { |
855 | #ifdef CONFIG_64BIT | 833 | #ifdef CONFIG_64BIT |
856 | { "maylr", 0x38, INSTR_RRF_F0FF }, | 834 | { "maylr", 0x38, INSTR_RRF_F0FF }, |
857 | { "mylr", 0x39, INSTR_RRF_F0FF }, | 835 | { "mylr", 0x39, INSTR_RRF_F0FF }, |
@@ -1034,7 +1012,7 @@ static struct insn opcode_b3[] = { | |||
1034 | { "", 0, INSTR_INVALID } | 1012 | { "", 0, INSTR_INVALID } |
1035 | }; | 1013 | }; |
1036 | 1014 | ||
1037 | static struct insn opcode_b9[] = { | 1015 | static struct s390_insn opcode_b9[] = { |
1038 | #ifdef CONFIG_64BIT | 1016 | #ifdef CONFIG_64BIT |
1039 | { "lpgr", 0x00, INSTR_RRE_RR }, | 1017 | { "lpgr", 0x00, INSTR_RRE_RR }, |
1040 | { "lngr", 0x01, INSTR_RRE_RR }, | 1018 | { "lngr", 0x01, INSTR_RRE_RR }, |
@@ -1167,7 +1145,7 @@ static struct insn opcode_b9[] = { | |||
1167 | { "", 0, INSTR_INVALID } | 1145 | { "", 0, INSTR_INVALID } |
1168 | }; | 1146 | }; |
1169 | 1147 | ||
1170 | static struct insn opcode_c0[] = { | 1148 | static struct s390_insn opcode_c0[] = { |
1171 | #ifdef CONFIG_64BIT | 1149 | #ifdef CONFIG_64BIT |
1172 | { "lgfi", 0x01, INSTR_RIL_RI }, | 1150 | { "lgfi", 0x01, INSTR_RIL_RI }, |
1173 | { "xihf", 0x06, INSTR_RIL_RU }, | 1151 | { "xihf", 0x06, INSTR_RIL_RU }, |
@@ -1187,7 +1165,7 @@ static struct insn opcode_c0[] = { | |||
1187 | { "", 0, INSTR_INVALID } | 1165 | { "", 0, INSTR_INVALID } |
1188 | }; | 1166 | }; |
1189 | 1167 | ||
1190 | static struct insn opcode_c2[] = { | 1168 | static struct s390_insn opcode_c2[] = { |
1191 | #ifdef CONFIG_64BIT | 1169 | #ifdef CONFIG_64BIT |
1192 | { "msgfi", 0x00, INSTR_RIL_RI }, | 1170 | { "msgfi", 0x00, INSTR_RIL_RI }, |
1193 | { "msfi", 0x01, INSTR_RIL_RI }, | 1171 | { "msfi", 0x01, INSTR_RIL_RI }, |
@@ -1205,7 +1183,7 @@ static struct insn opcode_c2[] = { | |||
1205 | { "", 0, INSTR_INVALID } | 1183 | { "", 0, INSTR_INVALID } |
1206 | }; | 1184 | }; |
1207 | 1185 | ||
1208 | static struct insn opcode_c4[] = { | 1186 | static struct s390_insn opcode_c4[] = { |
1209 | #ifdef CONFIG_64BIT | 1187 | #ifdef CONFIG_64BIT |
1210 | { "llhrl", 0x02, INSTR_RIL_RP }, | 1188 | { "llhrl", 0x02, INSTR_RIL_RP }, |
1211 | { "lghrl", 0x04, INSTR_RIL_RP }, | 1189 | { "lghrl", 0x04, INSTR_RIL_RP }, |
@@ -1222,7 +1200,7 @@ static struct insn opcode_c4[] = { | |||
1222 | { "", 0, INSTR_INVALID } | 1200 | { "", 0, INSTR_INVALID } |
1223 | }; | 1201 | }; |
1224 | 1202 | ||
1225 | static struct insn opcode_c6[] = { | 1203 | static struct s390_insn opcode_c6[] = { |
1226 | #ifdef CONFIG_64BIT | 1204 | #ifdef CONFIG_64BIT |
1227 | { "exrl", 0x00, INSTR_RIL_RP }, | 1205 | { "exrl", 0x00, INSTR_RIL_RP }, |
1228 | { "pfdrl", 0x02, INSTR_RIL_UP }, | 1206 | { "pfdrl", 0x02, INSTR_RIL_UP }, |
@@ -1240,7 +1218,7 @@ static struct insn opcode_c6[] = { | |||
1240 | { "", 0, INSTR_INVALID } | 1218 | { "", 0, INSTR_INVALID } |
1241 | }; | 1219 | }; |
1242 | 1220 | ||
1243 | static struct insn opcode_c8[] = { | 1221 | static struct s390_insn opcode_c8[] = { |
1244 | #ifdef CONFIG_64BIT | 1222 | #ifdef CONFIG_64BIT |
1245 | { "mvcos", 0x00, INSTR_SSF_RRDRD }, | 1223 | { "mvcos", 0x00, INSTR_SSF_RRDRD }, |
1246 | { "ectg", 0x01, INSTR_SSF_RRDRD }, | 1224 | { "ectg", 0x01, INSTR_SSF_RRDRD }, |
@@ -1251,7 +1229,7 @@ static struct insn opcode_c8[] = { | |||
1251 | { "", 0, INSTR_INVALID } | 1229 | { "", 0, INSTR_INVALID } |
1252 | }; | 1230 | }; |
1253 | 1231 | ||
1254 | static struct insn opcode_cc[] = { | 1232 | static struct s390_insn opcode_cc[] = { |
1255 | #ifdef CONFIG_64BIT | 1233 | #ifdef CONFIG_64BIT |
1256 | { "brcth", 0x06, INSTR_RIL_RP }, | 1234 | { "brcth", 0x06, INSTR_RIL_RP }, |
1257 | { "aih", 0x08, INSTR_RIL_RI }, | 1235 | { "aih", 0x08, INSTR_RIL_RI }, |
@@ -1263,7 +1241,7 @@ static struct insn opcode_cc[] = { | |||
1263 | { "", 0, INSTR_INVALID } | 1241 | { "", 0, INSTR_INVALID } |
1264 | }; | 1242 | }; |
1265 | 1243 | ||
1266 | static struct insn opcode_e3[] = { | 1244 | static struct s390_insn opcode_e3[] = { |
1267 | #ifdef CONFIG_64BIT | 1245 | #ifdef CONFIG_64BIT |
1268 | { "ltg", 0x02, INSTR_RXY_RRRD }, | 1246 | { "ltg", 0x02, INSTR_RXY_RRRD }, |
1269 | { "lrag", 0x03, INSTR_RXY_RRRD }, | 1247 | { "lrag", 0x03, INSTR_RXY_RRRD }, |
@@ -1369,7 +1347,7 @@ static struct insn opcode_e3[] = { | |||
1369 | { "", 0, INSTR_INVALID } | 1347 | { "", 0, INSTR_INVALID } |
1370 | }; | 1348 | }; |
1371 | 1349 | ||
1372 | static struct insn opcode_e5[] = { | 1350 | static struct s390_insn opcode_e5[] = { |
1373 | #ifdef CONFIG_64BIT | 1351 | #ifdef CONFIG_64BIT |
1374 | { "strag", 0x02, INSTR_SSE_RDRD }, | 1352 | { "strag", 0x02, INSTR_SSE_RDRD }, |
1375 | { "mvhhi", 0x44, INSTR_SIL_RDI }, | 1353 | { "mvhhi", 0x44, INSTR_SIL_RDI }, |
@@ -1391,7 +1369,7 @@ static struct insn opcode_e5[] = { | |||
1391 | { "", 0, INSTR_INVALID } | 1369 | { "", 0, INSTR_INVALID } |
1392 | }; | 1370 | }; |
1393 | 1371 | ||
1394 | static struct insn opcode_eb[] = { | 1372 | static struct s390_insn opcode_eb[] = { |
1395 | #ifdef CONFIG_64BIT | 1373 | #ifdef CONFIG_64BIT |
1396 | { "lmg", 0x04, INSTR_RSY_RRRD }, | 1374 | { "lmg", 0x04, INSTR_RSY_RRRD }, |
1397 | { "srag", 0x0a, INSTR_RSY_RRRD }, | 1375 | { "srag", 0x0a, INSTR_RSY_RRRD }, |
@@ -1465,7 +1443,7 @@ static struct insn opcode_eb[] = { | |||
1465 | { "", 0, INSTR_INVALID } | 1443 | { "", 0, INSTR_INVALID } |
1466 | }; | 1444 | }; |
1467 | 1445 | ||
1468 | static struct insn opcode_ec[] = { | 1446 | static struct s390_insn opcode_ec[] = { |
1469 | #ifdef CONFIG_64BIT | 1447 | #ifdef CONFIG_64BIT |
1470 | { "brxhg", 0x44, INSTR_RIE_RRP }, | 1448 | { "brxhg", 0x44, INSTR_RIE_RRP }, |
1471 | { "brxlg", 0x45, INSTR_RIE_RRP }, | 1449 | { "brxlg", 0x45, INSTR_RIE_RRP }, |
@@ -1504,7 +1482,7 @@ static struct insn opcode_ec[] = { | |||
1504 | { "", 0, INSTR_INVALID } | 1482 | { "", 0, INSTR_INVALID } |
1505 | }; | 1483 | }; |
1506 | 1484 | ||
1507 | static struct insn opcode_ed[] = { | 1485 | static struct s390_insn opcode_ed[] = { |
1508 | #ifdef CONFIG_64BIT | 1486 | #ifdef CONFIG_64BIT |
1509 | { "mayl", 0x38, INSTR_RXF_FRRDF }, | 1487 | { "mayl", 0x38, INSTR_RXF_FRRDF }, |
1510 | { "myl", 0x39, INSTR_RXF_FRRDF }, | 1488 | { "myl", 0x39, INSTR_RXF_FRRDF }, |
@@ -1572,7 +1550,7 @@ static struct insn opcode_ed[] = { | |||
1572 | 1550 | ||
1573 | /* Extracts an operand value from an instruction. */ | 1551 | /* Extracts an operand value from an instruction. */ |
1574 | static unsigned int extract_operand(unsigned char *code, | 1552 | static unsigned int extract_operand(unsigned char *code, |
1575 | const struct operand *operand) | 1553 | const struct s390_operand *operand) |
1576 | { | 1554 | { |
1577 | unsigned int val; | 1555 | unsigned int val; |
1578 | int bits; | 1556 | int bits; |
@@ -1608,16 +1586,11 @@ static unsigned int extract_operand(unsigned char *code, | |||
1608 | return val; | 1586 | return val; |
1609 | } | 1587 | } |
1610 | 1588 | ||
1611 | static inline int insn_length(unsigned char code) | 1589 | struct s390_insn *find_insn(unsigned char *code) |
1612 | { | ||
1613 | return ((((int) code + 64) >> 7) + 1) << 1; | ||
1614 | } | ||
1615 | |||
1616 | static struct insn *find_insn(unsigned char *code) | ||
1617 | { | 1590 | { |
1618 | unsigned char opfrag = code[1]; | 1591 | unsigned char opfrag = code[1]; |
1619 | unsigned char opmask; | 1592 | unsigned char opmask; |
1620 | struct insn *table; | 1593 | struct s390_insn *table; |
1621 | 1594 | ||
1622 | switch (code[0]) { | 1595 | switch (code[0]) { |
1623 | case 0x01: | 1596 | case 0x01: |
@@ -1706,7 +1679,7 @@ static struct insn *find_insn(unsigned char *code) | |||
1706 | */ | 1679 | */ |
1707 | int insn_to_mnemonic(unsigned char *instruction, char *buf, unsigned int len) | 1680 | int insn_to_mnemonic(unsigned char *instruction, char *buf, unsigned int len) |
1708 | { | 1681 | { |
1709 | struct insn *insn; | 1682 | struct s390_insn *insn; |
1710 | 1683 | ||
1711 | insn = find_insn(instruction); | 1684 | insn = find_insn(instruction); |
1712 | if (!insn) | 1685 | if (!insn) |
@@ -1722,9 +1695,9 @@ EXPORT_SYMBOL_GPL(insn_to_mnemonic); | |||
1722 | 1695 | ||
1723 | static int print_insn(char *buffer, unsigned char *code, unsigned long addr) | 1696 | static int print_insn(char *buffer, unsigned char *code, unsigned long addr) |
1724 | { | 1697 | { |
1725 | struct insn *insn; | 1698 | struct s390_insn *insn; |
1726 | const unsigned char *ops; | 1699 | const unsigned char *ops; |
1727 | const struct operand *operand; | 1700 | const struct s390_operand *operand; |
1728 | unsigned int value; | 1701 | unsigned int value; |
1729 | char separator; | 1702 | char separator; |
1730 | char *ptr; | 1703 | char *ptr; |