^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Disassemble s390 instructions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright IBM Corp. 2007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/kallsyms.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/kprobes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/kdebug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/dis.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <asm/cpcmd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <asm/lowcore.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <asm/debug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* Type of operand */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define OPERAND_GPR 0x1 /* Operand printed as %rx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define OPERAND_FPR 0x2 /* Operand printed as %fx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define OPERAND_AR 0x4 /* Operand printed as %ax */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define OPERAND_CR 0x8 /* Operand printed as %cx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define OPERAND_VR 0x10 /* Operand printed as %vx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define OPERAND_DISP 0x20 /* Operand printed as displacement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define OPERAND_BASE 0x40 /* Operand printed as base register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define OPERAND_INDEX 0x80 /* Operand printed as index register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define OPERAND_PCREL 0x100 /* Operand printed as pc-relative symbol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define OPERAND_SIGNED 0x200 /* Operand printed as signed value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define OPERAND_LENGTH 0x400 /* Operand printed as length (+1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct s390_operand {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) unsigned char bits; /* The number of bits in the operand. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) unsigned char shift; /* The number of bits to shift. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) unsigned short flags; /* One bit syntax flags. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct s390_insn {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) const char name[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) unsigned char zero;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) unsigned int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unsigned char opfrag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) unsigned char format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct s390_opcode_offset {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned char opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned char mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned char byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned short offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) unsigned short count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) UNUSED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) A_8, /* Access reg. starting at position 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) A_12, /* Access reg. starting at position 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) A_24, /* Access reg. starting at position 24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) A_28, /* Access reg. starting at position 28 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) B_16, /* Base register starting at position 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) B_32, /* Base register starting at position 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) C_8, /* Control reg. starting at position 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) C_12, /* Control reg. starting at position 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) D20_20, /* 20 bit displacement starting at 20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) D_20, /* Displacement starting at position 20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) D_36, /* Displacement starting at position 36 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) F_8, /* FPR starting at position 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) F_12, /* FPR starting at position 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) F_16, /* FPR starting at position 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) F_24, /* FPR starting at position 24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) F_28, /* FPR starting at position 28 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) F_32, /* FPR starting at position 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) I8_8, /* 8 bit signed value starting at 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) I8_32, /* 8 bit signed value starting at 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) I16_16, /* 16 bit signed value starting at 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) I16_32, /* 16 bit signed value starting at 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) I32_16, /* 32 bit signed value starting at 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) J12_12, /* 12 bit PC relative offset at 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) J16_16, /* 16 bit PC relative offset at 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) J16_32, /* 16 bit PC relative offset at 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) J24_24, /* 24 bit PC relative offset at 24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) J32_16, /* 32 bit PC relative offset at 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) L4_8, /* 4 bit length starting at position 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) L4_12, /* 4 bit length starting at position 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) L8_8, /* 8 bit length starting at position 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) R_8, /* GPR starting at position 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) R_12, /* GPR starting at position 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) R_16, /* GPR starting at position 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) R_24, /* GPR starting at position 24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) R_28, /* GPR starting at position 28 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) U4_8, /* 4 bit unsigned value starting at 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) U4_12, /* 4 bit unsigned value starting at 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) U4_16, /* 4 bit unsigned value starting at 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) U4_20, /* 4 bit unsigned value starting at 20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) U4_24, /* 4 bit unsigned value starting at 24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) U4_28, /* 4 bit unsigned value starting at 28 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) U4_32, /* 4 bit unsigned value starting at 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) U4_36, /* 4 bit unsigned value starting at 36 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) U8_8, /* 8 bit unsigned value starting at 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) U8_16, /* 8 bit unsigned value starting at 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) U8_24, /* 8 bit unsigned value starting at 24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) U8_28, /* 8 bit unsigned value starting at 28 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) U8_32, /* 8 bit unsigned value starting at 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) U12_16, /* 12 bit unsigned value starting at 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) U16_16, /* 16 bit unsigned value starting at 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) U16_32, /* 16 bit unsigned value starting at 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) U32_16, /* 32 bit unsigned value starting at 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) VX_12, /* Vector index register starting at position 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) V_8, /* Vector reg. starting at position 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) V_12, /* Vector reg. starting at position 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) V_16, /* Vector reg. starting at position 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) V_32, /* Vector reg. starting at position 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) X_12, /* Index register starting at position 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static const struct s390_operand operands[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) [UNUSED] = { 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) [A_8] = { 4, 8, OPERAND_AR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) [A_12] = { 4, 12, OPERAND_AR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) [A_24] = { 4, 24, OPERAND_AR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) [A_28] = { 4, 28, OPERAND_AR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) [B_16] = { 4, 16, OPERAND_BASE | OPERAND_GPR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) [B_32] = { 4, 32, OPERAND_BASE | OPERAND_GPR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) [C_8] = { 4, 8, OPERAND_CR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) [C_12] = { 4, 12, OPERAND_CR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) [D20_20] = { 20, 20, OPERAND_DISP | OPERAND_SIGNED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) [D_20] = { 12, 20, OPERAND_DISP },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) [D_36] = { 12, 36, OPERAND_DISP },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) [F_8] = { 4, 8, OPERAND_FPR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) [F_12] = { 4, 12, OPERAND_FPR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) [F_16] = { 4, 16, OPERAND_FPR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) [F_24] = { 4, 24, OPERAND_FPR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) [F_28] = { 4, 28, OPERAND_FPR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) [F_32] = { 4, 32, OPERAND_FPR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) [I8_8] = { 8, 8, OPERAND_SIGNED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) [I8_32] = { 8, 32, OPERAND_SIGNED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) [I16_16] = { 16, 16, OPERAND_SIGNED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) [I16_32] = { 16, 32, OPERAND_SIGNED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) [I32_16] = { 32, 16, OPERAND_SIGNED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) [J12_12] = { 12, 12, OPERAND_PCREL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) [J16_16] = { 16, 16, OPERAND_PCREL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) [J16_32] = { 16, 32, OPERAND_PCREL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) [J24_24] = { 24, 24, OPERAND_PCREL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) [J32_16] = { 32, 16, OPERAND_PCREL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) [L4_8] = { 4, 8, OPERAND_LENGTH },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) [L4_12] = { 4, 12, OPERAND_LENGTH },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) [L8_8] = { 8, 8, OPERAND_LENGTH },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) [R_8] = { 4, 8, OPERAND_GPR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) [R_12] = { 4, 12, OPERAND_GPR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) [R_16] = { 4, 16, OPERAND_GPR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) [R_24] = { 4, 24, OPERAND_GPR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) [R_28] = { 4, 28, OPERAND_GPR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) [U4_8] = { 4, 8, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) [U4_12] = { 4, 12, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) [U4_16] = { 4, 16, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) [U4_20] = { 4, 20, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) [U4_24] = { 4, 24, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) [U4_28] = { 4, 28, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) [U4_32] = { 4, 32, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) [U4_36] = { 4, 36, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) [U8_8] = { 8, 8, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) [U8_16] = { 8, 16, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) [U8_24] = { 8, 24, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) [U8_28] = { 8, 28, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) [U8_32] = { 8, 32, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) [U12_16] = { 12, 16, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) [U16_16] = { 16, 16, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) [U16_32] = { 16, 32, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) [U32_16] = { 32, 16, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) [VX_12] = { 4, 12, OPERAND_INDEX | OPERAND_VR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) [V_8] = { 4, 8, OPERAND_VR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) [V_12] = { 4, 12, OPERAND_VR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) [V_16] = { 4, 16, OPERAND_VR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) [V_32] = { 4, 32, OPERAND_VR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) [X_12] = { 4, 12, OPERAND_INDEX | OPERAND_GPR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static const unsigned char formats[][6] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) [INSTR_E] = { 0, 0, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) [INSTR_IE_UU] = { U4_24, U4_28, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) [INSTR_MII_UPP] = { U4_8, J12_12, J24_24 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) [INSTR_RIE_R0IU] = { R_8, I16_16, U4_32, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) [INSTR_RIE_R0UU] = { R_8, U16_16, U4_32, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) [INSTR_RIE_RRI0] = { R_8, R_12, I16_16, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) [INSTR_RIE_RRP] = { R_8, R_12, J16_16, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) [INSTR_RIE_RRPU] = { R_8, R_12, U4_32, J16_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) [INSTR_RIE_RRUUU] = { R_8, R_12, U8_16, U8_24, U8_32, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) [INSTR_RIE_RUI0] = { R_8, I16_16, U4_12, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) [INSTR_RIE_RUPI] = { R_8, I8_32, U4_12, J16_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) [INSTR_RIE_RUPU] = { R_8, U8_32, U4_12, J16_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) [INSTR_RIL_RI] = { R_8, I32_16, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) [INSTR_RIL_RP] = { R_8, J32_16, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) [INSTR_RIL_RU] = { R_8, U32_16, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) [INSTR_RIL_UP] = { U4_8, J32_16, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) [INSTR_RIS_RURDI] = { R_8, I8_32, U4_12, D_20, B_16, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) [INSTR_RIS_RURDU] = { R_8, U8_32, U4_12, D_20, B_16, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) [INSTR_RI_RI] = { R_8, I16_16, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) [INSTR_RI_RP] = { R_8, J16_16, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) [INSTR_RI_RU] = { R_8, U16_16, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) [INSTR_RI_UP] = { U4_8, J16_16, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) [INSTR_RRE_00] = { 0, 0, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) [INSTR_RRE_AA] = { A_24, A_28, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) [INSTR_RRE_AR] = { A_24, R_28, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) [INSTR_RRE_F0] = { F_24, 0, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) [INSTR_RRE_FF] = { F_24, F_28, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) [INSTR_RRE_FR] = { F_24, R_28, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) [INSTR_RRE_R0] = { R_24, 0, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) [INSTR_RRE_RA] = { R_24, A_28, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) [INSTR_RRE_RF] = { R_24, F_28, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) [INSTR_RRE_RR] = { R_24, R_28, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) [INSTR_RRF_0UFF] = { F_24, F_28, U4_20, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) [INSTR_RRF_0URF] = { R_24, F_28, U4_20, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) [INSTR_RRF_F0FF] = { F_16, F_24, F_28, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) [INSTR_RRF_F0FF2] = { F_24, F_16, F_28, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) [INSTR_RRF_F0FR] = { F_24, F_16, R_28, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) [INSTR_RRF_FFRU] = { F_24, F_16, R_28, U4_20, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) [INSTR_RRF_FUFF] = { F_24, F_16, F_28, U4_20, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) [INSTR_RRF_FUFF2] = { F_24, F_28, F_16, U4_20, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) [INSTR_RRF_R0RR] = { R_24, R_16, R_28, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) [INSTR_RRF_R0RR2] = { R_24, R_28, R_16, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) [INSTR_RRF_RURR] = { R_24, R_28, R_16, U4_20, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) [INSTR_RRF_RURR2] = { R_24, R_16, R_28, U4_20, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) [INSTR_RRF_U0FF] = { F_24, U4_16, F_28, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) [INSTR_RRF_U0RF] = { R_24, U4_16, F_28, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) [INSTR_RRF_U0RR] = { R_24, R_28, U4_16, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) [INSTR_RRF_URR] = { R_24, R_28, U8_16, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) [INSTR_RRF_UUFF] = { F_24, U4_16, F_28, U4_20, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) [INSTR_RRF_UUFR] = { F_24, U4_16, R_28, U4_20, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) [INSTR_RRF_UURF] = { R_24, U4_16, F_28, U4_20, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) [INSTR_RRS_RRRDU] = { R_8, R_12, U4_32, D_20, B_16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) [INSTR_RR_FF] = { F_8, F_12, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) [INSTR_RR_R0] = { R_8, 0, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) [INSTR_RR_RR] = { R_8, R_12, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) [INSTR_RR_U0] = { U8_8, 0, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) [INSTR_RR_UR] = { U4_8, R_12, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) [INSTR_RSI_RRP] = { R_8, R_12, J16_16, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) [INSTR_RSL_LRDFU] = { F_32, D_20, L8_8, B_16, U4_36, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) [INSTR_RSL_R0RD] = { D_20, L4_8, B_16, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) [INSTR_RSY_AARD] = { A_8, A_12, D20_20, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) [INSTR_RSY_CCRD] = { C_8, C_12, D20_20, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) [INSTR_RSY_RDRU] = { R_8, D20_20, B_16, U4_12, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) [INSTR_RSY_RRRD] = { R_8, R_12, D20_20, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) [INSTR_RSY_RURD] = { R_8, U4_12, D20_20, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) [INSTR_RSY_RURD2] = { R_8, D20_20, B_16, U4_12, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) [INSTR_RS_AARD] = { A_8, A_12, D_20, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) [INSTR_RS_CCRD] = { C_8, C_12, D_20, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) [INSTR_RS_R0RD] = { R_8, D_20, B_16, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) [INSTR_RS_RRRD] = { R_8, R_12, D_20, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) [INSTR_RS_RURD] = { R_8, U4_12, D_20, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) [INSTR_RXE_FRRD] = { F_8, D_20, X_12, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) [INSTR_RXE_RRRDU] = { R_8, D_20, X_12, B_16, U4_32, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) [INSTR_RXF_FRRDF] = { F_32, F_8, D_20, X_12, B_16, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) [INSTR_RXY_FRRD] = { F_8, D20_20, X_12, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) [INSTR_RXY_RRRD] = { R_8, D20_20, X_12, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) [INSTR_RXY_URRD] = { U4_8, D20_20, X_12, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) [INSTR_RX_FRRD] = { F_8, D_20, X_12, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) [INSTR_RX_RRRD] = { R_8, D_20, X_12, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) [INSTR_RX_URRD] = { U4_8, D_20, X_12, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) [INSTR_SIL_RDI] = { D_20, B_16, I16_32, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) [INSTR_SIL_RDU] = { D_20, B_16, U16_32, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) [INSTR_SIY_IRD] = { D20_20, B_16, I8_8, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) [INSTR_SIY_URD] = { D20_20, B_16, U8_8, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) [INSTR_SI_RD] = { D_20, B_16, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) [INSTR_SI_URD] = { D_20, B_16, U8_8, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) [INSTR_SMI_U0RDP] = { U4_8, J16_32, D_20, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) [INSTR_SSE_RDRD] = { D_20, B_16, D_36, B_32, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) [INSTR_SSF_RRDRD] = { D_20, B_16, D_36, B_32, R_8, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) [INSTR_SSF_RRDRD2] = { R_8, D_20, B_16, D_36, B_32, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) [INSTR_SS_L0RDRD] = { D_20, L8_8, B_16, D_36, B_32, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) [INSTR_SS_L2RDRD] = { D_20, B_16, D_36, L8_8, B_32, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) [INSTR_SS_LIRDRD] = { D_20, L4_8, B_16, D_36, B_32, U4_12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) [INSTR_SS_LLRDRD] = { D_20, L4_8, B_16, D_36, L4_12, B_32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) [INSTR_SS_RRRDRD] = { D_20, R_8, B_16, D_36, B_32, R_12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) [INSTR_SS_RRRDRD2] = { R_8, D_20, B_16, R_12, D_36, B_32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) [INSTR_SS_RRRDRD3] = { R_8, R_12, D_20, B_16, D_36, B_32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) [INSTR_S_00] = { 0, 0, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) [INSTR_S_RD] = { D_20, B_16, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) [INSTR_VRI_V0IU] = { V_8, I16_16, U4_32, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) [INSTR_VRI_V0U] = { V_8, U16_16, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) [INSTR_VRI_V0UU2] = { V_8, U16_16, U4_32, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) [INSTR_VRI_V0UUU] = { V_8, U8_16, U8_24, U4_32, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) [INSTR_VRI_VR0UU] = { V_8, R_12, U8_28, U4_24, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) [INSTR_VRI_VVUU] = { V_8, V_12, U16_16, U4_32, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) [INSTR_VRI_VVUUU] = { V_8, V_12, U12_16, U4_32, U4_28, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) [INSTR_VRI_VVUUU2] = { V_8, V_12, U8_28, U8_16, U4_24, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) [INSTR_VRI_VVV0U] = { V_8, V_12, V_16, U8_24, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) [INSTR_VRI_VVV0UU] = { V_8, V_12, V_16, U8_24, U4_32, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) [INSTR_VRI_VVV0UU2] = { V_8, V_12, V_16, U8_28, U4_24, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) [INSTR_VRR_0V] = { V_12, 0, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) [INSTR_VRR_0VV0U] = { V_12, V_16, U4_24, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) [INSTR_VRR_RV0UU] = { R_8, V_12, U4_24, U4_28, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) [INSTR_VRR_VRR] = { V_8, R_12, R_16, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) [INSTR_VRR_VV] = { V_8, V_12, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) [INSTR_VRR_VV0U] = { V_8, V_12, U4_32, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) [INSTR_VRR_VV0U0U] = { V_8, V_12, U4_32, U4_24, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) [INSTR_VRR_VV0UU2] = { V_8, V_12, U4_32, U4_28, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) [INSTR_VRR_VV0UUU] = { V_8, V_12, U4_32, U4_28, U4_24, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) [INSTR_VRR_VVV] = { V_8, V_12, V_16, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) [INSTR_VRR_VVV0U] = { V_8, V_12, V_16, U4_32, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) [INSTR_VRR_VVV0U0U] = { V_8, V_12, V_16, U4_32, U4_24, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) [INSTR_VRR_VVV0UU] = { V_8, V_12, V_16, U4_32, U4_28, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) [INSTR_VRR_VVV0UUU] = { V_8, V_12, V_16, U4_32, U4_28, U4_24 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) [INSTR_VRR_VVV0V] = { V_8, V_12, V_16, V_32, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) [INSTR_VRR_VVVU0UV] = { V_8, V_12, V_16, V_32, U4_28, U4_20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) [INSTR_VRR_VVVU0V] = { V_8, V_12, V_16, V_32, U4_20, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) [INSTR_VRR_VVVUU0V] = { V_8, V_12, V_16, V_32, U4_20, U4_24 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) [INSTR_VRS_RRDV] = { V_32, R_12, D_20, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) [INSTR_VRS_RVRDU] = { R_8, V_12, D_20, B_16, U4_32, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) [INSTR_VRS_VRRD] = { V_8, R_12, D_20, B_16, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) [INSTR_VRS_VRRDU] = { V_8, R_12, D_20, B_16, U4_32, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) [INSTR_VRS_VVRDU] = { V_8, V_12, D_20, B_16, U4_32, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) [INSTR_VRV_VVXRDU] = { V_8, D_20, VX_12, B_16, U4_32, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) [INSTR_VRX_VRRDU] = { V_8, D_20, X_12, B_16, U4_32, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) [INSTR_VRX_VV] = { V_8, V_12, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) [INSTR_VSI_URDV] = { V_32, D_20, B_16, U8_8, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static char long_insn_name[][7] = LONG_INSN_INITIALIZER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static struct s390_insn opcode[] = OPCODE_TABLE_INITIALIZER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static struct s390_opcode_offset opcode_offset[] = OPCODE_OFFSET_INITIALIZER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /* Extracts an operand value from an instruction. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static unsigned int extract_operand(unsigned char *code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) const struct s390_operand *operand)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) unsigned char *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) int bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /* Extract fragments of the operand byte for byte. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) cp = code + operand->shift / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) bits = (operand->shift & 7) + operand->bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) val <<= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) val |= (unsigned int) *cp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) bits -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) } while (bits > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) val >>= -bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) val &= ((1U << (operand->bits - 1)) << 1) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* Check for special long displacement case. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (operand->bits == 20 && operand->shift == 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) val = (val & 0xff) << 12 | (val & 0xfff00) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /* Check for register extensions bits for vector registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (operand->flags & OPERAND_VR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (operand->shift == 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) val |= (code[4] & 8) << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) else if (operand->shift == 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) val |= (code[4] & 4) << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) else if (operand->shift == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) val |= (code[4] & 2) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) else if (operand->shift == 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) val |= (code[4] & 1) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /* Sign extend value if the operand is signed or pc relative. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if ((operand->flags & (OPERAND_SIGNED | OPERAND_PCREL)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) (val & (1U << (operand->bits - 1))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) val |= (-1U << (operand->bits - 1)) << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* Double value if the operand is pc relative. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (operand->flags & OPERAND_PCREL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) val <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /* Length x in an instructions has real length x + 1. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (operand->flags & OPERAND_LENGTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) val++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct s390_insn *find_insn(unsigned char *code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) struct s390_opcode_offset *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) struct s390_insn *insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) unsigned char opfrag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /* Search the opcode offset table to find an entry which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * matches the beginning of the opcode. If there is no match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * the last entry will be used, which is the default entry for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * unknown instructions as well as 1-byte opcode instructions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) for (i = 0; i < ARRAY_SIZE(opcode_offset); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) entry = &opcode_offset[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (entry->opcode == code[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) opfrag = *(code + entry->byte) & entry->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) insn = &opcode[entry->offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) for (i = 0; i < entry->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (insn->opfrag == opfrag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) insn++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static int print_insn(char *buffer, unsigned char *code, unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) struct s390_insn *insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) const unsigned char *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) const struct s390_operand *operand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) unsigned int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) char separator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) char *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ptr = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) insn = find_insn(code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (insn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (insn->zero == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ptr += sprintf(ptr, "%.7s\t",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) long_insn_name[insn->offset]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) ptr += sprintf(ptr, "%.5s\t", insn->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /* Extract the operands. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) separator = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) for (ops = formats[insn->format], i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) *ops != 0 && i < 6; ops++, i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) operand = operands + *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) value = extract_operand(code, operand);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if ((operand->flags & OPERAND_INDEX) && value == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if ((operand->flags & OPERAND_BASE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) value == 0 && separator == '(') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) separator = ',';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (separator)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ptr += sprintf(ptr, "%c", separator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (operand->flags & OPERAND_GPR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) ptr += sprintf(ptr, "%%r%i", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) else if (operand->flags & OPERAND_FPR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ptr += sprintf(ptr, "%%f%i", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) else if (operand->flags & OPERAND_AR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) ptr += sprintf(ptr, "%%a%i", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) else if (operand->flags & OPERAND_CR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ptr += sprintf(ptr, "%%c%i", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) else if (operand->flags & OPERAND_VR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ptr += sprintf(ptr, "%%v%i", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) else if (operand->flags & OPERAND_PCREL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) void *pcrel = (void *)((int)value + addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ptr += sprintf(ptr, "%px", pcrel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) } else if (operand->flags & OPERAND_SIGNED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) ptr += sprintf(ptr, "%i", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) ptr += sprintf(ptr, "%u", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (operand->flags & OPERAND_DISP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) separator = '(';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) else if (operand->flags & OPERAND_BASE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ptr += sprintf(ptr, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) separator = ',';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) separator = ',';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) ptr += sprintf(ptr, "unknown");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return (int) (ptr - buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static int copy_from_regs(struct pt_regs *regs, void *dst, void *src, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (user_mode(regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (copy_from_user(dst, (char __user *)src, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (copy_from_kernel_nofault(dst, src, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) void show_code(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) char *mode = user_mode(regs) ? "User" : "Krnl";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) unsigned char code[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) char buffer[128], *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) int start, end, opsize, hops, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) /* Get a snapshot of the 64 bytes surrounding the fault address. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) for (start = 32; start && regs->psw.addr >= 34 - start; start -= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) addr = regs->psw.addr - 34 + start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (copy_from_regs(regs, code + start - 2, (void *)addr, 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) for (end = 32; end < 64; end += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) addr = regs->psw.addr + end - 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (copy_from_regs(regs, code + end, (void *)addr, 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /* Code snapshot useable ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if ((regs->psw.addr & 1) || start >= end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) printk("%s Code: Bad PSW.\n", mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /* Find a starting point for the disassembly. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) while (start < 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) for (i = 0, hops = 0; start + i < 32 && hops < 3; hops++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (!find_insn(code + start + i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) i += insn_length(code[start + i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (start + i == 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /* Looks good, sequence ends at PSW. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) start += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) /* Decode the instructions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ptr = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ptr += sprintf(ptr, "%s Code:", mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) hops = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) while (start < end && hops < 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) opsize = insn_length(code[start]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (start + opsize == 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) *ptr++ = '#';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) else if (start == 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) *ptr++ = '>';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) *ptr++ = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) addr = regs->psw.addr + start - 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) ptr += sprintf(ptr, "%px: ", (void *)addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (start + opsize >= end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) for (i = 0; i < opsize; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ptr += sprintf(ptr, "%02x", code[start + i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) *ptr++ = '\t';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (i < 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) *ptr++ = '\t';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) ptr += print_insn(ptr, code + start, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) start += opsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) pr_cont("%s", buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) ptr = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) ptr += sprintf(ptr, "\n ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) hops++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) pr_cont("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) void print_fn_code(unsigned char *code, unsigned long len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) char buffer[128], *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) int opsize, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) while (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) ptr = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) opsize = insn_length(*code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (opsize > len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) ptr += sprintf(ptr, "%px: ", code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) for (i = 0; i < opsize; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) ptr += sprintf(ptr, "%02x", code[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) *ptr++ = '\t';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (i < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) *ptr++ = '\t';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) ptr += print_insn(ptr, code, (unsigned long) code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) *ptr++ = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) *ptr++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) printk("%s", buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) code += opsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) len -= opsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }