1a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich/* $NetBSD: disassem.c,v 1.14 2003/03/27 16:58:36 mycroft Exp $ */ 2a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 3a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich/*- 4a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * Copyright (c) 1996 Mark Brinicombe. 5a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * Copyright (c) 1996 Brini. 6a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 7a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * All rights reserved. 8a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 9a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * Redistribution and use in source and binary forms, with or without 10a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * modification, are permitted provided that the following conditions 11a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * are met: 12a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 1. Redistributions of source code must retain the above copyright 13a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * notice, this list of conditions and the following disclaimer. 14a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 2. Redistributions in binary form must reproduce the above copyright 15a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * notice, this list of conditions and the following disclaimer in the 16a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * documentation and/or other materials provided with the distribution. 17a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 3. All advertising materials mentioning features or use of this software 18a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * must display the following acknowledgement: 19a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * This product includes software developed by Brini. 20a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 4. The name of the company nor the name of the author may be used to 21a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * endorse or promote products derived from this software without specific 22a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * prior written permission. 23a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 24a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED 25a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 28a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * SUCH DAMAGE. 35a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 36a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * RiscBSD kernel project 37a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 38a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * db_disasm.c 39a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 40a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * Kernel disassembler 41a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 42a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * Created : 10/02/96 43a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 44a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * Structured after the sparc/sparc/db_disasm.c by David S. Miller & 45a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * Paul Kranenburg 46a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 47a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * This code is not complete. Not all instructions are disassembled. 48a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich */ 49a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 50a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich#include <sys/cdefs.h> 51a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich//__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/arm/arm/disassem.c,v 1.2 2005/01/05 21:58:47 imp Exp $"); 52a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich#include <sys/param.h> 53a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich#include <stdio.h> 54a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich#include <stdarg.h> 55a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 56a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich#include "disassem.h" 57a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich#include "armreg.h" 58a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich//#include <ddb/ddb.h> 59a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 60a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich/* 61a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * General instruction format 62a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 63a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * insn[cc][mod] [operands] 64a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 65a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * Those fields with an uppercase format code indicate that the field 66a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * follows directly after the instruction before the separator i.e. 67a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * they modify the instruction rather than just being an operand to 68a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * the instruction. The only exception is the writeback flag which 69a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * follows a operand. 70a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 71a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 72a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * 2 - print Operand 2 of a data processing instruction 73a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * d - destination register (bits 12-15) 74a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * n - n register (bits 16-19) 75a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * s - s register (bits 8-11) 76a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * o - indirect register rn (bits 16-19) (used by swap) 77a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * m - m register (bits 0-3) 78a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * a - address operand of ldr/str instruction 79a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * e - address operand of ldrh/strh instruction 80a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * l - register list for ldm/stm instruction 81a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * f - 1st fp operand (register) (bits 12-14) 82a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * g - 2nd fp operand (register) (bits 16-18) 83a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * h - 3rd fp operand (register/immediate) (bits 0-4) 84a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * b - branch address 85a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * t - thumb branch address (bits 24, 0-23) 86a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * k - breakpoint comment (bits 0-3, 8-19) 87a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * X - block transfer type 88a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * Y - block transfer type (r13 base) 89a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * c - comment field bits(0-23) 90a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * p - saved or current status register 91a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * F - PSR transfer fields 92a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * D - destination-is-r15 (P) flag on TST, TEQ, CMP, CMN 93a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * L - co-processor transfer size 94a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * S - set status flag 95a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * P - fp precision 96a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * Q - fp precision (for ldf/stf) 97a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * R - fp rounding 98a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * v - co-processor data transfer registers + addressing mode 99a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * W - writeback flag 100a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * x - instruction in hex 101a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * # - co-processor number 102a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * y - co-processor data processing registers 103a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich * z - co-processor register transfer registers 104a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich */ 105a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 106a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstruct arm32_insn { 107a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich u_int mask; 108a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich u_int pattern; 109a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich const char* name; 110a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich const char* format; 111a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich}; 112a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 113a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic const struct arm32_insn arm32_i[] = { 114a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0fffffff, 0x0ff00000, "imb", "c" }, /* Before swi */ 115a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0fffffff, 0x0ff00001, "imbrange", "c" }, /* Before swi */ 116a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0f000000, 0x0f000000, "swi", "c" }, 117a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0xfe000000, 0xfa000000, "blx", "t" }, /* Before b and bl */ 118a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0f000000, 0x0a000000, "b", "b" }, 119a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0f000000, 0x0b000000, "bl", "b" }, 120a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0fe000f0, 0x00000090, "mul", "Snms" }, 121a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0fe000f0, 0x00200090, "mla", "Snmsd" }, 122a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0fe000f0, 0x00800090, "umull", "Sdnms" }, 123a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0fe000f0, 0x00c00090, "smull", "Sdnms" }, 124a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0fe000f0, 0x00a00090, "umlal", "Sdnms" }, 125a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0fe000f0, 0x00e00090, "smlal", "Sdnms" }, 126a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0d700000, 0x04200000, "strt", "daW" }, 127a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0d700000, 0x04300000, "ldrt", "daW" }, 128a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0d700000, 0x04600000, "strbt", "daW" }, 129a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0d700000, 0x04700000, "ldrbt", "daW" }, 130a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0c500000, 0x04000000, "str", "daW" }, 131a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0c500000, 0x04100000, "ldr", "daW" }, 132a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0c500000, 0x04400000, "strb", "daW" }, 133a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0c500000, 0x04500000, "ldrb", "daW" }, 134a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0e1f0000, 0x080d0000, "stm", "YnWl" },/* separate out r13 base */ 135a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0e1f0000, 0x081d0000, "ldm", "YnWl" },/* separate out r13 base */ 136a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0e100000, 0x08000000, "stm", "XnWl" }, 137a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0e100000, 0x08100000, "ldm", "XnWl" }, 138a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0e1000f0, 0x00100090, "ldrb", "deW" }, 139a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0e1000f0, 0x00000090, "strb", "deW" }, 140a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0e1000f0, 0x001000d0, "ldrsb", "deW" }, 141a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0e1000f0, 0x001000b0, "ldrh", "deW" }, 142a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0e1000f0, 0x000000b0, "strh", "deW" }, 143a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0e1000f0, 0x001000f0, "ldrsh", "deW" }, 144a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0f200090, 0x00200090, "und", "x" }, /* Before data processing */ 145a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0e1000d0, 0x000000d0, "und", "x" }, /* Before data processing */ 146a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff00ff0, 0x01000090, "swp", "dmo" }, 147a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff00ff0, 0x01400090, "swpb", "dmo" }, 148a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0fbf0fff, 0x010f0000, "mrs", "dp" }, /* Before data processing */ 149a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0fb0fff0, 0x0120f000, "msr", "pFm" },/* Before data processing */ 150a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0fb0f000, 0x0320f000, "msr", "pF2" },/* Before data processing */ 151a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ffffff0, 0x012fff10, "bx", "m" }, 152a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0fff0ff0, 0x016f0f10, "clz", "dm" }, 153a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ffffff0, 0x012fff30, "blx", "m" }, 154a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0xfff000f0, 0xe1200070, "bkpt", "k" }, 155a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0de00000, 0x00000000, "and", "Sdn2" }, 156a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0de00000, 0x00200000, "eor", "Sdn2" }, 157a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0de00000, 0x00400000, "sub", "Sdn2" }, 158a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0de00000, 0x00600000, "rsb", "Sdn2" }, 159a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0de00000, 0x00800000, "add", "Sdn2" }, 160a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0de00000, 0x00a00000, "adc", "Sdn2" }, 161a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0de00000, 0x00c00000, "sbc", "Sdn2" }, 162a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0de00000, 0x00e00000, "rsc", "Sdn2" }, 163a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0df00000, 0x01100000, "tst", "Dn2" }, 164a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0df00000, 0x01300000, "teq", "Dn2" }, 165a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0df00000, 0x01500000, "cmp", "Dn2" }, 166a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0df00000, 0x01700000, "cmn", "Dn2" }, 167a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0de00000, 0x01800000, "orr", "Sdn2" }, 168a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0de00000, 0x01a00000, "mov", "Sd2" }, 169a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0de00000, 0x01c00000, "bic", "Sdn2" }, 170a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0de00000, 0x01e00000, "mvn", "Sd2" }, 171a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e000100, "adf", "PRfgh" }, 172a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e100100, "muf", "PRfgh" }, 173a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e200100, "suf", "PRfgh" }, 174a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e300100, "rsf", "PRfgh" }, 175a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e400100, "dvf", "PRfgh" }, 176a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e500100, "rdf", "PRfgh" }, 177a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e600100, "pow", "PRfgh" }, 178a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e700100, "rpw", "PRfgh" }, 179a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e800100, "rmf", "PRfgh" }, 180a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e900100, "fml", "PRfgh" }, 181a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0ea00100, "fdv", "PRfgh" }, 182a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0eb00100, "frd", "PRfgh" }, 183a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0ec00100, "pol", "PRfgh" }, 184a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0f008f10, 0x0e000100, "fpbop", "PRfgh" }, 185a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e008100, "mvf", "PRfh" }, 186a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e108100, "mnf", "PRfh" }, 187a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e208100, "abs", "PRfh" }, 188a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e308100, "rnd", "PRfh" }, 189a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e408100, "sqt", "PRfh" }, 190a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e508100, "log", "PRfh" }, 191a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e608100, "lgn", "PRfh" }, 192a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e708100, "exp", "PRfh" }, 193a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e808100, "sin", "PRfh" }, 194a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0e908100, "cos", "PRfh" }, 195a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0ea08100, "tan", "PRfh" }, 196a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0eb08100, "asn", "PRfh" }, 197a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0ec08100, "acs", "PRfh" }, 198a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff08f10, 0x0ed08100, "atn", "PRfh" }, 199a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0f008f10, 0x0e008100, "fpuop", "PRfh" }, 200a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0e100f00, 0x0c000100, "stf", "QLv" }, 201a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0e100f00, 0x0c100100, "ldf", "QLv" }, 202a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff00f10, 0x0e000110, "flt", "PRgd" }, 203a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff00f10, 0x0e100110, "fix", "PRdh" }, 204a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff00f10, 0x0e200110, "wfs", "d" }, 205a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff00f10, 0x0e300110, "rfs", "d" }, 206a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff00f10, 0x0e400110, "wfc", "d" }, 207a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff00f10, 0x0e500110, "rfc", "d" }, 208a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff0ff10, 0x0e90f110, "cmf", "PRgh" }, 209a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff0ff10, 0x0eb0f110, "cnf", "PRgh" }, 210a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff0ff10, 0x0ed0f110, "cmfe", "PRgh" }, 211a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff0ff10, 0x0ef0f110, "cnfe", "PRgh" }, 212a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0xff100010, 0xfe000010, "mcr2", "#z" }, 213a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0f100010, 0x0e000010, "mcr", "#z" }, 214a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0xff100010, 0xfe100010, "mrc2", "#z" }, 215a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0f100010, 0x0e100010, "mrc", "#z" }, 216a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0xff000010, 0xfe000000, "cdp2", "#y" }, 217a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0f000010, 0x0e000000, "cdp", "#y" }, 218a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0xfe100090, 0xfc100000, "ldc2", "L#v" }, 219a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0e100090, 0x0c100000, "ldc", "L#v" }, 220a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0xfe100090, 0xfc000000, "stc2", "L#v" }, 221a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0e100090, 0x0c000000, "stc", "L#v" }, 222a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0xf550f000, 0xf550f000, "pld", "ne" }, 223a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff00ff0, 0x01000050, "qaad", "dmn" }, 224a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff00ff0, 0x01400050, "qdaad", "dmn" }, 225a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff00ff0, 0x01600050, "qdsub", "dmn" }, 226a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff00ff0, 0x01200050, "dsub", "dmn" }, 227a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff000f0, 0x01000080, "smlabb", "nmsd" }, // d & n inverted!! 228a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff000f0, 0x010000a0, "smlatb", "nmsd" }, // d & n inverted!! 229a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff000f0, 0x010000c0, "smlabt", "nmsd" }, // d & n inverted!! 230a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff000f0, 0x010000e0, "smlatt", "nmsd" }, // d & n inverted!! 231a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff000f0, 0x01400080, "smlalbb","ndms" }, // d & n inverted!! 232a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff000f0, 0x014000a0, "smlaltb","ndms" }, // d & n inverted!! 233a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff000f0, 0x014000c0, "smlalbt","ndms" }, // d & n inverted!! 234a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff000f0, 0x014000e0, "smlaltt","ndms" }, // d & n inverted!! 235a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff000f0, 0x01200080, "smlawb", "nmsd" }, // d & n inverted!! 236a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff0f0f0, 0x012000a0, "smulwb","nms" }, // d & n inverted!! 237a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff000f0, 0x012000c0, "smlawt", "nmsd" }, // d & n inverted!! 238a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff0f0f0, 0x012000e0, "smulwt","nms" }, // d & n inverted!! 239a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff0f0f0, 0x01600080, "smulbb","nms" }, // d & n inverted!! 240a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff0f0f0, 0x016000a0, "smultb","nms" }, // d & n inverted!! 241a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff0f0f0, 0x016000c0, "smulbt","nms" }, // d & n inverted!! 242a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x0ff0f0f0, 0x016000e0, "smultt","nms" }, // d & n inverted!! 243a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich { 0x00000000, 0x00000000, NULL, NULL } 244a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich}; 245a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 246a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic char const arm32_insn_conditions[][4] = { 247a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich "eq", "ne", "cs", "cc", 248a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich "mi", "pl", "vs", "vc", 249a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich "hi", "ls", "ge", "lt", 250a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich "gt", "le", "", "nv" 251a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich}; 252a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 253a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic char const insn_block_transfers[][4] = { 254a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich "da", "ia", "db", "ib" 255a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich}; 256a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 257a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic char const insn_stack_block_transfers[][4] = { 258a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich "ed", "ea", "fd", "fa" 259a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich}; 260a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 261a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic char const op_shifts[][4] = { 262a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich "lsl", "lsr", "asr", "ror" 263a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich}; 264a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 265a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic char const insn_fpa_rounding[][2] = { 266a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich "", "p", "m", "z" 267a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich}; 268a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 269a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic char const insn_fpa_precision[][2] = { 270a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich "s", "d", "e", "p" 271a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich}; 272a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 273a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic char const insn_fpaconstants[][8] = { 274a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich "0.0", "1.0", "2.0", "3.0", 275a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich "4.0", "5.0", "0.5", "10.0" 276a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich}; 277a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 278a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich#define insn_condition(x) arm32_insn_conditions[(x >> 28) & 0x0f] 279a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich#define insn_blktrans(x) insn_block_transfers[(x >> 23) & 3] 280a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich#define insn_stkblktrans(x) insn_stack_block_transfers[(x >> 23) & 3] 281a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich#define op2_shift(x) op_shifts[(x >> 5) & 3] 282a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich#define insn_fparnd(x) insn_fpa_rounding[(x >> 5) & 0x03] 283a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich#define insn_fpaprec(x) insn_fpa_precision[(((x >> 18) & 2)|(x >> 7)) & 1] 284a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich#define insn_fpaprect(x) insn_fpa_precision[(((x >> 21) & 2)|(x >> 15)) & 1] 285a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich#define insn_fpaimm(x) insn_fpaconstants[x & 0x07] 286a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 287a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich/* Local prototypes */ 288a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic void disasm_register_shift(const disasm_interface_t *di, u_int insn); 289a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic void disasm_print_reglist(const disasm_interface_t *di, u_int insn); 290a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic void disasm_insn_ldrstr(const disasm_interface_t *di, u_int insn, 291a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich u_int loc); 292a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic void disasm_insn_ldrhstrh(const disasm_interface_t *di, u_int insn, 293a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich u_int loc); 294a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic void disasm_insn_ldcstc(const disasm_interface_t *di, u_int insn, 295a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich u_int loc); 296a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic u_int disassemble_readword(u_int address); 297a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic void disassemble_printaddr(u_int address); 298a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 299a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichu_int 300a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichdisasm(const disasm_interface_t *di, u_int loc, int altfmt) 301a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich{ 302a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich const struct arm32_insn *i_ptr = &arm32_i[0]; 303a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 304a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich u_int insn; 305a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich int matchp; 306a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich int branch; 307a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich const char* f_ptr; 308a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich int fmt; 309a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 310a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich fmt = 0; 311a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich matchp = 0; 312a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich insn = di->di_readword(loc); 313a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 314a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich/* di->di_printf("loc=%08x insn=%08x : ", loc, insn);*/ 315a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 316a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich while (i_ptr->name) { 317a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if ((insn & i_ptr->mask) == i_ptr->pattern) { 318a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich matchp = 1; 319a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 320a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } 321a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich i_ptr++; 322a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } 323a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 324a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (!matchp) { 325a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("und%s\t%08x\n", insn_condition(insn), insn); 326a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich return(loc + INSN_SIZE); 327a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } 328a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 329a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* If instruction forces condition code, don't print it. */ 330a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if ((i_ptr->mask & 0xf0000000) == 0xf0000000) 331a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("%s", i_ptr->name); 332a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich else 333a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("%s%s", i_ptr->name, insn_condition(insn)); 334a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 335a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich f_ptr = i_ptr->format; 336a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 337a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* Insert tab if there are no instruction modifiers */ 338a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 339a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (*(f_ptr) < 'A' || *(f_ptr) > 'Z') { 340a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich ++fmt; 341a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("\t"); 342a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } 343a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 344a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich while (*f_ptr) { 345a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich switch (*f_ptr) { 346a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* 2 - print Operand 2 of a data processing instruction */ 347a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case '2': 348a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & 0x02000000) { 349a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich int rotate= ((insn >> 7) & 0x1e); 350a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 351a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("#0x%08x", 352a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich (insn & 0xff) << (32 - rotate) | 353a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich (insn & 0xff) >> rotate); 354a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } else { 355a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich disasm_register_shift(di, insn); 356a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } 357a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 358a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* d - destination register (bits 12-15) */ 359a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'd': 360a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("r%d", ((insn >> 12) & 0x0f)); 361a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 362a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* D - insert 'p' if Rd is R15 */ 363a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'D': 364a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (((insn >> 12) & 0x0f) == 15) 365a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("p"); 366a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 367a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* n - n register (bits 16-19) */ 368a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'n': 369a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("r%d", ((insn >> 16) & 0x0f)); 370a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 371a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* s - s register (bits 8-11) */ 372a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 's': 373a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("r%d", ((insn >> 8) & 0x0f)); 374a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 375a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* o - indirect register rn (bits 16-19) (used by swap) */ 376a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'o': 377a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("[r%d]", ((insn >> 16) & 0x0f)); 378a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 379a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* m - m register (bits 0-4) */ 380a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'm': 381a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("r%d", ((insn >> 0) & 0x0f)); 382a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 383a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* a - address operand of ldr/str instruction */ 384a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'a': 385a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich disasm_insn_ldrstr(di, insn, loc); 386a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 387a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* e - address operand of ldrh/strh instruction */ 388a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'e': 389a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich disasm_insn_ldrhstrh(di, insn, loc); 390a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 391a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* l - register list for ldm/stm instruction */ 392a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'l': 393a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich disasm_print_reglist(di, insn); 394a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 395a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* f - 1st fp operand (register) (bits 12-14) */ 396a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'f': 397a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("f%d", (insn >> 12) & 7); 398a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 399a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* g - 2nd fp operand (register) (bits 16-18) */ 400a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'g': 401a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("f%d", (insn >> 16) & 7); 402a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 403a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* h - 3rd fp operand (register/immediate) (bits 0-4) */ 404a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'h': 405a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & (1 << 3)) 406a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("#%s", insn_fpaimm(insn)); 407a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich else 408a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("f%d", insn & 7); 409a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 410a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* b - branch address */ 411a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'b': 412a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich branch = ((insn << 2) & 0x03ffffff); 413a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (branch & 0x02000000) 414a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich branch |= 0xfc000000; 415a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printaddr(loc + 8 + branch); 416a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 417a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* t - blx address */ 418a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 't': 419a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich branch = ((insn << 2) & 0x03ffffff) | 420a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich (insn >> 23 & 0x00000002); 421a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (branch & 0x02000000) 422a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich branch |= 0xfc000000; 423a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printaddr(loc + 8 + branch); 424a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 425a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* X - block transfer type */ 426a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'X': 427a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("%s", insn_blktrans(insn)); 428a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 429a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* Y - block transfer type (r13 base) */ 430a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'Y': 431a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("%s", insn_stkblktrans(insn)); 432a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 433a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* c - comment field bits(0-23) */ 434a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'c': 435a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("0x%08x", (insn & 0x00ffffff)); 436a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 437a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* k - breakpoint comment (bits 0-3, 8-19) */ 438a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'k': 439a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("0x%04x", 440a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich (insn & 0x000fff00) >> 4 | (insn & 0x0000000f)); 441a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 442a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* p - saved or current status register */ 443a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'p': 444a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & 0x00400000) 445a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("spsr"); 446a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich else 447a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("cpsr"); 448a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 449a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* F - PSR transfer fields */ 450a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'F': 451a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("_"); 452a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & (1 << 16)) 453a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("c"); 454a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & (1 << 17)) 455a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("x"); 456a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & (1 << 18)) 457a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("s"); 458a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & (1 << 19)) 459a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("f"); 460a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 461a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* B - byte transfer flag */ 462a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'B': 463a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & 0x00400000) 464a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("b"); 465a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 466a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* L - co-processor transfer size */ 467a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'L': 468a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & (1 << 22)) 469a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("l"); 470a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 471a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* S - set status flag */ 472a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'S': 473a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & 0x00100000) 474a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("s"); 475a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 476a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* P - fp precision */ 477a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'P': 478a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("%s", insn_fpaprec(insn)); 479a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 480a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* Q - fp precision (for ldf/stf) */ 481a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'Q': 482a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 483a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* R - fp rounding */ 484a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'R': 485a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("%s", insn_fparnd(insn)); 486a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 487a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* W - writeback flag */ 488a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'W': 489a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & (1 << 21)) 490a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("!"); 491a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 492a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* # - co-processor number */ 493a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case '#': 494a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("p%d", (insn >> 8) & 0x0f); 495a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 496a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* v - co-processor data transfer registers+addressing mode */ 497a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'v': 498a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich disasm_insn_ldcstc(di, insn, loc); 499a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 500a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* x - instruction in hex */ 501a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'x': 502a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("0x%08x", insn); 503a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 504a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* y - co-processor data processing registers */ 505a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'y': 506a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("%d, ", (insn >> 20) & 0x0f); 507a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 508a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("c%d, c%d, c%d", (insn >> 12) & 0x0f, 509a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich (insn >> 16) & 0x0f, insn & 0x0f); 510a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 511a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf(", %d", (insn >> 5) & 0x07); 512a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 513a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* z - co-processor register transfer registers */ 514a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich case 'z': 515a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("%d, ", (insn >> 21) & 0x07); 516a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("r%d, c%d, c%d, %d", 517a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich (insn >> 12) & 0x0f, (insn >> 16) & 0x0f, 518a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich insn & 0x0f, (insn >> 5) & 0x07); 519a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 520a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich/* if (((insn >> 5) & 0x07) != 0) 521a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf(", %d", (insn >> 5) & 0x07);*/ 522a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 523a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich default: 524a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("[%c - unknown]", *f_ptr); 525a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich break; 526a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } 527a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (*(f_ptr+1) >= 'A' && *(f_ptr+1) <= 'Z') 528a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich ++f_ptr; 529a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich else if (*(++f_ptr)) { 530a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich ++fmt; 531a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (fmt == 1) 532a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("\t"); 533a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich else 534a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf(", "); 535a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } 536a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich }; 537a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 538a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("\n"); 539a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 540a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich return(loc + INSN_SIZE); 541a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich} 542a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 543a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 544a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic void 545a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichdisasm_register_shift(const disasm_interface_t *di, u_int insn) 546a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich{ 547a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("r%d", (insn & 0x0f)); 548a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if ((insn & 0x00000ff0) == 0) 549a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich ; 550a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich else if ((insn & 0x00000ff0) == 0x00000060) 551a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf(", rrx"); 552a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich else { 553a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & 0x10) 554a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf(", %s r%d", op2_shift(insn), 555a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich (insn >> 8) & 0x0f); 556a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich else 557a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf(", %s #%d", op2_shift(insn), 558a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich (insn >> 7) & 0x1f); 559a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } 560a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich} 561a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 562a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 563a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic void 564a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichdisasm_print_reglist(const disasm_interface_t *di, u_int insn) 565a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich{ 566a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich int loop; 567a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich int start; 568a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich int comma; 569a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 570a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("{"); 571a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich start = -1; 572a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich comma = 0; 573a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 574a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich for (loop = 0; loop < 17; ++loop) { 575a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (start != -1) { 576a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (loop == 16 || !(insn & (1 << loop))) { 577a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (comma) 578a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf(", "); 579a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich else 580a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich comma = 1; 581a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (start == loop - 1) 582a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("r%d", start); 583a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich else 584a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("r%d-r%d", start, loop - 1); 585a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich start = -1; 586a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } 587a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } else { 588a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & (1 << loop)) 589a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich start = loop; 590a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } 591a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } 592a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("}"); 593a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 594a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & (1 << 22)) 595a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("^"); 596a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich} 597a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 598a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic void 599a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichdisasm_insn_ldrstr(const disasm_interface_t *di, u_int insn, u_int loc) 600a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich{ 601a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich int offset; 602a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 603a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich offset = insn & 0xfff; 604a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if ((insn & 0x032f0000) == 0x010f0000) { 605a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* rA = pc, immediate index */ 606a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & 0x00800000) 607a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich loc += offset; 608a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich else 609a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich loc -= offset; 610a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printaddr(loc + 8); 611a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } else { 612a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("[r%d", (insn >> 16) & 0x0f); 613a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if ((insn & 0x03000fff) != 0x01000000) { 614a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("%s, ", (insn & (1 << 24)) ? "" : "]"); 615a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (!(insn & 0x00800000)) 616a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("-"); 617a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & (1 << 25)) 618a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich disasm_register_shift(di, insn); 619a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich else 620a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("#0x%03x", offset); 621a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } 622a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & (1 << 24)) 623a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("]"); 624a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } 625a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich} 626a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 627a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic void 628a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichdisasm_insn_ldrhstrh(const disasm_interface_t *di, u_int insn, u_int loc) 629a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich{ 630a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich int offset; 631a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 632a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich offset = ((insn & 0xf00) >> 4) | (insn & 0xf); 633a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if ((insn & 0x004f0000) == 0x004f0000) { 634a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich /* rA = pc, immediate index */ 635a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & 0x00800000) 636a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich loc += offset; 637a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich else 638a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich loc -= offset; 639a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printaddr(loc + 8); 640a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } else { 641a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("[r%d", (insn >> 16) & 0x0f); 642a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if ((insn & 0x01400f0f) != 0x01400000) { 643a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("%s, ", (insn & (1 << 24)) ? "" : "]"); 644a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (!(insn & 0x00800000)) 645a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("-"); 646a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & (1 << 22)) 647a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("#0x%02x", offset); 648a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich else 649a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("r%d", (insn & 0x0f)); 650a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } 651a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & (1 << 24)) 652a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("]"); 653a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich } 654a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich} 655a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 656a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic void 657a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichdisasm_insn_ldcstc(const disasm_interface_t *di, u_int insn, u_int loc) 658a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich{ 659a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (((insn >> 8) & 0xf) == 1) 660a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("f%d, ", (insn >> 12) & 0x07); 661a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich else 662a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("c%d, ", (insn >> 12) & 0x0f); 663a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 664a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("[r%d", (insn >> 16) & 0x0f); 665a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 666a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("%s, ", (insn & (1 << 24)) ? "" : "]"); 667a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 668a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (!(insn & (1 << 23))) 669a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("-"); 670a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 671a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("#0x%03x", (insn & 0xff) << 2); 672a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 673a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & (1 << 24)) 674a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("]"); 675a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 676a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich if (insn & (1 << 21)) 677a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich di->di_printf("!"); 678a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich} 679a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 680a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic u_int 681a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichdisassemble_readword(u_int address) 682a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich{ 683a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich return(*((u_int *)address)); 684a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich} 685a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 686a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic void 687a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichdisassemble_printaddr(u_int address) 688a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich{ 689a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich printf("0x%08x", address); 690a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich} 691a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 692a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic void 693a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichdisassemble_printf(const char *fmt, ...) { 694a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich va_list ap; 695a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich va_start(ap, fmt); 696a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich vprintf(fmt, ap); 697a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich va_end(ap); 698a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich} 699a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 700a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichstatic const disasm_interface_t disassemble_di = { 701a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich disassemble_readword, disassemble_printaddr, disassemble_printf 702a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich}; 703a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 704a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichvoid 705a65356109772b04283d18d21dd5455e825ba8c25Jack Palevichdisassemble(u_int address) 706a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich{ 707a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 708a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich (void)disasm(&disassemble_di, address, 0); 709a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich} 710a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich 711a65356109772b04283d18d21dd5455e825ba8c25Jack Palevich/* End of disassem.c */ 712