1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2015 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
14 */
15
16 #include <stdio.h>
17 #include <libdisasm.h>
18 #include <sys/sysmacros.h>
19 #include <sys/byteorder.h>
20
21 #include "libdisasm_impl.h"
22
23 #define ILC2LEN(ilc) (2 * ((ilc) >= 2 ? (ilc) : (ilc) + 1))
24
25 /*
26 * Throughout this file, the instruction format names based on:
27 * SA22-7832-09 z/Architecture Principles of Operation
28 *
29 * System/370, ESA/390, and earlier z/Architecture POP use slightly
30 * different names for the formats (the variant names are numeric). For the
31 * sake of simplicity, we use the most detailed definitions - z/Architecture.
32 *
33 * For ESA/390 we map the formats:
34 * E -> E
35 * I -> I
36 * RR -> RR
37 * RRE -> RRE
38 * RRF -> RRD & RRFa-e
53 * For System/370 we map the formats:
54 * RR -> RR
55 * RX -> RXa-b
56 * RS -> RSa-b
57 * SI -> SI
58 * S -> S
59 * SS -> SSa-c
60 *
61 * Disassembly begins in tbl_xx. The first byte of the instruction is used
62 * as the index. This yields either an instruction or a sub-table.
63 *
64 * If an instruction is encountered, its format field is used to format the
65 * instruction.
66 *
67 * There are two types of sub-tables: extended opcode tables (indicated with
68 * IF_TBL) or a multiple mnemonics tables (indicated with IF_MULTI).
69 *
70 * Extended opcode tables indicade which additional bits of the instruction
71 * should be inspected. These bits are used as an index into the sub table.
72 *
73 * Multiple mnemonic tables, are used to print different mnemonics depending
74 * on the architecture. Over the years, certain instructions got a new
75 * preferred mnemonic. For example, 0xa70 is test-under-mask-high (tmh) on
76 * System/390. On z/Architecture systems, the instruction behaves
77 * identically (and the assembler hapilly accepts tmh), but the preferred
78 * mnemonic is tmlh (test-under-mask-low-high) because z/Architecture
79 * extended the general purpose registers from 32 bits to 64 bits. The
80 * current architecture flag (e.g., F_390) is used to index into the
81 * sub-table.
82 *
83 * Regardless of which sub-table is encountered, the selected entry in the
84 * sub-table is interpreted using the same rules as the contents of tbl_xx.
85 *
86 * Finally, we use the extended opcode sub-table mechanism to pretty print
87 * the branching instructions. All branches are conditional based on a
88 * 4-bit mask indicating which value of the condition code will result in a
89 * taken branch. In order to produce a more human friendly output, we use
90 * the 4-bit mask as an extended opcode to break up the branching
91 * instruction into 16 different ones. For example, instead of printing:
92 *
93 * bc 7,0x123(%r1,%r2)
94 *
95 * we print:
96 *
97 * bne 0x123(%r1,%r2)
98 */
99
100 /* BEGIN CSTYLED */
101 enum ifmt {
102 /* invalid */
103 IF_INVAL = 0,
104
105 /* indirection */
106 IF_TBL,
107 IF_MULTI,
108
109 /* 2-byte */
110 IF_ZERO, /* 370, 390, z */
111 IF_E, /* 390, z */
112 IF_I, /* 390, z */
113 IF_RR, /* 370, 390, z */
114
115 /* 4-byte */
116 IF_DIAG, /* 370, 390, z */
117 IF_IE, /* z */
164 IF_SSe, /* 390, z */
165 IF_SSf, /* 390, z */
166 IF_SSE, /* 390, z */
167 IF_SSF, /* z */
168 };
169
170 #define IF_NFMTS (IF_SSF + 1)
171
172 #define F_370 0x0001 /* 370 */
173 #define F_390 0x0002 /* 390 */
174 #define F_Z 0x0004 /* z */
175 #define F_SIGNED_IMM 0x0010 /* 370, 390, z */
176 #define F_CTL_REG 0x0020 /* 370, 390, z */
177 #define F_HIDE_MASK 0x0040 /* 370, 390, z */
178 #define F_R1_IS_MASK 0x0080 /* 370, 390, z */
179 /* END CSTYLED */
180
181 struct inst_table {
182 union {
183 struct {
184 const char *name;
185 unsigned flags;
186 } inst;
187 struct {
188 const struct inst_table *ptr;
189 uint8_t off:4;
190 uint8_t shift:4;
191 uint8_t mask;
192 } table;
193 struct {
194 const struct inst_table *ptr;
195 } multi;
196 } u;
197 enum ifmt fmt;
198 };
199
200 #define BITFLD(a, b) DECL_BITFIELD2(b:4, a:4)
201
202 union inst {
203 uint8_t raw[6];
204 struct {
205 uint8_t op;
206 uint8_t par1;
207 uint16_t par2;
208 } diag;
209 struct {
210 uint8_t op;
211 uint8_t i;
212 } i;
213 struct {
214 uint16_t op;
215 uint8_t pad;
216 BITFLD(i1, i2);
217 } ie;
513 uint8_t d2l;
514 } ss_f;
515 struct {
516 uint16_t op;
517 BITFLD(b1, d1h);
518 uint8_t d1l;
519 BITFLD(b2, d2h);
520 uint8_t d2l;
521 } sse;
522 struct {
523 uint8_t op1;
524 BITFLD(r3, op2);
525 BITFLD(b1, d1h);
526 uint8_t d1l;
527 BITFLD(b2, d2h);
528 uint8_t d2l;
529 } ssf;
530 };
531
532 #define INSTR(op, m, fm, fl) [op] = { \
533 .u.inst = { \
534 .name = (m), \
535 .flags = (fl), \
536 }, \
537 .fmt = (fm), \
538 }
539 #define TABLE(op, tbl, o, s, m) [op] = { \
540 .u.table = { \
541 .ptr = (tbl), \
542 .off = (o), \
543 .shift = (s), \
544 .mask = (m), \
545 }, \
546 .fmt = IF_TBL, \
547 }
548 #define MULTI(op, tbl) [op] = { \
549 .u.multi.ptr = (tbl), \
550 .fmt = IF_MULTI, \
551 }
552
553 /*
554 * Instruction tables based on:
555 * GA22-7000-4 System/370 Principles of Operation
556 * SA22-7201-08 ESA/390 Principles of Operation
557 * SA22-7832-09 z/Architecture Principles of Operation
558 */
559
560 /* BEGIN CSTYLED */
561 static const struct inst_table tbl_01xx[256] = {
562 INSTR(0x01, "pr", IF_E, F_390 | F_Z),
563 INSTR(0x02, "upt", IF_E, F_390 | F_Z),
564 INSTR(0x04, "ptff", IF_E, F_Z),
565 INSTR(0x07, "sckpf", IF_E, F_390 | F_Z),
566 INSTR(0x0a, "pfpo", IF_E, F_Z),
567 INSTR(0x0b, "tam", IF_E, F_390 | F_Z),
568 INSTR(0x0c, "sam24", IF_E, F_390 | F_Z),
569 INSTR(0x0d, "sam31", IF_E, F_390 | F_Z),
570 INSTR(0x0e, "sam64", IF_E, F_Z),
1773
1774 /* how general purpose regs are printed */
1775 static const char *R[16] = {
1776 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1777 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1778 };
1779
1780 /* how control regs are printed */
1781 static const char *C[16] = {
1782 "%c0", "%c1", "%c2", "%c3", "%c4", "%c5", "%c6", "%c7",
1783 "%c8", "%c9", "%c10", "%c11", "%c12", "%c13", "%c14", "%c15",
1784 };
1785
1786 /* B and X registers are still registers - print them the same way */
1787 #define B R
1788 #define X R
1789
1790 static inline uint32_t
1791 val_8_4_8(uint32_t hi, uint32_t mid, uint32_t lo)
1792 {
1793 return ((hi << 12) | (mid << 8) | lo);
1794 }
1795
1796 static inline uint32_t
1797 val_16_16(uint32_t hi, uint32_t lo)
1798 {
1799 return ((BE_16(hi) << 16) | BE_16(lo));
1800 }
1801
1802 static inline int32_t
1803 sval_16_16(uint32_t hi, uint32_t lo)
1804 {
1805 return (val_16_16(hi, lo));
1806 }
1807
1808 static inline uint32_t
1809 val_8_16(uint32_t hi, uint32_t lo)
1810 {
1811 return ((hi << 16) | BE_16(lo));
1812 }
1813
1814 static inline int32_t
1815 sval_8_16(uint32_t hi, uint32_t lo)
1816 {
1817 int32_t tmp = val_8_16(hi, lo);
1818
1819 if (tmp & 0x00800000)
1820 return (0xff000000 | tmp);
1821 return (tmp);
1822 }
1823
1824 static inline uint32_t
1825 val_4_8(uint32_t hi, uint32_t lo)
1826 {
1827 return ((hi << 8) | lo);
1828 }
1829
1830 static inline int32_t
1831 sval_4_8(uint32_t hi, uint32_t lo)
1832 {
1833 uint32_t tmp = val_4_8(hi, lo);
1834
1835 if (tmp & 0x800)
1836 return (0xfffff000 | tmp);
1837 return (tmp);
1838 }
1839
1840 /* ARGSUSED */
1841 static void
1842 fmt_zero(uint64_t addr, union inst *inst, char *buf, size_t buflen, int flags)
1843 {
1844 (void) snprintf(buf, buflen, "0x00, 0x00");
1845 }
1846
1847 /* ARGSUSED */
1848 static void
1849 fmt_diag(uint64_t addr, union inst *inst, char *buf, size_t buflen, int flags)
1850 {
1851 (void) snprintf(buf, buflen, "%#x",
1852 val_8_16(inst->diag.par1, inst->diag.par2));
1853 }
1854
2451 [IF_SI] = fmt_si,
2452 [IF_SIL] = fmt_sil,
2453 [IF_SIY] = fmt_siy,
2454 [IF_SMI] = fmt_smi,
2455 [IF_SSa] = fmt_ss_a,
2456 [IF_SSb] = fmt_ss_b,
2457 [IF_SSc] = fmt_ss_c,
2458 [IF_SSd] = fmt_ss_d,
2459 [IF_SSe] = fmt_ss_e,
2460 [IF_SSf] = fmt_ss_f,
2461 [IF_SSE] = fmt_sse,
2462 [IF_SSF] = fmt_ssf,
2463 };
2464
2465 static int
2466 dis_s390(uint64_t addr, union inst *inst, char *buf, size_t buflen, int mach)
2467 {
2468 const struct inst_table *tbl = &tbl_xx[inst->raw[0]];
2469 int tmp;
2470
2471 while (tbl->fmt == IF_TBL || tbl->fmt == IF_MULTI) {
2472 if (tbl->fmt == IF_TBL) {
2473 int idx;
2474
2475 idx = inst->raw[tbl->u.table.off];
2476 idx >>= tbl->u.table.shift;
2477 idx &= tbl->u.table.mask;
2478
2479 tbl = &tbl->u.table.ptr[idx];
2480 } else if (tbl->fmt == IF_MULTI) {
2481 tbl = &tbl->u.multi.ptr[mach];
2482 }
2483 }
2484
2485 if (tbl->fmt == IF_INVAL)
2486 goto inval;
2487
2488 if ((tbl->u.inst.flags & mach) == 0)
2489 goto inval;
2490
2491 tmp = snprintf(buf, buflen, "%-7s ", tbl->u.inst.name);
2492
2493 fmt_fxns[tbl->fmt](addr, inst, buf + tmp, buflen - tmp,
2494 tbl->u.inst.flags);
2495
2496 return (0);
2497
2498 inval:
2499 (void) snprintf(buf, buflen, "??");
2500
2501 /*
2502 * Even if we don't know how to disassemble the instruction, we know
2503 * how long it is, so we "succeed" even when we fail.
2504 */
2505 return (0);
2506 }
2507
2508 static int
2509 dis_s390_supports_flags(int flags)
2510 {
2511 int archflags = flags & DIS_ARCH_MASK;
2512
2513 if (archflags == DIS_S370 || archflags == DIS_S390_31 ||
2514 archflags == DIS_S390_64)
|
1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2015 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
14 */
15
16 #include <stdio.h>
17 #include <libdisasm.h>
18 #include <sys/sysmacros.h>
19 #include <sys/debug.h>
20 #include <sys/byteorder.h>
21
22 #include "libdisasm_impl.h"
23
24 #define ILC2LEN(ilc) (2 * ((ilc) >= 2 ? (ilc) : (ilc) + 1))
25
26 /*
27 * Throughout this file, the instruction format names based on:
28 * SA22-7832-09 z/Architecture Principles of Operation
29 *
30 * System/370, ESA/390, and earlier z/Architecture POP use slightly
31 * different names for the formats (the variant names are numeric). For the
32 * sake of simplicity, we use the most detailed definitions - z/Architecture.
33 *
34 * For ESA/390 we map the formats:
35 * E -> E
36 * I -> I
37 * RR -> RR
38 * RRE -> RRE
39 * RRF -> RRD & RRFa-e
54 * For System/370 we map the formats:
55 * RR -> RR
56 * RX -> RXa-b
57 * RS -> RSa-b
58 * SI -> SI
59 * S -> S
60 * SS -> SSa-c
61 *
62 * Disassembly begins in tbl_xx. The first byte of the instruction is used
63 * as the index. This yields either an instruction or a sub-table.
64 *
65 * If an instruction is encountered, its format field is used to format the
66 * instruction.
67 *
68 * There are two types of sub-tables: extended opcode tables (indicated with
69 * IF_TBL) or a multiple mnemonics tables (indicated with IF_MULTI).
70 *
71 * Extended opcode tables indicade which additional bits of the instruction
72 * should be inspected. These bits are used as an index into the sub table.
73 *
74 * Multiple mnemonic tables are used to print different mnemonics depending
75 * on the architecture. Over the years, certain instructions got a new
76 * preferred mnemonic. For example, 0xa70 is test-under-mask-high (tmh) on
77 * System/390. On z/Architecture systems, the instruction behaves
78 * identically (and the assembler hapilly accepts tmh), but the preferred
79 * mnemonic is tmlh (test-under-mask-low-high) because z/Architecture
80 * extended the general purpose registers from 32 bits to 64 bits. The
81 * current architecture flag (e.g., F_390) is used to index into the
82 * sub-table.
83 *
84 * Regardless of which sub-table is encountered, the selected entry in the
85 * sub-table is interpreted using the same rules as the contents of tbl_xx.
86 *
87 * Finally, we use the extended opcode sub-table mechanism to pretty print
88 * the branching instructions. All branches are conditional based on a
89 * 4-bit mask indicating which value of the condition code will result in a
90 * taken branch. In order to produce a more human friendly output, we use
91 * the 4-bit mask as an extended opcode to break up the branching
92 * instruction into 16 different ones. For example, instead of printing:
93 *
94 * bc 7,0x123(%r1,%r2)
95 *
96 * we print:
97 *
98 * bne 0x123(%r1,%r2)
99 *
100 * Note that we are using designated initializers via the INSTR/TABLE/MULTI
101 * macros and therefore the below tables can be sparse. We rely on unset
102 * entries having zero format fields (aka. IF_INVAL) per C99.
103 */
104
105 /* BEGIN CSTYLED */
106 enum ifmt {
107 /* invalid */
108 IF_INVAL = 0,
109
110 /* indirection */
111 IF_TBL,
112 IF_MULTI,
113
114 /* 2-byte */
115 IF_ZERO, /* 370, 390, z */
116 IF_E, /* 390, z */
117 IF_I, /* 390, z */
118 IF_RR, /* 370, 390, z */
119
120 /* 4-byte */
121 IF_DIAG, /* 370, 390, z */
122 IF_IE, /* z */
169 IF_SSe, /* 390, z */
170 IF_SSf, /* 390, z */
171 IF_SSE, /* 390, z */
172 IF_SSF, /* z */
173 };
174
175 #define IF_NFMTS (IF_SSF + 1)
176
177 #define F_370 0x0001 /* 370 */
178 #define F_390 0x0002 /* 390 */
179 #define F_Z 0x0004 /* z */
180 #define F_SIGNED_IMM 0x0010 /* 370, 390, z */
181 #define F_CTL_REG 0x0020 /* 370, 390, z */
182 #define F_HIDE_MASK 0x0040 /* 370, 390, z */
183 #define F_R1_IS_MASK 0x0080 /* 370, 390, z */
184 /* END CSTYLED */
185
186 struct inst_table {
187 union {
188 struct {
189 const char *it_name;
190 unsigned it_flags;
191 } it_inst;
192 struct {
193 const struct inst_table *it_ptr;
194 uint8_t it_off:4;
195 uint8_t it_shift:4;
196 uint8_t it_mask;
197 } it_table;
198 struct {
199 const struct inst_table *it_ptr;
200 } it_multi;
201 } it_u;
202 enum ifmt it_fmt;
203 };
204
205 #define BITFLD(a, b) DECL_BITFIELD2(b:4, a:4)
206
207 union inst {
208 uint8_t raw[6];
209 struct {
210 uint8_t op;
211 uint8_t par1;
212 uint16_t par2;
213 } diag;
214 struct {
215 uint8_t op;
216 uint8_t i;
217 } i;
218 struct {
219 uint16_t op;
220 uint8_t pad;
221 BITFLD(i1, i2);
222 } ie;
518 uint8_t d2l;
519 } ss_f;
520 struct {
521 uint16_t op;
522 BITFLD(b1, d1h);
523 uint8_t d1l;
524 BITFLD(b2, d2h);
525 uint8_t d2l;
526 } sse;
527 struct {
528 uint8_t op1;
529 BITFLD(r3, op2);
530 BITFLD(b1, d1h);
531 uint8_t d1l;
532 BITFLD(b2, d2h);
533 uint8_t d2l;
534 } ssf;
535 };
536
537 #define INSTR(op, m, fm, fl) [op] = { \
538 .it_u.it_inst = { \
539 .it_name = (m), \
540 .it_flags = (fl), \
541 }, \
542 .it_fmt = (fm), \
543 }
544 #define TABLE(op, tbl, o, s, m) [op] = { \
545 .it_u.it_table = { \
546 .it_ptr = (tbl), \
547 .it_off = (o), \
548 .it_shift = (s), \
549 .it_mask = (m), \
550 }, \
551 .it_fmt = IF_TBL, \
552 }
553 #define MULTI(op, tbl) [op] = { \
554 .it_u.it_multi.it_ptr = (tbl), \
555 .it_fmt = IF_MULTI, \
556 }
557
558 /*
559 * Instruction tables based on:
560 * GA22-7000-4 System/370 Principles of Operation
561 * SA22-7201-08 ESA/390 Principles of Operation
562 * SA22-7832-09 z/Architecture Principles of Operation
563 */
564
565 /* BEGIN CSTYLED */
566 static const struct inst_table tbl_01xx[256] = {
567 INSTR(0x01, "pr", IF_E, F_390 | F_Z),
568 INSTR(0x02, "upt", IF_E, F_390 | F_Z),
569 INSTR(0x04, "ptff", IF_E, F_Z),
570 INSTR(0x07, "sckpf", IF_E, F_390 | F_Z),
571 INSTR(0x0a, "pfpo", IF_E, F_Z),
572 INSTR(0x0b, "tam", IF_E, F_390 | F_Z),
573 INSTR(0x0c, "sam24", IF_E, F_390 | F_Z),
574 INSTR(0x0d, "sam31", IF_E, F_390 | F_Z),
575 INSTR(0x0e, "sam64", IF_E, F_Z),
1778
1779 /* how general purpose regs are printed */
1780 static const char *R[16] = {
1781 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1782 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1783 };
1784
1785 /* how control regs are printed */
1786 static const char *C[16] = {
1787 "%c0", "%c1", "%c2", "%c3", "%c4", "%c5", "%c6", "%c7",
1788 "%c8", "%c9", "%c10", "%c11", "%c12", "%c13", "%c14", "%c15",
1789 };
1790
1791 /* B and X registers are still registers - print them the same way */
1792 #define B R
1793 #define X R
1794
1795 static inline uint32_t
1796 val_8_4_8(uint32_t hi, uint32_t mid, uint32_t lo)
1797 {
1798 ASSERT0(hi & ~0xff);
1799 ASSERT0(mid & ~0xf);
1800 ASSERT0(lo & ~0xff);
1801 return ((hi << 12) | (mid << 8) | lo);
1802 }
1803
1804 static inline uint32_t
1805 val_16_16(uint32_t hi, uint32_t lo)
1806 {
1807 ASSERT0(hi & ~0xffff);
1808 ASSERT0(lo & ~0xffff);
1809 return ((BE_16(hi) << 16) | BE_16(lo));
1810 }
1811
1812 static inline int32_t
1813 sval_16_16(uint32_t hi, uint32_t lo)
1814 {
1815 return (val_16_16(hi, lo));
1816 }
1817
1818 static inline uint32_t
1819 val_8_16(uint32_t hi, uint32_t lo)
1820 {
1821 ASSERT0(hi & ~0xff);
1822 ASSERT0(lo & ~0xffff);
1823 return ((hi << 16) | BE_16(lo));
1824 }
1825
1826 static inline int32_t
1827 sval_8_16(uint32_t hi, uint32_t lo)
1828 {
1829 int32_t tmp = val_8_16(hi, lo);
1830
1831 /* sign extend */
1832 if (tmp & 0x00800000)
1833 return (0xff000000 | tmp);
1834 return (tmp);
1835 }
1836
1837 static inline uint32_t
1838 val_4_8(uint32_t hi, uint32_t lo)
1839 {
1840 ASSERT0(hi & ~0xf);
1841 ASSERT0(lo & ~0xff);
1842 return ((hi << 8) | lo);
1843 }
1844
1845 static inline int32_t
1846 sval_4_8(uint32_t hi, uint32_t lo)
1847 {
1848 uint32_t tmp = val_4_8(hi, lo);
1849
1850 /* sign extend */
1851 if (tmp & 0x800)
1852 return (0xfffff000 | tmp);
1853 return (tmp);
1854 }
1855
1856 /* ARGSUSED */
1857 static void
1858 fmt_zero(uint64_t addr, union inst *inst, char *buf, size_t buflen, int flags)
1859 {
1860 (void) snprintf(buf, buflen, "0x00, 0x00");
1861 }
1862
1863 /* ARGSUSED */
1864 static void
1865 fmt_diag(uint64_t addr, union inst *inst, char *buf, size_t buflen, int flags)
1866 {
1867 (void) snprintf(buf, buflen, "%#x",
1868 val_8_16(inst->diag.par1, inst->diag.par2));
1869 }
1870
2467 [IF_SI] = fmt_si,
2468 [IF_SIL] = fmt_sil,
2469 [IF_SIY] = fmt_siy,
2470 [IF_SMI] = fmt_smi,
2471 [IF_SSa] = fmt_ss_a,
2472 [IF_SSb] = fmt_ss_b,
2473 [IF_SSc] = fmt_ss_c,
2474 [IF_SSd] = fmt_ss_d,
2475 [IF_SSe] = fmt_ss_e,
2476 [IF_SSf] = fmt_ss_f,
2477 [IF_SSE] = fmt_sse,
2478 [IF_SSF] = fmt_ssf,
2479 };
2480
2481 static int
2482 dis_s390(uint64_t addr, union inst *inst, char *buf, size_t buflen, int mach)
2483 {
2484 const struct inst_table *tbl = &tbl_xx[inst->raw[0]];
2485 int tmp;
2486
2487 while (tbl->it_fmt == IF_TBL || tbl->it_fmt == IF_MULTI) {
2488 if (tbl->it_fmt == IF_TBL) {
2489 int idx;
2490
2491 idx = inst->raw[tbl->it_u.it_table.it_off];
2492 idx >>= tbl->it_u.it_table.it_shift;
2493 idx &= tbl->it_u.it_table.it_mask;
2494
2495 tbl = &tbl->it_u.it_table.it_ptr[idx];
2496 } else if (tbl->it_fmt == IF_MULTI) {
2497 tbl = &tbl->it_u.it_multi.it_ptr[mach];
2498 }
2499 }
2500
2501 if (tbl->it_fmt == IF_INVAL)
2502 goto inval;
2503
2504 if ((tbl->it_u.it_inst.it_flags & mach) == 0)
2505 goto inval;
2506
2507 tmp = snprintf(buf, buflen, "%-7s ", tbl->it_u.it_inst.it_name);
2508
2509 fmt_fxns[tbl->it_fmt](addr, inst, buf + tmp, buflen - tmp,
2510 tbl->it_u.it_inst.it_flags);
2511
2512 return (0);
2513
2514 inval:
2515 (void) snprintf(buf, buflen, "??");
2516
2517 /*
2518 * Even if we don't know how to disassemble the instruction, we know
2519 * how long it is, so we "succeed" even when we fail.
2520 */
2521 return (0);
2522 }
2523
2524 static int
2525 dis_s390_supports_flags(int flags)
2526 {
2527 int archflags = flags & DIS_ARCH_MASK;
2528
2529 if (archflags == DIS_S370 || archflags == DIS_S390_31 ||
2530 archflags == DIS_S390_64)
|