Print this page
libdisasm: print push/pop register list in a more human readable form
Instead of just blindly dumping a list of registers, we detect ranges and
print a list of ranges.
libdisasm: print r9 as "fp"
libdisasm: use "push" and "pop" when appropriate
While there is nothing technically wrong with printing the actual
instruction, it is easier on the eyes to just use these common aliases.
libdisasm: remove shouting
There's no need to print everything upper case.

*** 23,32 **** --- 23,33 ---- #include <stdio.h> #include <sys/byteorder.h> #include "libdisasm_impl.h" + extern size_t strlen(const char *); extern size_t strlcat(char *, const char *, size_t); /* * Condition code mask and shift, aka bits 28-31. */
*** 391,414 **** * and treat it as the empty string. The condition code 0b1111 takes us to a * separate series of encoded instructions and therefore we go elsewhere with * them. */ static const char *arm_cond_names[] = { ! "EQ", /* Equal */ ! "NE", /* Not Equal */ ! "CS/HS", /* Carry set/unsigned higher or same */ ! "CC/LO", /* Carry clear/unsigned lower */ ! "MI", /* Minus/negative */ ! "PL", /* Plus/positive or zero */ ! "VS", /* Overflow */ ! "VC", /* No overflow */ ! "HI", /* Unsigned higher */ ! "LS", /* Unsigned lower or same */ ! "GE", /* Signed greater than or equal */ ! "LT", /* Signed less than */ ! "GT", /* Signed greater than */ ! "LE", /* Signed less than or equal */ "", /* AL - Always (unconditional) */ NULL /* Not a condition code */ }; typedef enum arm_cond_code { --- 392,415 ---- * and treat it as the empty string. The condition code 0b1111 takes us to a * separate series of encoded instructions and therefore we go elsewhere with * them. */ static const char *arm_cond_names[] = { ! "eq", /* Equal */ ! "ne", /* Not Equal */ ! "cs/hs", /* Carry set/unsigned higher or same */ ! "cc/lo", /* Carry clear/unsigned lower */ ! "mi", /* Minus/negative */ ! "pl", /* Plus/positive or zero */ ! "vs", /* Overflow */ ! "vc", /* No overflow */ ! "hi", /* Unsigned higher */ ! "ls", /* Unsigned lower or same */ ! "ge", /* Signed greater than or equal */ ! "lt", /* Signed less than */ ! "gt", /* Signed greater than */ ! "le", /* Signed less than or equal */ "", /* AL - Always (unconditional) */ NULL /* Not a condition code */ }; typedef enum arm_cond_code {
*** 433,458 **** /* * Registers are encoded surprisingly sanely. It's a 4-bit value that indicates * which register in question we're working with. */ static const char *arm_reg_names[] = { ! "R0", ! "R1", ! "R2", ! "R3", ! "R4", ! "R5", ! "R6", ! "R7", ! "R8", ! "R9", ! "R10", ! "R11", ! "IP", /* Alt for R12 */ ! "SP", /* Alt for R13 */ ! "LR", /* Alt for R14 */ ! "PC" /* Alt for R15 */ }; typedef enum arm_reg { ARM_REG_R0, ARM_REG_R1, --- 434,459 ---- /* * Registers are encoded surprisingly sanely. It's a 4-bit value that indicates * which register in question we're working with. */ static const char *arm_reg_names[] = { ! "r0", ! "r1", ! "r2", ! "r3", ! "r4", ! "r5", ! "r6", ! "r7", ! "r8", ! "fp", /* Alt for r9 */ ! "r10", ! "r11", ! "ip", /* Alt for r12 */ ! "sp", /* Alt for r13 */ ! "lr", /* Alt for r14 */ ! "pc" /* Alt for r15 */ }; typedef enum arm_reg { ARM_REG_R0, ARM_REG_R1,
*** 497,522 **** /* * These are the opcodes for the instructions which are considered data * processing instructions. */ static const char *arm_dpi_opnames[] = { ! "AND", /* Logical AND */ ! "EOR", /* Logical Exclusive OR */ ! "SUB", /* Subtract */ ! "RSB", /* Reverse Subtract */ ! "ADD", /* Add */ ! "ADC", /* Add with Carry */ ! "SBC", /* Subtract with Carry */ ! "RSC", /* Reverse Subtract with Carry */ ! "TST", /* Test */ ! "TEQ", /* Test Equivalence */ ! "CMP", /* Compare */ ! "CMN", /* Compare negated */ ! "ORR", /* Logical (inclusive) OR */ ! "MOV", /* Move */ ! "BIC", /* Bit clear */ ! "MVN" /* Move not */ }; typedef enum arm_dpi_opcode { DPI_OP_AND, /* Logical AND */ DPI_OP_EOR, /* Logical Exclusive OR */ --- 498,523 ---- /* * These are the opcodes for the instructions which are considered data * processing instructions. */ static const char *arm_dpi_opnames[] = { ! "and", /* Logical AND */ ! "eor", /* Logical Exclusive OR */ ! "sub", /* Subtract */ ! "rsb", /* Reverse Subtract */ ! "add", /* Add */ ! "adc", /* Add with Carry */ ! "sbc", /* Subtract with Carry */ ! "rsc", /* Reverse Subtract with Carry */ ! "tst", /* Test */ ! "teq", /* Test Equivalence */ ! "cmp", /* Compare */ ! "cmn", /* Compare negated */ ! "orr", /* Logical (inclusive) OR */ ! "mov", /* Move */ ! "bic", /* Bit clear */ ! "mvn" /* Move not */ }; typedef enum arm_dpi_opcode { DPI_OP_AND, /* Logical AND */ DPI_OP_EOR, /* Logical Exclusive OR */
*** 535,557 **** DPI_OP_BIC, /* Bit clear */ DPI_OP_MVN /* Move not */ } arm_dpi_opcode_t; const char *arm_dpi_shifts[] = { ! "LSL", /* Logical shift left */ ! "LSR", /* Logical shift right */ ! "ASR", /* Arithmetic shift right */ ! "ROR", /* Rotate right */ ! "RRX" /* Rotate right with extend. This is a special case of ROR */ }; typedef enum arm_dpi_shift_code { DPI_S_LSL, /* Logical shift left */ DPI_S_LSR, /* Logical shift right */ DPI_S_ASR, /* Arithmetic shift right */ DPI_S_ROR, /* Rotate right */ ! DPI_S_RRX, /* Rotate right with extend. Special case of ROR */ DPI_S_NONE /* No shift code */ } arm_dpi_shift_code_t; #define ARM_DPI_SHIFTER_IMM32 0x00 #define ARM_DPI_SHIFTER_SIMM 0x01 --- 536,558 ---- DPI_OP_BIC, /* Bit clear */ DPI_OP_MVN /* Move not */ } arm_dpi_opcode_t; const char *arm_dpi_shifts[] = { ! "lsl", /* Logical shift left */ ! "lsr", /* Logical shift right */ ! "asr", /* Arithmetic shift right */ ! "ror", /* Rotate right */ ! "rrx" /* Rotate right with extend. This is a special case of ror */ }; typedef enum arm_dpi_shift_code { DPI_S_LSL, /* Logical shift left */ DPI_S_LSR, /* Logical shift right */ DPI_S_ASR, /* Arithmetic shift right */ DPI_S_ROR, /* Rotate right */ ! DPI_S_RRX, /* Rotate right with extend. Special case of ror */ DPI_S_NONE /* No shift code */ } arm_dpi_shift_code_t; #define ARM_DPI_SHIFTER_IMM32 0x00 #define ARM_DPI_SHIFTER_SIMM 0x01
*** 592,605 **** * This table contains the names of the load store multiple addressing modes. * The P and U bits are supposed to be combined to index into this. You should * do this by doing P << 1 | U. */ static const char *arm_lsm_mode_names[] = { ! "DA", ! "IA", ! "DB", ! "IB" }; /* * The MSR field has a four bit field mask. Each bit correspons to a letter. * From high to low, f, s, x, c. At least one must be specified, hence 0 is --- 593,606 ---- * This table contains the names of the load store multiple addressing modes. * The P and U bits are supposed to be combined to index into this. You should * do this by doing P << 1 | U. */ static const char *arm_lsm_mode_names[] = { ! "da", ! "ia", ! "db", ! "ib" }; /* * The MSR field has a four bit field mask. Each bit correspons to a letter. * From high to low, f, s, x, c. At least one must be specified, hence 0 is
*** 627,669 **** /* * Names for specific saturating add and subtraction instructions from the * extended control and dsp instructino section. */ static const char *arm_cdsp_sat_opnames[] = { ! "ADD", ! "SUB", ! "DADD", ! "DSUB" }; static const char *arm_padd_p_names[] = { NULL, /* 000 */ ! "S", /* 001 */ ! "Q", /* 010 */ ! "SH", /* 011 */ NULL, /* 100 */ ! "U", /* 101 */ ! "UQ", /* 110 */ ! "UH", /* 111 */ }; static const char *arm_padd_i_names[] = { ! "ADD16", /* 000 */ ! "ADDSUBX", /* 001 */ ! "SUBADDX", /* 010 */ ! "SUB16", /* 011 */ ! "ADD8", /* 100 */ NULL, /* 101 */ NULL, /* 110 */ ! "SUB8", /* 111 */ }; static const char *arm_extend_rot_names[] = { "", /* 0b00, ROR #0 */ ! ", ROR #8", /* 0b01 */ ! ", ROR #16", /* 0b10 */ ! ", ROR #24" /* 0b11 */ }; /* * There are sixteen data processing instructions (dpi). They come in a few * different forms which are based on whether immediate values are used and --- 628,670 ---- /* * Names for specific saturating add and subtraction instructions from the * extended control and dsp instructino section. */ static const char *arm_cdsp_sat_opnames[] = { ! "add", ! "sub", ! "dadd", ! "dsub" }; static const char *arm_padd_p_names[] = { NULL, /* 000 */ ! "s", /* 001 */ ! "q", /* 010 */ ! "sh", /* 011 */ NULL, /* 100 */ ! "u", /* 101 */ ! "uq", /* 110 */ ! "uh", /* 111 */ }; static const char *arm_padd_i_names[] = { ! "add16", /* 000 */ ! "addsubx", /* 001 */ ! "subaddx", /* 010 */ ! "sub16", /* 011 */ ! "add8", /* 100 */ NULL, /* 101 */ NULL, /* 110 */ ! "sub8", /* 111 */ }; static const char *arm_extend_rot_names[] = { "", /* 0b00, ROR #0 */ ! ", ror #8", /* 0b01 */ ! ", ror #16", /* 0b10 */ ! ", ror #24" /* 0b11 */ }; /* * There are sixteen data processing instructions (dpi). They come in a few * different forms which are based on whether immediate values are used and
*** 776,786 **** case DPI_OP_MOV: case DPI_OP_MVN: len = snprintf(buf, buflen, "%s%s%s %s", arm_dpi_opnames[dpi_inst.dpii_op], arm_cond_names[dpi_inst.dpii_cond], ! dpi_inst.dpii_sbit != 0 ? "S" : "", arm_reg_names[dpi_inst.dpii_rd]); break; case DPI_OP_CMP: case DPI_OP_CMN: case DPI_OP_TST: --- 777,787 ---- case DPI_OP_MOV: case DPI_OP_MVN: len = snprintf(buf, buflen, "%s%s%s %s", arm_dpi_opnames[dpi_inst.dpii_op], arm_cond_names[dpi_inst.dpii_cond], ! dpi_inst.dpii_sbit != 0 ? "s" : "", arm_reg_names[dpi_inst.dpii_rd]); break; case DPI_OP_CMP: case DPI_OP_CMN: case DPI_OP_TST:
*** 792,802 **** break; default: len = snprintf(buf, buflen, "%s%s%s %s, %s", arm_dpi_opnames[dpi_inst.dpii_op], arm_cond_names[dpi_inst.dpii_cond], ! dpi_inst.dpii_sbit != 0 ? "S" : "", arm_reg_names[dpi_inst.dpii_rd], arm_reg_names[dpi_inst.dpii_rn]); break; } --- 793,803 ---- break; default: len = snprintf(buf, buflen, "%s%s%s %s, %s", arm_dpi_opnames[dpi_inst.dpii_op], arm_cond_names[dpi_inst.dpii_cond], ! dpi_inst.dpii_sbit != 0 ? "s" : "", arm_reg_names[dpi_inst.dpii_rd], arm_reg_names[dpi_inst.dpii_rn]); break; }
*** 828,838 **** len = snprintf(buf, buflen, ", %s", arm_reg_names[dpi_inst.dpii_un.dpii_si.dpiss_targ]); break; } if (dpi_inst.dpii_un.dpii_si.dpiss_code == DPI_S_RRX) { ! len = snprintf(buf, buflen, ", %s RRX", arm_reg_names[dpi_inst.dpii_un.dpii_si.dpiss_targ]); break; } len = snprintf(buf, buflen, ", %s, %s #%d", arm_reg_names[dpi_inst.dpii_un.dpii_si.dpiss_targ], --- 829,839 ---- len = snprintf(buf, buflen, ", %s", arm_reg_names[dpi_inst.dpii_un.dpii_si.dpiss_targ]); break; } if (dpi_inst.dpii_un.dpii_si.dpiss_code == DPI_S_RRX) { ! len = snprintf(buf, buflen, ", %s rrx", arm_reg_names[dpi_inst.dpii_un.dpii_si.dpiss_targ]); break; } len = snprintf(buf, buflen, ", %s, %s #%d", arm_reg_names[dpi_inst.dpii_un.dpii_si.dpiss_targ],
*** 898,910 **** wbit = in & ARM_LS_WBIT_MASK; lbit = in & ARM_LS_LBIT_MASK; rd = (in & ARM_LS_RD_MASK) >> ARM_LS_RD_SHIFT; rn = (in & ARM_LS_RN_MASK) >> ARM_LS_RN_SHIFT; ! len = snprintf(buf, buflen, "%s%s%s%s %s, ", lbit != 0 ? "LDR" : "STR", ! arm_cond_names[cc], bbit != 0 ? "B" : "", ! (pbit == 0 && wbit != 0) ? "T" : "", arm_reg_names[rd]); if (len >= buflen) return (-1); /* Figure out the specifics of the encoding for the rest */ --- 899,911 ---- wbit = in & ARM_LS_WBIT_MASK; lbit = in & ARM_LS_LBIT_MASK; rd = (in & ARM_LS_RD_MASK) >> ARM_LS_RD_SHIFT; rn = (in & ARM_LS_RN_MASK) >> ARM_LS_RN_SHIFT; ! len = snprintf(buf, buflen, "%s%s%s%s %s, ", lbit != 0 ? "ldr" : "str", ! arm_cond_names[cc], bbit != 0 ? "b" : "", ! (pbit == 0 && wbit != 0) ? "t" : "", arm_reg_names[rd]); if (len >= buflen) return (-1); /* Figure out the specifics of the encoding for the rest */
*** 986,995 **** --- 987,1056 ---- } return (len < buflen ? 0 : -1); } + static void + print_range(char **bufp, size_t *buflenp, uint16_t regs, uint16_t precede) + { + char *buf = *bufp; + size_t buflen = *buflenp; + boolean_t cont = B_FALSE; + int minreg = -1; + int i; + + *buf = '\0'; + + if (precede && regs) + strlcat(buf, ", ", buflen); + + for (i = 0; i < 16; i++) { + boolean_t present = (regs & (1 << i)) != 0; + boolean_t lastreg = (regs & (2 << i)) == 0; + + if (!present) + continue; + + if (minreg == -1) { + if (cont) + strlcat(buf, ", ", buflen); + + strlcat(buf, arm_reg_names[i], buflen); + + if (!lastreg) + minreg = i; + } else { + if (lastreg) { + strlcat(buf, "-", buflen); + strlcat(buf, arm_reg_names[i], buflen); + minreg = -1; + } + } + + cont = B_TRUE; + } + + *bufp += strlen(buf); + *buflenp -= strlen(buf); + } + + static size_t + print_reg_list(char *buf, size_t buflen, uint16_t regs) + { + char *save = buf; + + print_range(&buf, &buflen, regs & 0x01ff, 0); + print_range(&buf, &buflen, regs & 0x0200, regs & 0x01ff); /* fp */ + print_range(&buf, &buflen, regs & 0x0c00, regs & 0x03ff); + print_range(&buf, &buflen, regs & 0x1000, regs & 0x0fff); /* ip */ + print_range(&buf, &buflen, regs & 0x2000, regs & 0x1fff); /* sp */ + print_range(&buf, &buflen, regs & 0x4000, regs & 0x3fff); /* lr */ + print_range(&buf, &buflen, regs & 0x8000, regs & 0x7fff); /* pc */ + + return (strlen(save)); + } + /* * This handles load and store multiple instructions. The general format is as * follows: * * 31 - 28|27 26 25|24|23|22|21|20|19-16|15-0
*** 1035,1045 **** * routine. */ static int arm_dis_ldstr_multi(uint32_t in, char *buf, size_t buflen) { ! int sbit, wbit, lbit, ii, cont; uint16_t regs, addr_mode; arm_reg_t rn; arm_cond_code_t cc; size_t len; --- 1096,1106 ---- * routine. */ static int arm_dis_ldstr_multi(uint32_t in, char *buf, size_t buflen) { ! int sbit, wbit, lbit; uint16_t regs, addr_mode; arm_reg_t rn; arm_cond_code_t cc; size_t len;
*** 1049,1083 **** lbit = in & ARM_LSM_LBIT_MASK; rn = (in & ARM_LSM_RN_MASK) >> ARM_LSM_RN_SHIFT; regs = in & ARM_LSM_RLIST_MASK; addr_mode = (in & ARM_LSM_ADDR_MASK) >> ARM_LSM_ADDR_SHIFT; len = snprintf(buf, buflen, "%s%s%s %s%s, { ", ! lbit != 0 ? "LDM" : "STM", arm_cond_names[cc], arm_lsm_mode_names[addr_mode], arm_reg_names[rn], wbit != 0 ? "!" : ""); ! cont = 0; ! for (ii = 0; ii < 16; ii++) { ! if (!(regs & (1 << ii))) ! continue; ! ! len += snprintf(buf + len, buflen - len, "%s%s", ! cont > 0 ? ", " : "", arm_reg_names[ii]); ! if (len >= buflen) ! return (-1); ! cont++; ! } len += snprintf(buf + len, buflen - len, " }%s", sbit != 0 ? "^" : ""); return (len >= buflen ? -1 : 0); } /* ! * Here we need to handle miscillaneous loads and stores. This is used to load * and store signed and unsigned half words. To load a signed byte. And to load * and store double words. There is no specific store routines for signed bytes * and halfwords as they are supposed to use the SRB and STRH. There are two * primary encodings this time. The general case looks like: * --- 1110,1140 ---- lbit = in & ARM_LSM_LBIT_MASK; rn = (in & ARM_LSM_RN_MASK) >> ARM_LSM_RN_SHIFT; regs = in & ARM_LSM_RLIST_MASK; addr_mode = (in & ARM_LSM_ADDR_MASK) >> ARM_LSM_ADDR_SHIFT; + if ((lbit == 0 && addr_mode == 2 && rn == ARM_REG_R13 && wbit != 0) || + (lbit != 0 && addr_mode == 1 && rn == ARM_REG_R13 && wbit != 0)) + len = snprintf(buf, buflen, "%s%s { ", + lbit != 0 ? "pop" : "push", + arm_cond_names[cc]); + else len = snprintf(buf, buflen, "%s%s%s %s%s, { ", ! lbit != 0 ? "ldm" : "stm", arm_cond_names[cc], arm_lsm_mode_names[addr_mode], arm_reg_names[rn], wbit != 0 ? "!" : ""); ! len += print_reg_list(buf + len, buflen - len, regs); len += snprintf(buf + len, buflen - len, " }%s", sbit != 0 ? "^" : ""); return (len >= buflen ? -1 : 0); } /* ! * Here we need to handle miscellaneous loads and stores. This is used to load * and store signed and unsigned half words. To load a signed byte. And to load * and store double words. There is no specific store routines for signed bytes * and halfwords as they are supposed to use the SRB and STRH. There are two * primary encodings this time. The general case looks like: *
*** 1126,1147 **** lbit = in & ARM_ELS_LBIT_MASK; sbit = in & ARM_ELS_SBIT_MASK; hbit = in & ARM_ELS_SBIT_MASK; if (lbit || (sbit && hbit == 0)) ! iname = "LDR"; else ! iname = "STR"; if (sbit == 0 && hbit) ! suffix = "H"; else if (lbit == 0) ! suffix = "D"; else if (sbit && hbit == 0) ! suffix = "SB"; else if (sbit && hbit) ! suffix = "SH"; cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; rn = (in & ARM_ELS_RN_MASK) >> ARM_ELS_RN_SHIFT; rd = (in & ARM_ELS_RD_MASK) >> ARM_ELS_RD_SHIFT; --- 1183,1204 ---- lbit = in & ARM_ELS_LBIT_MASK; sbit = in & ARM_ELS_SBIT_MASK; hbit = in & ARM_ELS_SBIT_MASK; if (lbit || (sbit && hbit == 0)) ! iname = "ldr"; else ! iname = "str"; if (sbit == 0 && hbit) ! suffix = "h"; else if (lbit == 0) ! suffix = "d"; else if (sbit && hbit == 0) ! suffix = "sb"; else if (sbit && hbit) ! suffix = "sh"; cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; rn = (in & ARM_ELS_RN_MASK) >> ARM_ELS_RN_SHIFT; rd = (in & ARM_ELS_RD_MASK) >> ARM_ELS_RD_SHIFT;
*** 1200,1212 **** cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; rn = (in & ARM_ELS_RN_MASK) >> ARM_ELS_RN_SHIFT; rd = (in & ARM_ELS_RD_MASK) >> ARM_ELS_RD_SHIFT; rm = in & ARM_ELS_RN_MASK; ! if (snprintf(buf, buflen, "SWP%s%s %s, %s, [%s]", arm_cond_names[cc], ! (in & ARM_ELS_SWAP_BYTE_MASK) ? "B" : "", arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rn]) >= buflen) return (-1); return (0); --- 1257,1269 ---- cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; rn = (in & ARM_ELS_RN_MASK) >> ARM_ELS_RN_SHIFT; rd = (in & ARM_ELS_RD_MASK) >> ARM_ELS_RD_SHIFT; rm = in & ARM_ELS_RN_MASK; ! if (snprintf(buf, buflen, "swp%s%s %s, %s, [%s]", arm_cond_names[cc], ! (in & ARM_ELS_SWAP_BYTE_MASK) ? "b" : "", arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rn]) >= buflen) return (-1); return (0);
*** 1227,1238 **** rn = (in & ARM_ELS_RN_MASK) >> ARM_ELS_RN_SHIFT; rd = (in & ARM_ELS_RD_MASK) >> ARM_ELS_RD_SHIFT; rm = in & ARM_ELS_RN_MASK; lbit = in & ARM_ELS_LBIT_MASK; ! len = snprintf(buf, buflen, "%s%sEX %s, ", ! lbit != 0 ? "LDR" : "STR", arm_cond_names[cc], arm_reg_names[rd]); if (len >= buflen) return (-1); if (lbit) --- 1284,1295 ---- rn = (in & ARM_ELS_RN_MASK) >> ARM_ELS_RN_SHIFT; rd = (in & ARM_ELS_RD_MASK) >> ARM_ELS_RD_SHIFT; rm = in & ARM_ELS_RN_MASK; lbit = in & ARM_ELS_LBIT_MASK; ! len = snprintf(buf, buflen, "%s%sex %s, ", ! lbit != 0 ? "ldr" : "str", arm_cond_names[cc], arm_reg_names[rd]); if (len >= buflen) return (-1); if (lbit)
*** 1290,1322 **** cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; if ((in & ARM_EMULT_MA_MASK) == 0) { if (in & ARM_EMULT_ABIT_MASK) { ! len = snprintf(buf, buflen, "MLA%s%s %s, %s, %s, %s", arm_cond_names[cc], ! (in & ARM_EMULT_SBIT_MASK) ? "S" : "", arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs], arm_reg_names[rs]); } else { ! len = snprintf(buf, buflen, "MUL%s%s %s, %s, %s", arm_cond_names[cc], ! (in & ARM_EMULT_SBIT_MASK) ? "S" : "", arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs]); } } else if ((in & ARM_EMULT_UMA_MASK) == ARM_EMULT_UMA_TARG) { ! len = snprintf(buf, buflen, "UMAAL%s %s, %s, %s, %s", arm_cond_names[cc], arm_reg_names[rn], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs]); } else if ((in & ARM_EMULT_MAL_MASK) == ARM_EMULT_MAL_TARG) { len = snprintf(buf, buflen, "%s%s%s%s %s, %s, %s, %s", ! (in & ARM_EMULT_UNBIT_MASK) ? "S" : "U", ! (in & ARM_EMULT_ABIT_MASK) ? "MLAL" : "MULL", arm_cond_names[cc], ! (in & ARM_EMULT_SBIT_MASK) ? "S" : "", arm_reg_names[rn], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs]); } else { /* Not a supported instruction in this space */ return (-1); --- 1347,1379 ---- cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; if ((in & ARM_EMULT_MA_MASK) == 0) { if (in & ARM_EMULT_ABIT_MASK) { ! len = snprintf(buf, buflen, "mla%s%s %s, %s, %s, %s", arm_cond_names[cc], ! (in & ARM_EMULT_SBIT_MASK) ? "s" : "", arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs], arm_reg_names[rs]); } else { ! len = snprintf(buf, buflen, "mul%s%s %s, %s, %s", arm_cond_names[cc], ! (in & ARM_EMULT_SBIT_MASK) ? "s" : "", arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs]); } } else if ((in & ARM_EMULT_UMA_MASK) == ARM_EMULT_UMA_TARG) { ! len = snprintf(buf, buflen, "umaal%s %s, %s, %s, %s", arm_cond_names[cc], arm_reg_names[rn], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs]); } else if ((in & ARM_EMULT_MAL_MASK) == ARM_EMULT_MAL_TARG) { len = snprintf(buf, buflen, "%s%s%s%s %s, %s, %s, %s", ! (in & ARM_EMULT_UNBIT_MASK) ? "s" : "u", ! (in & ARM_EMULT_ABIT_MASK) ? "mlal" : "mull", arm_cond_names[cc], ! (in & ARM_EMULT_SBIT_MASK) ? "s" : "", arm_reg_names[rn], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs]); } else { /* Not a supported instruction in this space */ return (-1);
*** 1339,1359 **** cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; if ((in & ARM_CDSP_MRS_MASK) == ARM_CDSP_MRS_TARG) { rd = (in & ARM_CDSP_RD_MASK) >> ARM_CDSP_RD_SHIFT; ! if (snprintf(buf, buflen, "MRS%s %s, %s", arm_cond_names[cc], arm_reg_names[rd], ! (in & ARM_CDSP_STATUS_RBIT) != 0 ? "SPSR" : "CPSR") >= buflen) return (-1); return (0); } field = (in & ARM_CDSP_MSR_F_MASK) >> ARM_CDSP_MSR_F_SHIFT; ! len = snprintf(buf, buflen, "MSR%s %s_%s, ", arm_cond_names[cc], ! (in & ARM_CDSP_STATUS_RBIT) != 0 ? "SPSR" : "CPSR", arm_cdsp_msr_field_names[field]); if (len >= buflen) return (-1); if (in & ARM_CDSP_MSR_ISIMM_MASK) { --- 1396,1416 ---- cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; if ((in & ARM_CDSP_MRS_MASK) == ARM_CDSP_MRS_TARG) { rd = (in & ARM_CDSP_RD_MASK) >> ARM_CDSP_RD_SHIFT; ! if (snprintf(buf, buflen, "mrs%s %s, %s", arm_cond_names[cc], arm_reg_names[rd], ! (in & ARM_CDSP_STATUS_RBIT) != 0 ? "spsr" : "cpsr") >= buflen) return (-1); return (0); } field = (in & ARM_CDSP_MSR_F_MASK) >> ARM_CDSP_MSR_F_SHIFT; ! len = snprintf(buf, buflen, "msr%s %s_%s, ", arm_cond_names[cc], ! (in & ARM_CDSP_STATUS_RBIT) != 0 ? "spsr" : "cpsr", arm_cdsp_msr_field_names[field]); if (len >= buflen) return (-1); if (in & ARM_CDSP_MSR_ISIMM_MASK) {
*** 1400,1433 **** */ if ((in & ARM_CDSP_BEX_UP_MASK) == ARM_CDSP_BEX_UP_TARG && (in & ARM_CDSP_BEX_LOW_MASK) != ARM_CDSP_BEX_NLOW_TARG) { rm = in & ARM_CDSP_RM_MASK; imm = (in & ARM_CDSP_BEX_TYPE_MASK) >> ARM_CDSP_BEX_TYPE_SHIFT; ! if (snprintf(buf, buflen, "B%s%s %s", ! imm == ARM_CDSP_BEX_TYPE_X ? "X" : ! imm == ARM_CDSP_BEX_TYPE_J ? "XJ" : "LX", arm_cond_names[cc], arm_reg_names[rm]) >= buflen) return (-1); return (0); } /* Count leading zeros */ if ((in & ARM_CDSP_CLZ_MASK) == ARM_CDSP_CLZ_TARG) { rd = (in & ARM_CDSP_RD_MASK) >> ARM_CDSP_RD_SHIFT; rm = in & ARM_CDSP_RM_MASK; ! if (snprintf(buf, buflen, "CLZ%s %s, %s", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm]) >= buflen) return (-1); return (0); } if ((in & ARM_CDSP_SAT_MASK) == ARM_CDSP_SAT_TARG) { rd = (in & ARM_CDSP_RD_MASK) >> ARM_CDSP_RD_SHIFT; rn = (in & ARM_CDSP_RN_MASK) >> ARM_CDSP_RN_SHIFT; rm = in & ARM_CDSP_RM_MASK; imm = (in & ARM_CDSP_SAT_OP_MASK) >> ARM_CDSP_SAT_OP_SHIFT; ! if (snprintf(buf, buflen, "Q%s%s %s, %s, %s", arm_cdsp_sat_opnames[imm], arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rn]) >= buflen) return (-1); return (0); --- 1457,1490 ---- */ if ((in & ARM_CDSP_BEX_UP_MASK) == ARM_CDSP_BEX_UP_TARG && (in & ARM_CDSP_BEX_LOW_MASK) != ARM_CDSP_BEX_NLOW_TARG) { rm = in & ARM_CDSP_RM_MASK; imm = (in & ARM_CDSP_BEX_TYPE_MASK) >> ARM_CDSP_BEX_TYPE_SHIFT; ! if (snprintf(buf, buflen, "b%s%s %s", ! imm == ARM_CDSP_BEX_TYPE_X ? "x" : ! imm == ARM_CDSP_BEX_TYPE_J ? "xj" : "lx", arm_cond_names[cc], arm_reg_names[rm]) >= buflen) return (-1); return (0); } /* Count leading zeros */ if ((in & ARM_CDSP_CLZ_MASK) == ARM_CDSP_CLZ_TARG) { rd = (in & ARM_CDSP_RD_MASK) >> ARM_CDSP_RD_SHIFT; rm = in & ARM_CDSP_RM_MASK; ! if (snprintf(buf, buflen, "clz%s %s, %s", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm]) >= buflen) return (-1); return (0); } if ((in & ARM_CDSP_SAT_MASK) == ARM_CDSP_SAT_TARG) { rd = (in & ARM_CDSP_RD_MASK) >> ARM_CDSP_RD_SHIFT; rn = (in & ARM_CDSP_RN_MASK) >> ARM_CDSP_RN_SHIFT; rm = in & ARM_CDSP_RM_MASK; imm = (in & ARM_CDSP_SAT_OP_MASK) >> ARM_CDSP_SAT_OP_SHIFT; ! if (snprintf(buf, buflen, "q%s%s %s, %s, %s", arm_cdsp_sat_opnames[imm], arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rn]) >= buflen) return (-1); return (0);
*** 1445,1455 **** return (-1); imm = (in & ARM_CDSP_BKPT_UIMM_MASK) >> ARM_CDSP_BKPT_UIMM_SHIFT; imm <<= 4; imm |= (in & ARM_CDSP_BKPT_LIMM_MASK); ! if (snprintf(buf, buflen, "BKPT %d", imm) >= buflen) return (1); return (0); } /* --- 1502,1512 ---- return (-1); imm = (in & ARM_CDSP_BKPT_UIMM_MASK) >> ARM_CDSP_BKPT_UIMM_SHIFT; imm <<= 4; imm |= (in & ARM_CDSP_BKPT_LIMM_MASK); ! if (snprintf(buf, buflen, "bkpt %d", imm) >= buflen) return (1); return (0); } /*
*** 1477,1522 **** rm = in & ARM_CDSP_RM_MASK; op = (in & ARM_CDSP_SMUL_OP_MASK) >> ARM_CDSP_SMUL_OP_SHIFT; switch (op) { case 0: ! len = snprintf(buf, buflen, "SMLA%s%s%s %s, %s, %s, %s", ! (in & ARM_CDSP_SMUL_X_MASK) != 0 ? "T" : "B", ! (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "T" : "B", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs], arm_reg_names[rn]); break; case 1: if (in & ARM_CDSP_SMUL_X_MASK) { len = snprintf(buf, buflen, ! "SMULW%s%s %s, %s, %s", ! (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "T" : ! "B", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs]); } else { len = snprintf(buf, buflen, ! "SMLAW%s%s %s, %s, %s %s", ! (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "T" : ! "B", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs], arm_reg_names[rn]); } break; case 2: len = snprintf(buf, buflen, ! "SMLAL%s%s%s %s, %s, %s, %s", ! (in & ARM_CDSP_SMUL_X_MASK) != 0 ? "T" : "B", ! (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "T" : "B", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rn], arm_reg_names[rm], arm_reg_names[rs]); break; case 3: ! len = snprintf(buf, buflen, "SMUL%s%s%s %s, %s, %s", ! (in & ARM_CDSP_SMUL_X_MASK) != 0 ? "T" : "B", ! (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "T" : "B", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs]); break; default: return (-1); --- 1534,1579 ---- rm = in & ARM_CDSP_RM_MASK; op = (in & ARM_CDSP_SMUL_OP_MASK) >> ARM_CDSP_SMUL_OP_SHIFT; switch (op) { case 0: ! len = snprintf(buf, buflen, "smla%s%s%s %s, %s, %s, %s", ! (in & ARM_CDSP_SMUL_X_MASK) != 0 ? "t" : "b", ! (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "t" : "b", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs], arm_reg_names[rn]); break; case 1: if (in & ARM_CDSP_SMUL_X_MASK) { len = snprintf(buf, buflen, ! "smulw%s%s %s, %s, %s", ! (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "t" : ! "b", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs]); } else { len = snprintf(buf, buflen, ! "smlaw%s%s %s, %s, %s %s", ! (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "t" : ! "b", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs], arm_reg_names[rn]); } break; case 2: len = snprintf(buf, buflen, ! "smlal%s%s%s %s, %s, %s, %s", ! (in & ARM_CDSP_SMUL_X_MASK) != 0 ? "t" : "b", ! (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "t" : "b", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rn], arm_reg_names[rm], arm_reg_names[rs]); break; case 3: ! len = snprintf(buf, buflen, "smul%s%s%s %s, %s, %s", ! (in & ARM_CDSP_SMUL_X_MASK) != 0 ? "t" : "b", ! (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "t" : "b", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs]); break; default: return (-1);
*** 1562,1573 **** if (cc == ARM_COND_NACC) ccn = "2"; else ccn = arm_cond_names[cc]; ! len = snprintf(buf, buflen, "%s%s %s, #%d, %s, %s, C%s", ! (in & ARM_COPROC_DRT_DIR_MASK) != 0 ? "MRRC" : "MCRR", ccn, arm_coproc_names[coproc], op, arm_reg_names[rd], arm_reg_names[rn], arm_reg_names[rm]); return (len >= buflen ? -1 : 0); } --- 1619,1630 ---- if (cc == ARM_COND_NACC) ccn = "2"; else ccn = arm_cond_names[cc]; ! len = snprintf(buf, buflen, "%s%s %s, #%d, %s, %s, c%s", ! (in & ARM_COPROC_DRT_DIR_MASK) != 0 ? "mrrc" : "mcrr", ccn, arm_coproc_names[coproc], op, arm_reg_names[rd], arm_reg_names[rn], arm_reg_names[rm]); return (len >= buflen ? -1 : 0); }
*** 1628,1639 **** if (cc == ARM_COND_NACC) ccn = "2"; else ccn = arm_cond_names[cc]; ! len = snprintf(buf, buflen, "%s%s%s %s, C%s, ", ! lbit != 0 ? "LDC" : "STC", ccn, nbit != 0 ? "L" : "", arm_coproc_names[coproc], arm_reg_names[rd]); if (len >= buflen) return (-1); if (pbit != 0) { --- 1685,1696 ---- if (cc == ARM_COND_NACC) ccn = "2"; else ccn = arm_cond_names[cc]; ! len = snprintf(buf, buflen, "%s%s%s %s, c%s, ", ! lbit != 0 ? "ldc" : "stc", ccn, nbit != 0 ? "l" : "", arm_coproc_names[coproc], arm_reg_names[rd]); if (len >= buflen) return (-1); if (pbit != 0) {
*** 1683,1693 **** if (cc == ARM_COND_NACC) ccn = "2"; else ccn = arm_cond_names[cc]; ! if (snprintf(buf, buflen, "CDP%s %s, #%d, C%s, C%s, C%s, #%d", ccn, arm_coproc_names[coproc], op1, arm_reg_names[rd], arm_reg_names[rn], arm_reg_names[rm], op2) >= buflen) return (-1); return (0); --- 1740,1750 ---- if (cc == ARM_COND_NACC) ccn = "2"; else ccn = arm_cond_names[cc]; ! if (snprintf(buf, buflen, "cdp%s %s, #%d, c%s, c%s, c%s, #%d", ccn, arm_coproc_names[coproc], op1, arm_reg_names[rd], arm_reg_names[rn], arm_reg_names[rm], op2) >= buflen) return (-1); return (0);
*** 1724,1735 **** if (cc == ARM_COND_NACC) ccn = "2"; else ccn = arm_cond_names[cc]; ! len = snprintf(buf, buflen, "%s%s %s, #%d, %s, C%s, C%s", ! (in & ARM_COPROC_CRT_DIR_MASK) != 0 ? "MRC" : "MCR", ccn, arm_coproc_names[coproc], op1, arm_reg_names[rd], arm_reg_names[rn], arm_reg_names[rm]); if (len >= buflen) return (-1); --- 1781,1792 ---- if (cc == ARM_COND_NACC) ccn = "2"; else ccn = arm_cond_names[cc]; ! len = snprintf(buf, buflen, "%s%s %s, #%d, %s, c%s, c%s", ! (in & ARM_COPROC_CRT_DIR_MASK) != 0 ? "mrc" : "mcr", ccn, arm_coproc_names[coproc], op1, arm_reg_names[rd], arm_reg_names[rn], arm_reg_names[rm]); if (len >= buflen) return (-1);
*** 1779,1796 **** /* Ob01 is not a valid value for the imod */ if (imm == 1) return (-1); if (imm != 0) ! len = snprintf(buf, buflen, "CPS%s %s%s%s%s", ! imm == 2 ? "IE" : "ID", (in & ARM_UNI_CPS_A_MASK) ? "a" : "", (in & ARM_UNI_CPS_I_MASK) ? "i" : "", (in & ARM_UNI_CPS_F_MASK) ? "f" : "", (in & ARM_UNI_CPS_MMOD_MASK) ? " ," : ""); else ! len = snprintf(buf, buflen, "CPS "); if (len >= buflen) return (-1); if (in & ARM_UNI_CPS_MMOD_MASK) if (snprintf(buf + len, buflen - len, "#%d", --- 1836,1853 ---- /* Ob01 is not a valid value for the imod */ if (imm == 1) return (-1); if (imm != 0) ! len = snprintf(buf, buflen, "cps%s %s%s%s%s", ! imm == 2 ? "ie" : "id", (in & ARM_UNI_CPS_A_MASK) ? "a" : "", (in & ARM_UNI_CPS_I_MASK) ? "i" : "", (in & ARM_UNI_CPS_F_MASK) ? "f" : "", (in & ARM_UNI_CPS_MMOD_MASK) ? " ," : ""); else ! len = snprintf(buf, buflen, "cps "); if (len >= buflen) return (-1); if (in & ARM_UNI_CPS_MMOD_MASK) if (snprintf(buf + len, buflen - len, "#%d",
*** 1799,1809 **** return (0); } if ((in & ARM_UNI_SE_MASK) == ARM_UNI_SE_TARG) { if (snprintf(buf, buflen, "SETEND %s", ! (in & ARM_UNI_SE_BE_MASK) ? "BE" : "LE") >= buflen) return (-1); return (0); } /* --- 1856,1866 ---- return (0); } if ((in & ARM_UNI_SE_MASK) == ARM_UNI_SE_TARG) { if (snprintf(buf, buflen, "SETEND %s", ! (in & ARM_UNI_SE_BE_MASK) ? "be" : "le") >= buflen) return (-1); return (0); } /*
*** 1814,1833 **** * explanation of what's happening here. */ if ((in & ARM_UNI_PLD_MASK) == ARM_UNI_PLD_TARG) { rn = (in & ARM_LS_RN_MASK) >> ARM_LS_RN_SHIFT; if ((in & ARM_LS_IBIT_MASK) == 0) { ! if (snprintf(buf, buflen, "PLD [%s, #%s%d", arm_reg_names[rn], (in & ARM_LS_UBIT_MASK) != 0 ? "" : "-", in & ARM_LS_IMM_MASK) >= buflen) return (-1); return (0); } rm = in & ARM_LS_REG_RM_MASK; ! len = snprintf(buf, buflen, "PLD [%s, %s%s", arm_reg_names[rn], (in & ARM_LS_UBIT_MASK) != 0 ? "" : "-", arm_reg_names[rm]); if (len >= buflen) return (-1); --- 1871,1890 ---- * explanation of what's happening here. */ if ((in & ARM_UNI_PLD_MASK) == ARM_UNI_PLD_TARG) { rn = (in & ARM_LS_RN_MASK) >> ARM_LS_RN_SHIFT; if ((in & ARM_LS_IBIT_MASK) == 0) { ! if (snprintf(buf, buflen, "pld [%s, #%s%d", arm_reg_names[rn], (in & ARM_LS_UBIT_MASK) != 0 ? "" : "-", in & ARM_LS_IMM_MASK) >= buflen) return (-1); return (0); } rm = in & ARM_LS_REG_RM_MASK; ! len = snprintf(buf, buflen, "pld [%s, %s%s", arm_reg_names[rn], (in & ARM_LS_UBIT_MASK) != 0 ? "" : "-", arm_reg_names[rm]); if (len >= buflen) return (-1);
*** 1859,1869 **** /* * This is a special case of STM, but it works across chip modes. */ if ((in & ARM_UNI_SRS_MASK) == ARM_UNI_SRS_TARG) { imm = (in & ARM_LSM_ADDR_MASK) >> ARM_LSM_ADDR_SHIFT; ! if (snprintf(buf, buflen, "SRS%s #%d%s", arm_lsm_mode_names[imm], in & ARM_UNI_SRS_MODE_MASK, (in & ARM_UNI_SRS_WBIT_MASK) != 0 ? "!" : "") >= buflen) return (-1); return (0); --- 1916,1926 ---- /* * This is a special case of STM, but it works across chip modes. */ if ((in & ARM_UNI_SRS_MASK) == ARM_UNI_SRS_TARG) { imm = (in & ARM_LSM_ADDR_MASK) >> ARM_LSM_ADDR_SHIFT; ! if (snprintf(buf, buflen, "srs%s #%d%s", arm_lsm_mode_names[imm], in & ARM_UNI_SRS_MODE_MASK, (in & ARM_UNI_SRS_WBIT_MASK) != 0 ? "!" : "") >= buflen) return (-1); return (0);
*** 1874,1892 **** * and STM, but a bit different. */ if ((in & ARM_UNI_RFE_MASK) == ARM_UNI_RFE_TARG) { imm = (in & ARM_LSM_ADDR_MASK) >> ARM_LSM_ADDR_SHIFT; rn = (in & ARM_LS_RN_MASK) >> ARM_LS_RN_SHIFT; ! if (snprintf(buf, buflen, "RFE%s %s%s", arm_lsm_mode_names[imm], arm_reg_names[rn], (in & ARM_UNI_RFE_WBIT_MASK) != 0 ? "!" : "") >= buflen) return (-1); return (0); } if ((in & ARM_UNI_BLX_MASK) == ARM_UNI_BLX_TARG) { ! if (snprintf(buf, buflen, "BLX %d", in & ARM_UNI_BLX_IMM_MASK) >= buflen) return (-1); return (0); } --- 1931,1949 ---- * and STM, but a bit different. */ if ((in & ARM_UNI_RFE_MASK) == ARM_UNI_RFE_TARG) { imm = (in & ARM_LSM_ADDR_MASK) >> ARM_LSM_ADDR_SHIFT; rn = (in & ARM_LS_RN_MASK) >> ARM_LS_RN_SHIFT; ! if (snprintf(buf, buflen, "rfe%s %s%s", arm_lsm_mode_names[imm], arm_reg_names[rn], (in & ARM_UNI_RFE_WBIT_MASK) != 0 ? "!" : "") >= buflen) return (-1); return (0); } if ((in & ARM_UNI_BLX_MASK) == ARM_UNI_BLX_TARG) { ! if (snprintf(buf, buflen, "blx %d", in & ARM_UNI_BLX_IMM_MASK) >= buflen) return (-1); return (0); }
*** 1927,1938 **** if (in & ARM_BRANCH_SIGN_MASK) addr |= ARM_BRANCH_NEG_SIGN; else addr &= ARM_BRANCH_POS_SIGN; addr <<= 2; ! if ((len = snprintf(buf, buflen, "B%s%s %d", ! (in & ARM_BRANCH_LBIT_MASK) != 0 ? "L" : "", arm_cond_names[cc], (int)addr)) >= buflen) return (-1); /* Per the ARM manuals, we have to account for the extra 8 bytes here */ if (dhp->dh_lookup(dhp->dh_data, dhp->dh_addr + (int)addr + 8, NULL, 0, --- 1984,1995 ---- if (in & ARM_BRANCH_SIGN_MASK) addr |= ARM_BRANCH_NEG_SIGN; else addr &= ARM_BRANCH_POS_SIGN; addr <<= 2; ! if ((len = snprintf(buf, buflen, "b%s%s %d", ! (in & ARM_BRANCH_LBIT_MASK) != 0 ? "l" : "", arm_cond_names[cc], (int)addr)) >= buflen) return (-1); /* Per the ARM manuals, we have to account for the extra 8 bytes here */ if (dhp->dh_lookup(dhp->dh_data, dhp->dh_addr + (int)addr + 8, NULL, 0,
*** 2029,2059 **** sbit = in & ARM_MEDIA_SZE_S_MASK; cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; switch (op) { case 0x0: ! opn = rn == ARM_REG_R15 ? "XTAB16" : "XTB16"; break; case 0x2: ! opn = rn == ARM_REG_R15 ? "XTAB" : "XTB"; break; case 0x3: ! opn = rn == ARM_REG_R15 ? "XTAH" : "XTH"; break; default: return (-1); break; } if (rn == ARM_REG_R15) { len = snprintf(buf, buflen, "%s%s%s %s, %s", ! sbit != 0 ? "U" : "S", opn, arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rn]); } else { len = snprintf(buf, buflen, "%s%s%s %s, %s, %s", ! sbit != 0 ? "U" : "S", opn, arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rn], arm_reg_names[rm]); } if (len >= buflen) --- 2086,2116 ---- sbit = in & ARM_MEDIA_SZE_S_MASK; cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT; switch (op) { case 0x0: ! opn = rn == ARM_REG_R15 ? "xtab16" : "xtb16"; break; case 0x2: ! opn = rn == ARM_REG_R15 ? "xtab" : "xtb"; break; case 0x3: ! opn = rn == ARM_REG_R15 ? "xtah" : "xth"; break; default: return (-1); break; } if (rn == ARM_REG_R15) { len = snprintf(buf, buflen, "%s%s%s %s, %s", ! sbit != 0 ? "u" : "s", opn, arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rn]); } else { len = snprintf(buf, buflen, "%s%s%s %s, %s, %s", ! sbit != 0 ? "u" : "s", opn, arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rn], arm_reg_names[rm]); } if (len >= buflen)
*** 2092,2114 **** rm = in & ARM_MEDIA_RM_MASK; op1 = (in & ARM_MEDIA_HPACK_SHIFT_MASK) >> ARM_MEDIA_HPACK_SHIFT_IMM; len = snprintf(buf, buflen, "%s%s %s, %s, %s", (in & ARM_MEDIA_HPACK_OP_MASK) != 0 ? ! "PKHTB" : "PKHBT", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rn], arm_reg_names[rd]); if (len >= buflen) return (-1); if (op1 != 0) { if (in & ARM_MEDIA_HPACK_OP_MASK) len += snprintf(buf + len, buflen - len, ! ", ASR %d", op1); else len += snprintf(buf + len, buflen - len, ! ", LSL %d", op1); } return (len >= buflen ? -1 : 0); } if ((in & ARM_MEDIA_WSAT_MASK) == ARM_MEDIA_WSAT_TARG) { --- 2149,2171 ---- rm = in & ARM_MEDIA_RM_MASK; op1 = (in & ARM_MEDIA_HPACK_SHIFT_MASK) >> ARM_MEDIA_HPACK_SHIFT_IMM; len = snprintf(buf, buflen, "%s%s %s, %s, %s", (in & ARM_MEDIA_HPACK_OP_MASK) != 0 ? ! "pkhtb" : "pkhbt", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rn], arm_reg_names[rd]); if (len >= buflen) return (-1); if (op1 != 0) { if (in & ARM_MEDIA_HPACK_OP_MASK) len += snprintf(buf + len, buflen - len, ! ", asr %d", op1); else len += snprintf(buf + len, buflen - len, ! ", lsl %d", op1); } return (len >= buflen ? -1 : 0); } if ((in & ARM_MEDIA_WSAT_MASK) == ARM_MEDIA_WSAT_TARG) {
*** 2117,2127 **** op1 = (in & ARM_MEDIA_SAT_IMM_MASK) >> ARM_MEDIA_SAT_IMM_SHIFT; op2 = (in & ARM_MEDIA_SAT_SHI_MASK) >> ARM_MEDIA_SAT_SHI_SHIFT; len = snprintf(buf, buflen, "%s%s %s, #%d, %s", ! (in & ARM_MEDIA_SAT_U_MASK) != 0 ? "USAT" : "SSAT", arm_cond_names[cc], arm_reg_names[rd], op1, arm_reg_names[rm]); if (len >= buflen) return (-1); --- 2174,2184 ---- op1 = (in & ARM_MEDIA_SAT_IMM_MASK) >> ARM_MEDIA_SAT_IMM_SHIFT; op2 = (in & ARM_MEDIA_SAT_SHI_MASK) >> ARM_MEDIA_SAT_SHI_SHIFT; len = snprintf(buf, buflen, "%s%s %s, #%d, %s", ! (in & ARM_MEDIA_SAT_U_MASK) != 0 ? "usat" : "ssat", arm_cond_names[cc], arm_reg_names[rd], op1, arm_reg_names[rm]); if (len >= buflen) return (-1);
*** 2135,2145 **** if (op2 == 0) op2 = 32; if (snprintf(buf + len, buflen - len, ", %s #%d", (in & ARM_MEDIA_SAT_STYPE_MASK) != 0 ? ! "ASR" : "LSL", op2) >= buflen - len) return (-1); } return (0); } --- 2192,2202 ---- if (op2 == 0) op2 = 32; if (snprintf(buf + len, buflen - len, ", %s #%d", (in & ARM_MEDIA_SAT_STYPE_MASK) != 0 ? ! "asr" : "lsl", op2) >= buflen - len) return (-1); } return (0); }
*** 2147,2198 **** rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; rm = in & ARM_MEDIA_RM_MASK; op1 = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT; if (snprintf(buf, buflen, "%s%s %s, #%d, %s", (in & ARM_MEDIA_SAT_U_MASK) != 0 ? ! "USAT16" : "SSAT16", arm_cond_names[cc], arm_reg_names[rd], op1, arm_reg_names[rm]) >= buflen) return (-1); return (0); } if ((in & ARM_MEDIA_REV_MASK) == ARM_MEDIA_REV_TARG) { rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; rm = in & ARM_MEDIA_RM_MASK; ! if (snprintf(buf, buflen, "REV%s %s, %s", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rd]) >= buflen) return (-1); return (0); } if ((in & ARM_MEDIA_BRPH_MASK) == ARM_MEDIA_BRPH_TARG) { rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; rm = in & ARM_MEDIA_RM_MASK; ! if (snprintf(buf, buflen, "REV16%s %s, %s", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rd]) >= buflen) return (-1); return (0); } if ((in & ARM_MEDIA_BRSH_MASK) == ARM_MEDIA_BRSH_TARG) { rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; rm = in & ARM_MEDIA_RM_MASK; ! if (snprintf(buf, buflen, "REVSH%s %s, %s", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rd]) >= buflen) return (-1); return (0); } if ((in & ARM_MEDIA_SEL_MASK) == ARM_MEDIA_SEL_TARG) { rn = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT; rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; rm = in & ARM_MEDIA_RM_MASK; ! if (snprintf(buf, buflen, "SEL%s %s, %s, %s", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rn], arm_reg_names[rm]) >= buflen) return (-1); return (0); } --- 2204,2255 ---- rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; rm = in & ARM_MEDIA_RM_MASK; op1 = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT; if (snprintf(buf, buflen, "%s%s %s, #%d, %s", (in & ARM_MEDIA_SAT_U_MASK) != 0 ? ! "usat16" : "ssat16", arm_cond_names[cc], arm_reg_names[rd], op1, arm_reg_names[rm]) >= buflen) return (-1); return (0); } if ((in & ARM_MEDIA_REV_MASK) == ARM_MEDIA_REV_TARG) { rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; rm = in & ARM_MEDIA_RM_MASK; ! if (snprintf(buf, buflen, "rev%s %s, %s", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rd]) >= buflen) return (-1); return (0); } if ((in & ARM_MEDIA_BRPH_MASK) == ARM_MEDIA_BRPH_TARG) { rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; rm = in & ARM_MEDIA_RM_MASK; ! if (snprintf(buf, buflen, "rev16%s %s, %s", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rd]) >= buflen) return (-1); return (0); } if ((in & ARM_MEDIA_BRSH_MASK) == ARM_MEDIA_BRSH_TARG) { rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; rm = in & ARM_MEDIA_RM_MASK; ! if (snprintf(buf, buflen, "revsh%s %s, %s", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rd]) >= buflen) return (-1); return (0); } if ((in & ARM_MEDIA_SEL_MASK) == ARM_MEDIA_SEL_TARG) { rn = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT; rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; rm = in & ARM_MEDIA_RM_MASK; ! if (snprintf(buf, buflen, "sel%s %s, %s, %s", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rn], arm_reg_names[rm]) >= buflen) return (-1); return (0); }
*** 2224,2252 **** if (op1 == 0x0) { if (op2 != 0x0 && op2 != 0x1) return (-1); if (rn == ARM_REG_R15) { len = snprintf(buf, buflen, "%s%s%s %s, %s, %s", ! op2 != 0 ? "SMUSD" : "SMUAD", ! xbit != 0 ? "X" : "X", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs]); } else { len = snprintf(buf, buflen, "%s%s%s %s, %s, %s, %s", ! op2 != 0 ? "SMLSD" : "SMLAD", ! xbit != 0 ? "X" : "", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs], arm_reg_names[rn]); } } else if (op1 == 0x8) { if (op2 != 0x0) return (-1); ! len = snprintf(buf, buflen, "SMLALD%s%s %s, %s, %s, %s", ! xbit != 0 ? "X" : "", arm_cond_names[cc], arm_reg_names[rn], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs]); } else return (-1); --- 2281,2309 ---- if (op1 == 0x0) { if (op2 != 0x0 && op2 != 0x1) return (-1); if (rn == ARM_REG_R15) { len = snprintf(buf, buflen, "%s%s%s %s, %s, %s", ! op2 != 0 ? "smusd" : "smuad", ! xbit != 0 ? "x" : "x", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs]); } else { len = snprintf(buf, buflen, "%s%s%s %s, %s, %s, %s", ! op2 != 0 ? "smlsd" : "smlad", ! xbit != 0 ? "x" : "", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs], arm_reg_names[rn]); } } else if (op1 == 0x8) { if (op2 != 0x0) return (-1); ! len = snprintf(buf, buflen, "smlald%s%s %s, %s, %s, %s", ! xbit != 0 ? "x" : "", arm_cond_names[cc], arm_reg_names[rn], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs]); } else return (-1);
*** 2269,2284 **** rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; rs = (in & ARM_MEDIA_RS_MASK) >> ARM_MEDIA_RS_SHIFT; rm = in & ARM_MEDIA_RM_MASK; if (rn != ARM_REG_R15) ! len = snprintf(buf, buflen, "USADA8%s %s, %s, %s, %s", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs], arm_reg_names[rn]); else ! len = snprintf(buf, buflen, "USAD8%s %s, %s, %s", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs]); return (len >= buflen ? -1 : 0); break; default: --- 2326,2341 ---- rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT; rs = (in & ARM_MEDIA_RS_MASK) >> ARM_MEDIA_RS_SHIFT; rm = in & ARM_MEDIA_RM_MASK; if (rn != ARM_REG_R15) ! len = snprintf(buf, buflen, "usada8%s %s, %s, %s, %s", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs], arm_reg_names[rn]); else ! len = snprintf(buf, buflen, "usad8%s %s, %s, %s", arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rs]); return (len >= buflen ? -1 : 0); break; default:
*** 2447,2457 **** /* * The software interrupt is pretty straightforward. The * lower 24 bits are the interrupt number. It's also * valid for it to run with a condition code. */ ! if (snprintf(buf, buflen, "SWI%s %d", arm_cond_names[cc], in & ARM_SWI_IMM_MASK) >= buflen) return (-1); return (0); } else if (in & ARM_L1_7_COPROCMASK) { --- 2504,2514 ---- /* * The software interrupt is pretty straightforward. The * lower 24 bits are the interrupt number. It's also * valid for it to run with a condition code. */ ! if (snprintf(buf, buflen, "swi%s %d", arm_cond_names[cc], in & ARM_SWI_IMM_MASK) >= buflen) return (-1); return (0); } else if (in & ARM_L1_7_COPROCMASK) {