16f72e28d04348ad4539679949609675b114896e1andrewfish/** @file 2b32fecd24743853164e151a84cb0e33da556cc74andrewfish Thumb Dissassembler. Still a work in progress. 3b32fecd24743853164e151a84cb0e33da556cc74andrewfish 43402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Wrong output is a bug, so please fix it. 5b32fecd24743853164e151a84cb0e33da556cc74andrewfish Hex output means there is not yet an entry or a decode bug. 63402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron gOpThumb[] are Thumb 16-bit, and gOpThumb2[] work on the 32-bit 73402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 16-bit stream of Thumb2 instruction. Then there are big case 8b32fecd24743853164e151a84cb0e33da556cc74andrewfish statements to print everything out. If you are adding instructions 9b32fecd24743853164e151a84cb0e33da556cc74andrewfish try to reuse existing case entries if possible. 106f72e28d04348ad4539679949609675b114896e1andrewfish 11d6ebcab76903254f4423b7e7d3808fb0abaadb46hhtian Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR> 123402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 13d6ebcab76903254f4423b7e7d3808fb0abaadb46hhtian This program and the accompanying materials 146f72e28d04348ad4539679949609675b114896e1andrewfish are licensed and made available under the terms and conditions of the BSD License 156f72e28d04348ad4539679949609675b114896e1andrewfish which accompanies this distribution. The full text of the license may be found at 166f72e28d04348ad4539679949609675b114896e1andrewfish http://opensource.org/licenses/bsd-license.php 176f72e28d04348ad4539679949609675b114896e1andrewfish 186f72e28d04348ad4539679949609675b114896e1andrewfish THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 196f72e28d04348ad4539679949609675b114896e1andrewfish WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 206f72e28d04348ad4539679949609675b114896e1andrewfish 216f72e28d04348ad4539679949609675b114896e1andrewfish**/ 226f72e28d04348ad4539679949609675b114896e1andrewfish 236f72e28d04348ad4539679949609675b114896e1andrewfish#include <Base.h> 246f72e28d04348ad4539679949609675b114896e1andrewfish#include <Library/BaseLib.h> 25eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish#include <Library/DebugLib.h> 266f72e28d04348ad4539679949609675b114896e1andrewfish#include <Library/PrintLib.h> 276f72e28d04348ad4539679949609675b114896e1andrewfish 287c34497d5de78120879d44ebf4b5e10004894873andrewfishextern CHAR8 *gCondition[]; 297c34497d5de78120879d44ebf4b5e10004894873andrewfish 306f72e28d04348ad4539679949609675b114896e1andrewfishextern CHAR8 *gReg[]; 316f72e28d04348ad4539679949609675b114896e1andrewfish 32b32fecd24743853164e151a84cb0e33da556cc74andrewfish// Thumb address modes 336f72e28d04348ad4539679949609675b114896e1andrewfish#define LOAD_STORE_FORMAT1 1 34eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish#define LOAD_STORE_FORMAT1_H 101 353402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron#define LOAD_STORE_FORMAT1_B 111 366f72e28d04348ad4539679949609675b114896e1andrewfish#define LOAD_STORE_FORMAT2 2 376f72e28d04348ad4539679949609675b114896e1andrewfish#define LOAD_STORE_FORMAT3 3 386f72e28d04348ad4539679949609675b114896e1andrewfish#define LOAD_STORE_FORMAT4 4 393402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron#define LOAD_STORE_MULTIPLE_FORMAT1 5 403402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron#define PUSH_FORMAT 6 413402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron#define POP_FORMAT 106 426f72e28d04348ad4539679949609675b114896e1andrewfish#define IMMED_8 7 436f72e28d04348ad4539679949609675b114896e1andrewfish#define CONDITIONAL_BRANCH 8 446f72e28d04348ad4539679949609675b114896e1andrewfish#define UNCONDITIONAL_BRANCH 9 456f72e28d04348ad4539679949609675b114896e1andrewfish#define UNCONDITIONAL_BRANCH_SHORT 109 466f72e28d04348ad4539679949609675b114896e1andrewfish#define BRANCH_EXCHANGE 10 476f72e28d04348ad4539679949609675b114896e1andrewfish#define DATA_FORMAT1 11 486f72e28d04348ad4539679949609675b114896e1andrewfish#define DATA_FORMAT2 12 496f72e28d04348ad4539679949609675b114896e1andrewfish#define DATA_FORMAT3 13 506f72e28d04348ad4539679949609675b114896e1andrewfish#define DATA_FORMAT4 14 516f72e28d04348ad4539679949609675b114896e1andrewfish#define DATA_FORMAT5 15 526f72e28d04348ad4539679949609675b114896e1andrewfish#define DATA_FORMAT6_SP 16 536f72e28d04348ad4539679949609675b114896e1andrewfish#define DATA_FORMAT6_PC 116 546f72e28d04348ad4539679949609675b114896e1andrewfish#define DATA_FORMAT7 17 556f72e28d04348ad4539679949609675b114896e1andrewfish#define DATA_FORMAT8 19 566f72e28d04348ad4539679949609675b114896e1andrewfish#define CPS_FORMAT 20 576f72e28d04348ad4539679949609675b114896e1andrewfish#define ENDIAN_FORMAT 21 58b32fecd24743853164e151a84cb0e33da556cc74andrewfish#define DATA_CBZ 22 59b32fecd24743853164e151a84cb0e33da556cc74andrewfish#define ADR_FORMAT 23 60f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish#define IT_BLOCK 24 61b32fecd24743853164e151a84cb0e33da556cc74andrewfish 62b32fecd24743853164e151a84cb0e33da556cc74andrewfish// Thumb2 address modes 637c34497d5de78120879d44ebf4b5e10004894873andrewfish#define B_T3 200 647c34497d5de78120879d44ebf4b5e10004894873andrewfish#define B_T4 201 657c34497d5de78120879d44ebf4b5e10004894873andrewfish#define BL_T2 202 66b32fecd24743853164e151a84cb0e33da556cc74andrewfish#define POP_T2 203 67b32fecd24743853164e151a84cb0e33da556cc74andrewfish#define POP_T3 204 68b32fecd24743853164e151a84cb0e33da556cc74andrewfish#define STM_FORMAT 205 69b32fecd24743853164e151a84cb0e33da556cc74andrewfish#define LDM_REG_IMM12_SIGNED 206 70b32fecd24743853164e151a84cb0e33da556cc74andrewfish#define LDM_REG_IMM12_LSL 207 71b32fecd24743853164e151a84cb0e33da556cc74andrewfish#define LDM_REG_IMM8 208 72b32fecd24743853164e151a84cb0e33da556cc74andrewfish#define LDM_REG_IMM12 209 73b32fecd24743853164e151a84cb0e33da556cc74andrewfish#define LDM_REG_INDIRECT_LSL 210 74b32fecd24743853164e151a84cb0e33da556cc74andrewfish#define LDM_REG_IMM8_SIGNED 211 75b32fecd24743853164e151a84cb0e33da556cc74andrewfish#define LDRD_REG_IMM8 212 76b32fecd24743853164e151a84cb0e33da556cc74andrewfish#define LDREXB 213 77b32fecd24743853164e151a84cb0e33da556cc74andrewfish#define LDREXD 214 78b32fecd24743853164e151a84cb0e33da556cc74andrewfish#define SRS_FORMAT 215 79b32fecd24743853164e151a84cb0e33da556cc74andrewfish#define RFE_FORMAT 216 80b32fecd24743853164e151a84cb0e33da556cc74andrewfish#define LDRD_REG_IMM8_SIGNED 217 81eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish#define ADD_IMM12 218 82eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish#define ADD_IMM5 219 83eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish#define ADR_THUMB2 220 84eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish#define CMN_THUMB2 221 85c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish#define ASR_IMM5 222 86c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish#define ASR_3REG 223 87c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish#define BFC_THUMB2 224 88c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish#define CDP_THUMB2 225 89c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish#define THUMB2_NO_ARGS 226 90c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish#define THUMB2_2REGS 227 91c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish#define ADD_IMM5_2REG 228 92c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish#define CPD_THUMB2 229 93c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish#define THUMB2_4REGS 230 94fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish#define ADD_IMM12_1REG 231 95fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish#define THUMB2_IMM16 232 963402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron#define MRC_THUMB2 233 973402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron#define MRRC_THUMB2 234 98fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish#define THUMB2_MRS 235 99fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish#define THUMB2_MSR 236 100fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish 101fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish 102c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 1036f72e28d04348ad4539679949609675b114896e1andrewfish 1046f72e28d04348ad4539679949609675b114896e1andrewfishtypedef struct { 1056f72e28d04348ad4539679949609675b114896e1andrewfish CHAR8 *Start; 1066f72e28d04348ad4539679949609675b114896e1andrewfish UINT32 OpCode; 1076f72e28d04348ad4539679949609675b114896e1andrewfish UINT32 Mask; 1086f72e28d04348ad4539679949609675b114896e1andrewfish UINT32 AddressMode; 1096f72e28d04348ad4539679949609675b114896e1andrewfish} THUMB_INSTRUCTIONS; 1106f72e28d04348ad4539679949609675b114896e1andrewfish 111097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfishTHUMB_INSTRUCTIONS gOpThumb[] = { 1126f72e28d04348ad4539679949609675b114896e1andrewfish// Thumb 16-bit instrucitons 113b32fecd24743853164e151a84cb0e33da556cc74andrewfish// Op Mask Format 114f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish { "ADC" , 0x4140, 0xffc0, DATA_FORMAT5 }, // ADC <Rndn>, <Rm> 115b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "ADR", 0xa000, 0xf800, ADR_FORMAT }, // ADR <Rd>, <label> 1166f72e28d04348ad4539679949609675b114896e1andrewfish { "ADD" , 0x1c00, 0xfe00, DATA_FORMAT2 }, 1176f72e28d04348ad4539679949609675b114896e1andrewfish { "ADD" , 0x3000, 0xf800, DATA_FORMAT3 }, 1186f72e28d04348ad4539679949609675b114896e1andrewfish { "ADD" , 0x1800, 0xfe00, DATA_FORMAT1 }, 1196f72e28d04348ad4539679949609675b114896e1andrewfish { "ADD" , 0x4400, 0xff00, DATA_FORMAT8 }, // A8.6.9 1206f72e28d04348ad4539679949609675b114896e1andrewfish { "ADD" , 0xa000, 0xf100, DATA_FORMAT6_PC }, 1213402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "ADD" , 0xa800, 0xf800, DATA_FORMAT6_SP }, 1227c34497d5de78120879d44ebf4b5e10004894873andrewfish { "ADD" , 0xb000, 0xff80, DATA_FORMAT7 }, 1236f72e28d04348ad4539679949609675b114896e1andrewfish 1246f72e28d04348ad4539679949609675b114896e1andrewfish { "AND" , 0x4000, 0xffc0, DATA_FORMAT5 }, 1256f72e28d04348ad4539679949609675b114896e1andrewfish 1266f72e28d04348ad4539679949609675b114896e1andrewfish { "ASR" , 0x1000, 0xf800, DATA_FORMAT4 }, 1276f72e28d04348ad4539679949609675b114896e1andrewfish { "ASR" , 0x4100, 0xffc0, DATA_FORMAT5 }, 1286f72e28d04348ad4539679949609675b114896e1andrewfish 1296f72e28d04348ad4539679949609675b114896e1andrewfish { "B" , 0xd000, 0xf000, CONDITIONAL_BRANCH }, 1307c34497d5de78120879d44ebf4b5e10004894873andrewfish { "B" , 0xe000, 0xf800, UNCONDITIONAL_BRANCH_SHORT }, 1316f72e28d04348ad4539679949609675b114896e1andrewfish { "BLX" , 0x4780, 0xff80, BRANCH_EXCHANGE }, 1327c34497d5de78120879d44ebf4b5e10004894873andrewfish { "BX" , 0x4700, 0xff87, BRANCH_EXCHANGE }, 1336f72e28d04348ad4539679949609675b114896e1andrewfish 1346f72e28d04348ad4539679949609675b114896e1andrewfish { "BIC" , 0x4380, 0xffc0, DATA_FORMAT5 }, 1356f72e28d04348ad4539679949609675b114896e1andrewfish { "BKPT", 0xdf00, 0xff00, IMMED_8 }, 136b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "CBZ", 0xb100, 0xfd00, DATA_CBZ }, 137b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "CBNZ", 0xb900, 0xfd00, DATA_CBZ }, 1386f72e28d04348ad4539679949609675b114896e1andrewfish { "CMN" , 0x42c0, 0xffc0, DATA_FORMAT5 }, 1396f72e28d04348ad4539679949609675b114896e1andrewfish 1407c34497d5de78120879d44ebf4b5e10004894873andrewfish { "CMP" , 0x2800, 0xf800, DATA_FORMAT3 }, 1416f72e28d04348ad4539679949609675b114896e1andrewfish { "CMP" , 0x4280, 0xffc0, DATA_FORMAT5 }, 1426f72e28d04348ad4539679949609675b114896e1andrewfish { "CMP" , 0x4500, 0xff00, DATA_FORMAT8 }, 1436f72e28d04348ad4539679949609675b114896e1andrewfish 1446f72e28d04348ad4539679949609675b114896e1andrewfish { "CPS" , 0xb660, 0xffe8, CPS_FORMAT }, 1457c34497d5de78120879d44ebf4b5e10004894873andrewfish { "MOV" , 0x4600, 0xff00, DATA_FORMAT8 }, 1466f72e28d04348ad4539679949609675b114896e1andrewfish { "EOR" , 0x4040, 0xffc0, DATA_FORMAT5 }, 1476f72e28d04348ad4539679949609675b114896e1andrewfish 1486f72e28d04348ad4539679949609675b114896e1andrewfish { "LDMIA" , 0xc800, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 }, 149f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish { "LDR" , 0x6800, 0xf800, LOAD_STORE_FORMAT1 }, // LDR <Rt>, [<Rn> {,#<imm>}] 150f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish { "LDR" , 0x5800, 0xfe00, LOAD_STORE_FORMAT2 }, // STR <Rt>, [<Rn>, <Rm>] 1516f72e28d04348ad4539679949609675b114896e1andrewfish { "LDR" , 0x4800, 0xf800, LOAD_STORE_FORMAT3 }, 152f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish { "LDR" , 0x9800, 0xf800, LOAD_STORE_FORMAT4 }, // LDR <Rt>, [SP, #<imm>] 153eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "LDRB" , 0x7800, 0xf800, LOAD_STORE_FORMAT1_B }, 154f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish { "LDRB" , 0x5c00, 0xfe00, LOAD_STORE_FORMAT2 }, // STR <Rt>, [<Rn>, <Rm>] 155eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "LDRH" , 0x8800, 0xf800, LOAD_STORE_FORMAT1_H }, 1566f72e28d04348ad4539679949609675b114896e1andrewfish { "LDRH" , 0x7a00, 0xfe00, LOAD_STORE_FORMAT2 }, 157f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish { "LDRSB" , 0x5600, 0xfe00, LOAD_STORE_FORMAT2 }, // STR <Rt>, [<Rn>, <Rm>] 1586f72e28d04348ad4539679949609675b114896e1andrewfish { "LDRSH" , 0x5e00, 0xfe00, LOAD_STORE_FORMAT2 }, 1593402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 1607c34497d5de78120879d44ebf4b5e10004894873andrewfish { "MOVS", 0x0000, 0xffc0, DATA_FORMAT5 }, // LSL with imm5 == 0 is a MOVS, so this must go before LSL 1616f72e28d04348ad4539679949609675b114896e1andrewfish { "LSL" , 0x0000, 0xf800, DATA_FORMAT4 }, 1626f72e28d04348ad4539679949609675b114896e1andrewfish { "LSL" , 0x4080, 0xffc0, DATA_FORMAT5 }, 1636f72e28d04348ad4539679949609675b114896e1andrewfish { "LSR" , 0x0001, 0xf800, DATA_FORMAT4 }, 1646f72e28d04348ad4539679949609675b114896e1andrewfish { "LSR" , 0x40c0, 0xffc0, DATA_FORMAT5 }, 165c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "LSRS", 0x0800, 0xf800, DATA_FORMAT4 }, // LSRS <Rd>, <Rm>, #<imm5> 1666f72e28d04348ad4539679949609675b114896e1andrewfish 1677c34497d5de78120879d44ebf4b5e10004894873andrewfish { "MOVS", 0x2000, 0xf800, DATA_FORMAT3 }, 1686f72e28d04348ad4539679949609675b114896e1andrewfish { "MOV" , 0x1c00, 0xffc0, DATA_FORMAT3 }, 1696f72e28d04348ad4539679949609675b114896e1andrewfish { "MOV" , 0x4600, 0xff00, DATA_FORMAT8 }, 1706f72e28d04348ad4539679949609675b114896e1andrewfish 1716f72e28d04348ad4539679949609675b114896e1andrewfish { "MUL" , 0x4340, 0xffc0, DATA_FORMAT5 }, 1726f72e28d04348ad4539679949609675b114896e1andrewfish { "MVN" , 0x41c0, 0xffc0, DATA_FORMAT5 }, 1736f72e28d04348ad4539679949609675b114896e1andrewfish { "NEG" , 0x4240, 0xffc0, DATA_FORMAT5 }, 174f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish { "ORR" , 0x4300, 0xffc0, DATA_FORMAT5 }, 1757c34497d5de78120879d44ebf4b5e10004894873andrewfish { "POP" , 0xbc00, 0xfe00, POP_FORMAT }, 1767c34497d5de78120879d44ebf4b5e10004894873andrewfish { "PUSH", 0xb400, 0xfe00, PUSH_FORMAT }, 1777c34497d5de78120879d44ebf4b5e10004894873andrewfish 1786f72e28d04348ad4539679949609675b114896e1andrewfish { "REV" , 0xba00, 0xffc0, DATA_FORMAT5 }, 1796f72e28d04348ad4539679949609675b114896e1andrewfish { "REV16" , 0xba40, 0xffc0, DATA_FORMAT5 }, 1806f72e28d04348ad4539679949609675b114896e1andrewfish { "REVSH" , 0xbac0, 0xffc0, DATA_FORMAT5 }, 1816f72e28d04348ad4539679949609675b114896e1andrewfish 1827c34497d5de78120879d44ebf4b5e10004894873andrewfish { "ROR" , 0x41c0, 0xffc0, DATA_FORMAT5 }, 1837c34497d5de78120879d44ebf4b5e10004894873andrewfish { "SBC" , 0x4180, 0xffc0, DATA_FORMAT5 }, 1847c34497d5de78120879d44ebf4b5e10004894873andrewfish { "SETEND" , 0xb650, 0xfff0, ENDIAN_FORMAT }, 1856f72e28d04348ad4539679949609675b114896e1andrewfish 1866f72e28d04348ad4539679949609675b114896e1andrewfish { "STMIA" , 0xc000, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 }, 187f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish { "STR" , 0x6000, 0xf800, LOAD_STORE_FORMAT1 }, // STR <Rt>, [<Rn> {,#<imm>}] 188f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish { "STR" , 0x5000, 0xfe00, LOAD_STORE_FORMAT2 }, // STR <Rt>, [<Rn>, <Rm>] 189f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish { "STR" , 0x9000, 0xf800, LOAD_STORE_FORMAT4 }, // STR <Rt>, [SP, #<imm>] 190f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish { "STRB" , 0x7000, 0xf800, LOAD_STORE_FORMAT1_B }, // STRB <Rt>, [<Rn>, #<imm5>] 191f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish { "STRB" , 0x5400, 0xfe00, LOAD_STORE_FORMAT2 }, // STRB <Rt>, [<Rn>, <Rm>] 192f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish { "STRH" , 0x8000, 0xf800, LOAD_STORE_FORMAT1_H }, // STRH <Rt>, [<Rn>{,#<imm>}] 193f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish { "STRH" , 0x5200, 0xfe00, LOAD_STORE_FORMAT2 }, // STRH <Rt>, [<Rn>, <Rm>] 1946f72e28d04348ad4539679949609675b114896e1andrewfish 1956f72e28d04348ad4539679949609675b114896e1andrewfish { "SUB" , 0x1e00, 0xfe00, DATA_FORMAT2 }, 1966f72e28d04348ad4539679949609675b114896e1andrewfish { "SUB" , 0x3800, 0xf800, DATA_FORMAT3 }, 1976f72e28d04348ad4539679949609675b114896e1andrewfish { "SUB" , 0x1a00, 0xfe00, DATA_FORMAT1 }, 1986f72e28d04348ad4539679949609675b114896e1andrewfish { "SUB" , 0xb080, 0xff80, DATA_FORMAT7 }, 1996f72e28d04348ad4539679949609675b114896e1andrewfish 200f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish { "SBC" , 0x4180, 0xffc0, DATA_FORMAT5 }, 201f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish 2026f72e28d04348ad4539679949609675b114896e1andrewfish { "SWI" , 0xdf00, 0xff00, IMMED_8 }, 2036f72e28d04348ad4539679949609675b114896e1andrewfish { "SXTB", 0xb240, 0xffc0, DATA_FORMAT5 }, 2046f72e28d04348ad4539679949609675b114896e1andrewfish { "SXTH", 0xb200, 0xffc0, DATA_FORMAT5 }, 2056f72e28d04348ad4539679949609675b114896e1andrewfish { "TST" , 0x4200, 0xffc0, DATA_FORMAT5 }, 2066f72e28d04348ad4539679949609675b114896e1andrewfish { "UXTB", 0xb2c0, 0xffc0, DATA_FORMAT5 }, 207f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish { "UXTH", 0xb280, 0xffc0, DATA_FORMAT5 }, 208f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish 209f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish { "IT", 0xbf00, 0xff00, IT_BLOCK } 210b32fecd24743853164e151a84cb0e33da556cc74andrewfish 211097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish}; 212097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish 213097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfishTHUMB_INSTRUCTIONS gOpThumb2[] = { 214b32fecd24743853164e151a84cb0e33da556cc74andrewfish//Instruct OpCode OpCode Mask Addressig Mode 2153402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 2163402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "ADR", 0xf2af0000, 0xfbff8000, ADR_THUMB2 }, // ADDR <Rd>, <label> ;Needs to go before ADDW 217c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "CMN", 0xf1100f00, 0xfff08f00, CMN_THUMB2 }, // CMN <Rn>, #<const> ;Needs to go before ADD 218c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "CMN", 0xeb100f00, 0xfff08f00, ADD_IMM5_2REG }, // CMN <Rn>, <Rm> {,<shift> #<const>} 219c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "CMP", 0xf1a00f00, 0xfff08f00, CMN_THUMB2 }, // CMP <Rn>, #<const> 220c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "TEQ", 0xf0900f00, 0xfff08f00, CMN_THUMB2 }, // CMP <Rn>, #<const> 221c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "TEQ", 0xea900f00, 0xfff08f00, ADD_IMM5_2REG }, // CMN <Rn>, <Rm> {,<shift> #<const>} 222c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "TST", 0xf0100f00, 0xfff08f00, CMN_THUMB2 }, // CMP <Rn>, #<const> 223c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "TST", 0xea100f00, 0xfff08f00, ADD_IMM5_2REG }, // TST <Rn>, <Rm> {,<shift> #<const>} 224eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish 225fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "MOV", 0xf04f0000, 0xfbef8000, ADD_IMM12_1REG }, // MOV <Rd>, #<const> 226fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "MOVW", 0xf2400000, 0xfbe08000, THUMB2_IMM16 }, // MOVW <Rd>, #<const> 227fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "MOVT", 0xf2c00000, 0xfbe08000, THUMB2_IMM16 }, // MOVT <Rd>, #<const> 2283402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 229eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "ADC", 0xf1400000, 0xfbe08000, ADD_IMM12 }, // ADC{S} <Rd>, <Rn>, #<const> 230eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "ADC", 0xeb400000, 0xffe08000, ADD_IMM5 }, // ADC{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>} 231eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "ADD", 0xf1000000, 0xfbe08000, ADD_IMM12 }, // ADD{S} <Rd>, <Rn>, #<const> 232eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "ADD", 0xeb000000, 0xffe08000, ADD_IMM5 }, // ADD{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>} 233eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "ADDW", 0xf2000000, 0xfbe08000, ADD_IMM12 }, // ADDW{S} <Rd>, <Rn>, #<const> 234eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "AND", 0xf0000000, 0xfbe08000, ADD_IMM12 }, // AND{S} <Rd>, <Rn>, #<const> 235eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "AND", 0xea000000, 0xffe08000, ADD_IMM5 }, // AND{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>} 236eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "BIC", 0xf0200000, 0xfbe08000, ADD_IMM12 }, // BIC{S} <Rd>, <Rn>, #<const> 237eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "BIC", 0xea200000, 0xffe08000, ADD_IMM5 }, // BIC{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>} 238eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "EOR", 0xf0800000, 0xfbe08000, ADD_IMM12 }, // EOR{S} <Rd>, <Rn>, #<const> 239eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "EOR", 0xea800000, 0xffe08000, ADD_IMM5 }, // EOR{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>} 240eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "ORN", 0xf0600000, 0xfbe08000, ADD_IMM12 }, // ORN{S} <Rd>, <Rn>, #<const> 241eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "ORN", 0xea600000, 0xffe08000, ADD_IMM5 }, // ORN{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>} 242eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "ORR", 0xf0400000, 0xfbe08000, ADD_IMM12 }, // ORR{S} <Rd>, <Rn>, #<const> 243eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "ORR", 0xea400000, 0xffe08000, ADD_IMM5 }, // ORR{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>} 244eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "RSB", 0xf1c00000, 0xfbe08000, ADD_IMM12 }, // RSB{S} <Rd>, <Rn>, #<const> 245eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "RSB", 0xebc00000, 0xffe08000, ADD_IMM5 }, // RSB{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>} 246eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "SBC", 0xf1600000, 0xfbe08000, ADD_IMM12 }, // SBC{S} <Rd>, <Rn>, #<const> 247eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "SBC", 0xeb600000, 0xffe08000, ADD_IMM5 }, // SBC{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>} 248eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "SUB", 0xf1a00000, 0xfbe08000, ADD_IMM12 }, // SUB{S} <Rd>, <Rn>, #<const> 249eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish { "SUB", 0xeba00000, 0xffe08000, ADD_IMM5 }, // SUB{S} <Rd>, <Rn>, <Rm> {,<shift> #<const>} 250eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish 251c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "ASR", 0xea4f0020, 0xffef8030, ASR_IMM5 }, // ARS <Rd>, <Rm> #<const>} imm3:imm2 2523402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "ASR", 0xfa40f000, 0xffe0f0f0, ASR_3REG }, // ARS <Rd>, <Rn>, <Rm> 253c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "LSR", 0xea4f0010, 0xffef8030, ASR_IMM5 }, // LSR <Rd>, <Rm> #<const>} imm3:imm2 2543402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "LSR", 0xfa20f000, 0xffe0f0f0, ASR_3REG }, // LSR <Rd>, <Rn>, <Rm> 255c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "ROR", 0xea4f0030, 0xffef8030, ASR_IMM5 }, // ROR <Rd>, <Rm> #<const>} imm3:imm2 2563402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "ROR", 0xfa60f000, 0xffe0f0f0, ASR_3REG }, // ROR <Rd>, <Rn>, <Rm> 257c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 258c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "BFC", 0xf36f0000, 0xffff8010, BFC_THUMB2 }, // BFC <Rd>, #<lsb>, #<width> 259c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "BIC", 0xf3600000, 0xfff08010, BFC_THUMB2 }, // BIC <Rn>, <Rd>, #<lsb>, #<width> 260c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "SBFX", 0xf3400000, 0xfff08010, BFC_THUMB2 }, // SBFX <Rn>, <Rd>, #<lsb>, #<width> 261c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "UBFX", 0xf3c00000, 0xfff08010, BFC_THUMB2 }, // UBFX <Rn>, <Rd>, #<lsb>, #<width> 262c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 263c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "CPD", 0xee000000, 0xff000010, CPD_THUMB2 }, // CPD <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> 264c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "CPD2", 0xfe000000, 0xff000010, CPD_THUMB2 }, // CPD <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> 265c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 266fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "MRC", 0xee100000, 0xff100000, MRC_THUMB2 }, // MRC <coproc>,<opc1>,<Rt>,<CRn>,<CRm>,<opc2> 267fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "MRC2", 0xfe100000, 0xff100000, MRC_THUMB2 }, // MRC2 <coproc>,<opc1>,<Rt>,<CRn>,<CRm>,<opc2> 268fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "MRRC", 0xec500000, 0xfff00000, MRRC_THUMB2 }, // MRRC <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> 269fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "MRRC2", 0xfc500000, 0xfff00000, MRRC_THUMB2 }, // MRR2 <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> 270fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish 271fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "MRS", 0xf3ef8000, 0xfffff0ff, THUMB2_MRS }, // MRS <Rd>, CPSR 272fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "MSR", 0xf3808000, 0xfff0fcff, THUMB2_MSR }, // MSR CPSR_fs, <Rn> 273fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish 274c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "CLREX", 0xf3bf8f2f, 0xfffffff, THUMB2_NO_ARGS }, // CLREX 275c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 276c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "CLZ", 0xfab0f080, 0xfff0f0f0, THUMB2_2REGS }, // CLZ <Rd>,<Rm> 277c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "MOV", 0xec4f0000, 0xfff0f0f0, THUMB2_2REGS }, // MOV <Rd>,<Rm> 278c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "MOVS", 0xec5f0000, 0xfff0f0f0, THUMB2_2REGS }, // MOVS <Rd>,<Rm> 279c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "RBIT", 0xfb90f0a0, 0xfff0f0f0, THUMB2_2REGS }, // RBIT <Rd>,<Rm> 280c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "REV", 0xfb90f080, 0xfff0f0f0, THUMB2_2REGS }, // REV <Rd>,<Rm> 281c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "REV16", 0xfa90f090, 0xfff0f0f0, THUMB2_2REGS }, // REV16 <Rd>,<Rm> 282c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "REVSH", 0xfa90f0b0, 0xfff0f0f0, THUMB2_2REGS }, // REVSH <Rd>,<Rm> 283c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "RRX", 0xea4f0030, 0xfffff0f0, THUMB2_2REGS }, // RRX <Rd>,<Rm> 284c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "RRXS", 0xea5f0030, 0xfffff0f0, THUMB2_2REGS }, // RRXS <Rd>,<Rm> 285c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 286c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "MLA", 0xfb000000, 0xfff000f0, THUMB2_4REGS }, // MLA <Rd>, <Rn>, <Rm>, <Ra> 287c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "MLS", 0xfb000010, 0xfff000f0, THUMB2_4REGS }, // MLA <Rd>, <Rn>, <Rm>, <Ra> 288c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 289c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 290c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "SMLABB", 0xfb100000, 0xfff000f0, THUMB2_4REGS }, // SMLABB <Rd>, <Rn>, <Rm>, <Ra> 291c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "SMLABT", 0xfb100010, 0xfff000f0, THUMB2_4REGS }, // SMLABT <Rd>, <Rn>, <Rm>, <Ra> 292c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "SMLABB", 0xfb100020, 0xfff000f0, THUMB2_4REGS }, // SMLATB <Rd>, <Rn>, <Rm>, <Ra> 293c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish { "SMLATT", 0xfb100030, 0xfff000f0, THUMB2_4REGS }, // SMLATT <Rd>, <Rn>, <Rm>, <Ra> 294fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "SMLAWB", 0xfb300000, 0xfff000f0, THUMB2_4REGS }, // SMLAWB <Rd>, <Rn>, <Rm>, <Ra> 295fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "SMLAWT", 0xfb300010, 0xfff000f0, THUMB2_4REGS }, // SMLAWT <Rd>, <Rn>, <Rm>, <Ra> 296fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "SMLSD", 0xfb400000, 0xfff000f0, THUMB2_4REGS }, // SMLSD <Rd>, <Rn>, <Rm>, <Ra> 297fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "SMLSDX", 0xfb400010, 0xfff000f0, THUMB2_4REGS }, // SMLSDX <Rd>, <Rn>, <Rm>, <Ra> 298fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "SMMLA", 0xfb500000, 0xfff000f0, THUMB2_4REGS }, // SMMLA <Rd>, <Rn>, <Rm>, <Ra> 299fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "SMMLAR", 0xfb500010, 0xfff000f0, THUMB2_4REGS }, // SMMLAR <Rd>, <Rn>, <Rm>, <Ra> 300fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "SMMLS", 0xfb600000, 0xfff000f0, THUMB2_4REGS }, // SMMLS <Rd>, <Rn>, <Rm>, <Ra> 301fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "SMMLSR", 0xfb600010, 0xfff000f0, THUMB2_4REGS }, // SMMLSR <Rd>, <Rn>, <Rm>, <Ra> 302fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "USADA8", 0xfb700000, 0xfff000f0, THUMB2_4REGS }, // USADA8 <Rd>, <Rn>, <Rm>, <Ra> 303fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "SMLAD", 0xfb200000, 0xfff000f0, THUMB2_4REGS }, // SMLAD <Rd>, <Rn>, <Rm>, <Ra> 304fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish { "SMLADX", 0xfb200010, 0xfff000f0, THUMB2_4REGS }, // SMLADX <Rd>, <Rn>, <Rm>, <Ra> 305c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 306c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 307b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "B", 0xf0008000, 0xf800d000, B_T3 }, // B<c> <label> 308b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "B", 0xf0009000, 0xf800d000, B_T4 }, // B<c> <label> 309b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "BL", 0xf000d000, 0xf800d000, B_T4 }, // BL<c> <label> 310b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "BLX", 0xf000c000, 0xf800d000, BL_T2 }, // BLX<c> <label> 311b32fecd24743853164e151a84cb0e33da556cc74andrewfish 312b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "POP", 0xe8bd0000, 0xffff2000, POP_T2 }, // POP <registers> 313b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "POP", 0xf85d0b04, 0xffff0fff, POP_T3 }, // POP <register> 314b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "PUSH", 0xe8ad0000, 0xffffa000, POP_T2 }, // PUSH <registers> 315b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "PUSH", 0xf84d0d04, 0xffff0fff, POP_T3 }, // PUSH <register> 316b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "STM" , 0xe8800000, 0xffd0a000, STM_FORMAT }, // STM <Rn>{!},<registers> 317b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "STMDB", 0xe9800000, 0xffd0a000, STM_FORMAT }, // STMDB <Rn>{!},<registers> 318b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "LDM" , 0xe8900000, 0xffd02000, STM_FORMAT }, // LDM <Rn>{!},<registers> 319b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "LDMDB", 0xe9100000, 0xffd02000, STM_FORMAT }, // LDMDB <Rn>{!},<registers> 3203402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 321b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "LDR", 0xf8d00000, 0xfff00000, LDM_REG_IMM12 }, // LDR <rt>, [<rn>, {, #<imm12>]} 322b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "LDRB", 0xf8900000, 0xfff00000, LDM_REG_IMM12 }, // LDRB <rt>, [<rn>, {, #<imm12>]} 323b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "LDRH", 0xf8b00000, 0xfff00000, LDM_REG_IMM12 }, // LDRH <rt>, [<rn>, {, #<imm12>]} 324b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "LDRSB", 0xf9900000, 0xfff00000, LDM_REG_IMM12 }, // LDRSB <rt>, [<rn>, {, #<imm12>]} 325b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "LDRSH", 0xf9b00000, 0xfff00000, LDM_REG_IMM12 }, // LDRSH <rt>, [<rn>, {, #<imm12>]} 326b32fecd24743853164e151a84cb0e33da556cc74andrewfish 3273402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "LDR", 0xf85f0000, 0xff7f0000, LDM_REG_IMM12_SIGNED }, // LDR <Rt>, <label> 3283402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "LDRB", 0xf81f0000, 0xff7f0000, LDM_REG_IMM12_SIGNED }, // LDRB <Rt>, <label> 3293402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "LDRH", 0xf83f0000, 0xff7f0000, LDM_REG_IMM12_SIGNED }, // LDRH <Rt>, <label> 3303402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "LDRSB", 0xf91f0000, 0xff7f0000, LDM_REG_IMM12_SIGNED }, // LDRSB <Rt>, <label> 3313402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "LDRSH", 0xf93f0000, 0xff7f0000, LDM_REG_IMM12_SIGNED }, // LDRSB <Rt>, <label> 3323402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 333b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "LDR", 0xf8500000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // LDR <rt>, [<rn>, <rm> {, LSL #<imm2>]} 334b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "LDRB", 0xf8100000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // LDRB <rt>, [<rn>, <rm> {, LSL #<imm2>]} 335b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "LDRH", 0xf8300000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // LDRH <rt>, [<rn>, <rm> {, LSL #<imm2>]} 336b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "LDRSB", 0xf9100000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // LDRSB <rt>, [<rn>, <rm> {, LSL #<imm2>]} 337b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "LDRSH", 0xf9300000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // LDRSH <rt>, [<rn>, <rm> {, LSL #<imm2>]} 338b32fecd24743853164e151a84cb0e33da556cc74andrewfish 339b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "LDR", 0xf8500800, 0xfff00800, LDM_REG_IMM8 }, // LDR <rt>, [<rn>, {, #<imm8>]} 340b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "LDRBT", 0xf8100e00, 0xfff00f00, LDM_REG_IMM8 }, // LDRBT <rt>, [<rn>, {, #<imm8>]} 341b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "LDRHT", 0xf8300e00, 0xfff00f00, LDM_REG_IMM8 }, // LDRHT <rt>, [<rn>, {, #<imm8>]} 3423402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "LDRSB", 0xf9100800, 0xfff00800, LDM_REG_IMM8 }, // LDRHT <rt>, [<rn>, {, #<imm8>]} {!} form? 3433402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "LDRSBT",0xf9100e00, 0xfff00f00, LDM_REG_IMM8 }, // LDRHBT <rt>, [<rn>, {, #<imm8>]} {!} form? 3443402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "LDRSH" ,0xf9300800, 0xfff00800, LDM_REG_IMM8 }, // LDRSH <rt>, [<rn>, {, #<imm8>]} 3453402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "LDRSHT",0xf9300e00, 0xfff00f00, LDM_REG_IMM8 }, // LDRSHT <rt>, [<rn>, {, #<imm8>]} 3463402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "LDRT", 0xf8500e00, 0xfff00f00, LDM_REG_IMM8 }, // LDRT <rt>, [<rn>, {, #<imm8>]} 347b32fecd24743853164e151a84cb0e33da556cc74andrewfish 348b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "LDRD", 0xe8500000, 0xfe500000, LDRD_REG_IMM8_SIGNED }, // LDRD <rt>, <rt2>, [<rn>, {, #<imm8>]}{!} 349b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "LDRD", 0xe8500000, 0xfe500000, LDRD_REG_IMM8 }, // LDRD <rt>, <rt2>, <label> 3503402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 3513402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "LDREX", 0xe8500f00, 0xfff00f00, LDM_REG_IMM8 }, // LDREX <Rt>, [Rn, {#imm8}]] 3523402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "LDREXB", 0xe8d00f4f, 0xfff00fff, LDREXB }, // LDREXB <Rt>, [<Rn>] 3533402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "LDREXH", 0xe8d00f5f, 0xfff00fff, LDREXB }, // LDREXH <Rt>, [<Rn>] 3543402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 3553402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "LDREXD", 0xe8d00f4f, 0xfff00fff, LDREXD }, // LDREXD <Rt>, <Rt2>, [<Rn>] 3563402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 3573402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "STR", 0xf8c00000, 0xfff00000, LDM_REG_IMM12 }, // STR <rt>, [<rn>, {, #<imm12>]} 358b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "STRB", 0xf8800000, 0xfff00000, LDM_REG_IMM12 }, // STRB <rt>, [<rn>, {, #<imm12>]} 359b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "STRH", 0xf8a00000, 0xfff00000, LDM_REG_IMM12 }, // STRH <rt>, [<rn>, {, #<imm12>]} 3603402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 361b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "STR", 0xf8400000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // STR <rt>, [<rn>, <rm> {, LSL #<imm2>]} 362b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "STRB", 0xf8000000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // STRB <rt>, [<rn>, <rm> {, LSL #<imm2>]} 363b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "STRH", 0xf8200000, 0xfff00fc0, LDM_REG_INDIRECT_LSL }, // STRH <rt>, [<rn>, <rm> {, LSL #<imm2>]} 3646f72e28d04348ad4539679949609675b114896e1andrewfish 365b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "STR", 0xf8400800, 0xfff00800, LDM_REG_IMM8 }, // STR <rt>, [<rn>, {, #<imm8>]} 366b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "STRH", 0xf8200800, 0xfff00800, LDM_REG_IMM8 }, // STRH <rt>, [<rn>, {, #<imm8>]} 367b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "STRBT", 0xf8000e00, 0xfff00f00, LDM_REG_IMM8 }, // STRBT <rt>, [<rn>, {, #<imm8>]} 368b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "STRHT", 0xf8200e00, 0xfff00f00, LDM_REG_IMM8 }, // STRHT <rt>, [<rn>, {, #<imm8>]} 3693402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "STRT", 0xf8400e00, 0xfff00f00, LDM_REG_IMM8 }, // STRT <rt>, [<rn>, {, #<imm8>]} 3706f72e28d04348ad4539679949609675b114896e1andrewfish 371b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "STRD", 0xe8400000, 0xfe500000, LDRD_REG_IMM8_SIGNED }, // STRD <rt>, <rt2>, [<rn>, {, #<imm8>]}{!} 3726f72e28d04348ad4539679949609675b114896e1andrewfish 3733402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "STREX", 0xe8400f00, 0xfff00f00, LDM_REG_IMM8 }, // STREX <Rt>, [Rn, {#imm8}]] 3743402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "STREXB", 0xe8c00f4f, 0xfff00fff, LDREXB }, // STREXB <Rd>, <Rt>, [<Rn>] 3753402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "STREXH", 0xe8c00f5f, 0xfff00fff, LDREXB }, // STREXH <Rd>, <Rt>, [<Rn>] 3763402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 3773402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron { "STREXD", 0xe8d00f4f, 0xfff00fff, LDREXD }, // STREXD <Rd>, <Rt>, <Rt2>, [<Rn>] 3786f72e28d04348ad4539679949609675b114896e1andrewfish 379b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "SRSDB", 0xe80dc000, 0xffdffff0, SRS_FORMAT }, // SRSDB<c> SP{!},#<mode> 380b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "SRS" , 0xe98dc000, 0xffdffff0, SRS_FORMAT }, // SRS{IA}<c> SP{!},#<mode> 381b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "RFEDB", 0xe810c000, 0xffd0ffff, RFE_FORMAT }, // RFEDB<c> <Rn>{!} 382b32fecd24743853164e151a84cb0e33da556cc74andrewfish { "RFE" , 0xe990c000, 0xffd0ffff, RFE_FORMAT } // RFE{IA}<c> <Rn>{!} 3837c34497d5de78120879d44ebf4b5e10004894873andrewfish}; 3846f72e28d04348ad4539679949609675b114896e1andrewfish 385eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfishCHAR8 *gShiftType[] = { 386eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish "LSL", 387eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish "LSR", 388eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish "ASR", 389eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish "ROR" 390eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish}; 391eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish 3926f72e28d04348ad4539679949609675b114896e1andrewfishCHAR8 mThumbMregListStr[4*15 + 1]; 3936f72e28d04348ad4539679949609675b114896e1andrewfish 3946f72e28d04348ad4539679949609675b114896e1andrewfishCHAR8 * 3956f72e28d04348ad4539679949609675b114896e1andrewfishThumbMRegList ( 3967c34497d5de78120879d44ebf4b5e10004894873andrewfish UINT32 RegBitMask 3976f72e28d04348ad4539679949609675b114896e1andrewfish ) 3986f72e28d04348ad4539679949609675b114896e1andrewfish{ 3996f72e28d04348ad4539679949609675b114896e1andrewfish UINTN Index, Start, End; 4006f72e28d04348ad4539679949609675b114896e1andrewfish BOOLEAN First; 4013402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 402f00ace96f3c8e1dbfd0cd0d882b0c98cfbde37dcLaszlo Ersek mThumbMregListStr[0] = '\0'; 403f00ace96f3c8e1dbfd0cd0d882b0c98cfbde37dcLaszlo Ersek AsciiStrCatS (mThumbMregListStr, sizeof mThumbMregListStr, "{"); 4043402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 4057c34497d5de78120879d44ebf4b5e10004894873andrewfish for (Index = 0, First = TRUE; Index <= 15; Index++) { 4067c34497d5de78120879d44ebf4b5e10004894873andrewfish if ((RegBitMask & (1 << Index)) != 0) { 4076f72e28d04348ad4539679949609675b114896e1andrewfish Start = End = Index; 4087c34497d5de78120879d44ebf4b5e10004894873andrewfish for (Index++; ((RegBitMask & (1 << Index)) != 0) && (Index <= 9); Index++) { 4096f72e28d04348ad4539679949609675b114896e1andrewfish End = Index; 4106f72e28d04348ad4539679949609675b114896e1andrewfish } 4113402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 4126f72e28d04348ad4539679949609675b114896e1andrewfish if (!First) { 413f00ace96f3c8e1dbfd0cd0d882b0c98cfbde37dcLaszlo Ersek AsciiStrCatS (mThumbMregListStr, sizeof mThumbMregListStr, ","); 4146f72e28d04348ad4539679949609675b114896e1andrewfish } else { 4156f72e28d04348ad4539679949609675b114896e1andrewfish First = FALSE; 4166f72e28d04348ad4539679949609675b114896e1andrewfish } 4173402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 4186f72e28d04348ad4539679949609675b114896e1andrewfish if (Start == End) { 419f00ace96f3c8e1dbfd0cd0d882b0c98cfbde37dcLaszlo Ersek AsciiStrCatS (mThumbMregListStr, sizeof mThumbMregListStr, gReg[Start]); 4206f72e28d04348ad4539679949609675b114896e1andrewfish } else { 421f00ace96f3c8e1dbfd0cd0d882b0c98cfbde37dcLaszlo Ersek AsciiStrCatS (mThumbMregListStr, sizeof mThumbMregListStr, gReg[Start]); 422f00ace96f3c8e1dbfd0cd0d882b0c98cfbde37dcLaszlo Ersek AsciiStrCatS (mThumbMregListStr, sizeof mThumbMregListStr, "-"); 423f00ace96f3c8e1dbfd0cd0d882b0c98cfbde37dcLaszlo Ersek AsciiStrCatS (mThumbMregListStr, sizeof mThumbMregListStr, gReg[End]); 4246f72e28d04348ad4539679949609675b114896e1andrewfish } 4256f72e28d04348ad4539679949609675b114896e1andrewfish } 4266f72e28d04348ad4539679949609675b114896e1andrewfish } 4276f72e28d04348ad4539679949609675b114896e1andrewfish if (First) { 428f00ace96f3c8e1dbfd0cd0d882b0c98cfbde37dcLaszlo Ersek AsciiStrCatS (mThumbMregListStr, sizeof mThumbMregListStr, "ERROR"); 4296f72e28d04348ad4539679949609675b114896e1andrewfish } 430f00ace96f3c8e1dbfd0cd0d882b0c98cfbde37dcLaszlo Ersek AsciiStrCatS (mThumbMregListStr, sizeof mThumbMregListStr, "}"); 4313402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 4326f72e28d04348ad4539679949609675b114896e1andrewfish // BugBug: Make caller pass in buffer it is cleaner 4336f72e28d04348ad4539679949609675b114896e1andrewfish return mThumbMregListStr; 4346f72e28d04348ad4539679949609675b114896e1andrewfish} 4356f72e28d04348ad4539679949609675b114896e1andrewfish 4366f72e28d04348ad4539679949609675b114896e1andrewfishUINT32 4377c34497d5de78120879d44ebf4b5e10004894873andrewfishSignExtend32 ( 4387c34497d5de78120879d44ebf4b5e10004894873andrewfish IN UINT32 Data, 4397c34497d5de78120879d44ebf4b5e10004894873andrewfish IN UINT32 TopBit 4406f72e28d04348ad4539679949609675b114896e1andrewfish ) 4416f72e28d04348ad4539679949609675b114896e1andrewfish{ 4427c34497d5de78120879d44ebf4b5e10004894873andrewfish if (((Data & TopBit) == 0) || (TopBit == BIT31)) { 4437c34497d5de78120879d44ebf4b5e10004894873andrewfish return Data; 4447c34497d5de78120879d44ebf4b5e10004894873andrewfish } 4453402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 4467c34497d5de78120879d44ebf4b5e10004894873andrewfish do { 4477c34497d5de78120879d44ebf4b5e10004894873andrewfish TopBit <<= 1; 4483402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Data |= TopBit; 4497c34497d5de78120879d44ebf4b5e10004894873andrewfish } while ((TopBit & BIT31) != BIT31); 4507c34497d5de78120879d44ebf4b5e10004894873andrewfish 4517c34497d5de78120879d44ebf4b5e10004894873andrewfish return Data; 4526f72e28d04348ad4539679949609675b114896e1andrewfish} 4536f72e28d04348ad4539679949609675b114896e1andrewfish 454eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish// 4553402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron// Some instructions specify the PC is always considered aligned 456eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish// The PC is after the instruction that is excuting. So you pass 457eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish// in the instruction address and you get back the aligned answer 458eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish// 459c639c2def9f9541a8dce49546da0daf11153e2aaandrewfishUINT32 460eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfishPCAlign4 ( 461eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish IN UINT32 Data 462eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish ) 463eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish{ 464eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish return (Data + 4) & 0xfffffffc; 465eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish} 466eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish 4676f72e28d04348ad4539679949609675b114896e1andrewfish/** 4683402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to 4693402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron point to next instructin. 4703402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 4713402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron We cheat and only decode instructions that access 4726f72e28d04348ad4539679949609675b114896e1andrewfish memory. If the instruction is not found we dump the instruction in hex. 4733402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 4743402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron @param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble. 475097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish @param Buf Buffer to sprintf disassembly into. 4763402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron @param Size Size of Buf in bytes. 477f9f937d243c8c9615119be2f2b35821e7de80925andrewfish @param Extended TRUE dump hex for instruction too. 4783402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 4796f72e28d04348ad4539679949609675b114896e1andrewfish**/ 4806f72e28d04348ad4539679949609675b114896e1andrewfishVOID 4816f72e28d04348ad4539679949609675b114896e1andrewfishDisassembleThumbInstruction ( 482097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish IN UINT16 **OpCodePtrPtr, 4836f72e28d04348ad4539679949609675b114896e1andrewfish OUT CHAR8 *Buf, 484f9f937d243c8c9615119be2f2b35821e7de80925andrewfish OUT UINTN Size, 485f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish OUT UINT32 *ItBlock, 486f9f937d243c8c9615119be2f2b35821e7de80925andrewfish IN BOOLEAN Extended 4876f72e28d04348ad4539679949609675b114896e1andrewfish ) 4886f72e28d04348ad4539679949609675b114896e1andrewfish{ 489097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish UINT16 *OpCodePtr; 490097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish UINT16 OpCode; 4917c34497d5de78120879d44ebf4b5e10004894873andrewfish UINT32 OpCode32; 4926f72e28d04348ad4539679949609675b114896e1andrewfish UINT32 Index; 4936f72e28d04348ad4539679949609675b114896e1andrewfish UINT32 Offset; 494b32fecd24743853164e151a84cb0e33da556cc74andrewfish UINT16 Rd, Rn, Rm, Rt, Rt2; 4956f72e28d04348ad4539679949609675b114896e1andrewfish BOOLEAN H1, H2, imod; 4962a9f433bc9d885511869524a7657787ed1ab909boliviermartin //BOOLEAN ItFlag; 497c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish UINT32 PC, Target, msbit, lsbit; 4987c34497d5de78120879d44ebf4b5e10004894873andrewfish CHAR8 *Cond; 499b32fecd24743853164e151a84cb0e33da556cc74andrewfish BOOLEAN S, J1, J2, P, U, W; 5003402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron UINT32 coproc, opc1, opc2, CRd, CRn, CRm; 501f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish UINT32 Mask; 5026f72e28d04348ad4539679949609675b114896e1andrewfish 503097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish OpCodePtr = *OpCodePtrPtr; 504097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish OpCode = **OpCodePtrPtr; 5053402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 506097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish // Thumb2 is a stream of 16-bit instructions not a 32-bit instruction. 5077c34497d5de78120879d44ebf4b5e10004894873andrewfish OpCode32 = (((UINT32)OpCode) << 16) | *(OpCodePtr + 1); 508097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish 5096f72e28d04348ad4539679949609675b114896e1andrewfish // These register names match branch form, but not others 5106f72e28d04348ad4539679949609675b114896e1andrewfish Rd = OpCode & 0x7; 5116f72e28d04348ad4539679949609675b114896e1andrewfish Rn = (OpCode >> 3) & 0x7; 5126f72e28d04348ad4539679949609675b114896e1andrewfish Rm = (OpCode >> 6) & 0x7; 5136f72e28d04348ad4539679949609675b114896e1andrewfish H1 = (OpCode & BIT7) != 0; 5146f72e28d04348ad4539679949609675b114896e1andrewfish H2 = (OpCode & BIT6) != 0; 5156f72e28d04348ad4539679949609675b114896e1andrewfish imod = (OpCode & BIT4) != 0; 5167c34497d5de78120879d44ebf4b5e10004894873andrewfish PC = (UINT32)(UINTN)OpCodePtr; 5176f72e28d04348ad4539679949609675b114896e1andrewfish 518097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish // Increment by the minimum instruction size, Thumb2 could be bigger 519097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish *OpCodePtrPtr += 1; 5203402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 521f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish // Manage IT Block ItFlag TRUE means we are in an IT block 5222a9f433bc9d885511869524a7657787ed1ab909boliviermartin /*if (*ItBlock != 0) { 523f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish ItFlag = TRUE; 524f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish *ItBlock -= 1; 525f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish } else { 526f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish ItFlag = FALSE; 5272a9f433bc9d885511869524a7657787ed1ab909boliviermartin }*/ 528f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish 529097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish for (Index = 0; Index < sizeof (gOpThumb)/sizeof (THUMB_INSTRUCTIONS); Index++) { 530097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish if ((OpCode & gOpThumb[Index].Mask) == gOpThumb[Index].OpCode) { 531f9f937d243c8c9615119be2f2b35821e7de80925andrewfish if (Extended) { 5323402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Offset = AsciiSPrint (Buf, Size, "0x%04x %-6a", OpCode, gOpThumb[Index].Start); 533f9f937d243c8c9615119be2f2b35821e7de80925andrewfish } else { 5343402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Offset = AsciiSPrint (Buf, Size, "%-6a", gOpThumb[Index].Start); 535f9f937d243c8c9615119be2f2b35821e7de80925andrewfish } 536097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish switch (gOpThumb[Index].AddressMode) { 5376f72e28d04348ad4539679949609675b114896e1andrewfish case LOAD_STORE_FORMAT1: 5386f72e28d04348ad4539679949609675b114896e1andrewfish // A6.5.1 <Rd>, [<Rn>, #<5_bit_offset>] 5393402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, Rn, (OpCode >> 4) & 0x7c); 5407c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 541eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish case LOAD_STORE_FORMAT1_H: 542eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish // A6.5.1 <Rd>, [<Rn>, #<5_bit_offset>] 5433402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, Rn, (OpCode >> 5) & 0x3e); 544eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish return; 545eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish case LOAD_STORE_FORMAT1_B: 546eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish // A6.5.1 <Rd>, [<Rn>, #<5_bit_offset>] 5473402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, Rn, (OpCode >> 6) & 0x1f); 548eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish return; 549eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish 5506f72e28d04348ad4539679949609675b114896e1andrewfish case LOAD_STORE_FORMAT2: 5516f72e28d04348ad4539679949609675b114896e1andrewfish // A6.5.1 <Rd>, [<Rn>, <Rm>] 5523402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d, r%d]", Rd, Rn, Rm); 5537c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 5546f72e28d04348ad4539679949609675b114896e1andrewfish case LOAD_STORE_FORMAT3: 5556f72e28d04348ad4539679949609675b114896e1andrewfish // A6.5.1 <Rd>, [PC, #<8_bit_offset>] 5567c34497d5de78120879d44ebf4b5e10004894873andrewfish Target = (OpCode & 0xff) << 2; 5573402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [pc, #0x%x] ;0x%08x", (OpCode >> 8) & 7, Target, PCAlign4 (PC) + Target); 5587c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 5596f72e28d04348ad4539679949609675b114896e1andrewfish case LOAD_STORE_FORMAT4: 5607c34497d5de78120879d44ebf4b5e10004894873andrewfish // Rt, [SP, #imm8] 5617c34497d5de78120879d44ebf4b5e10004894873andrewfish Target = (OpCode & 0xff) << 2; 5623402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [sp, #0x%x]", (OpCode >> 8) & 7, Target); 5637c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 5643402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 5656f72e28d04348ad4539679949609675b114896e1andrewfish case LOAD_STORE_MULTIPLE_FORMAT1: 5667c34497d5de78120879d44ebf4b5e10004894873andrewfish // <Rn>!, {r0-r7} 5673402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " r%d!, %a", (OpCode >> 8) & 7, ThumbMRegList (OpCode & 0xff)); 5687c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 5693402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 5707c34497d5de78120879d44ebf4b5e10004894873andrewfish case POP_FORMAT: 5717c34497d5de78120879d44ebf4b5e10004894873andrewfish // POP {r0-r7,pc} 5723402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a", ThumbMRegList ((OpCode & 0xff) | ((OpCode & BIT8) == BIT8 ? BIT15 : 0))); 5737c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 5747c34497d5de78120879d44ebf4b5e10004894873andrewfish 5757c34497d5de78120879d44ebf4b5e10004894873andrewfish case PUSH_FORMAT: 5767c34497d5de78120879d44ebf4b5e10004894873andrewfish // PUSH {r0-r7,lr} 5773402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a", ThumbMRegList ((OpCode & 0xff) | ((OpCode & BIT8) == BIT8 ? BIT14 : 0))); 5787c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 5797c34497d5de78120879d44ebf4b5e10004894873andrewfish 5803402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 5816f72e28d04348ad4539679949609675b114896e1andrewfish case IMMED_8: 5826f72e28d04348ad4539679949609675b114896e1andrewfish // A6.7 <immed_8> 5833402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%x", OpCode & 0xff); 5847c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 5856f72e28d04348ad4539679949609675b114896e1andrewfish 5866f72e28d04348ad4539679949609675b114896e1andrewfish case CONDITIONAL_BRANCH: 5876f72e28d04348ad4539679949609675b114896e1andrewfish // A6.3.1 B<cond> <target_address> 5887c34497d5de78120879d44ebf4b5e10004894873andrewfish // Patch in the condition code. A little hack but based on "%-6a" 5897c34497d5de78120879d44ebf4b5e10004894873andrewfish Cond = gCondition[(OpCode >> 8) & 0xf]; 5907c34497d5de78120879d44ebf4b5e10004894873andrewfish Buf[Offset-5] = *Cond++; 5917c34497d5de78120879d44ebf4b5e10004894873andrewfish Buf[Offset-4] = *Cond; 5923402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%04x", PC + 4 + SignExtend32 ((OpCode & 0xff) << 1, BIT8)); 5937c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 5946f72e28d04348ad4539679949609675b114896e1andrewfish case UNCONDITIONAL_BRANCH_SHORT: 5956f72e28d04348ad4539679949609675b114896e1andrewfish // A6.3.2 B <target_address> 5963402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%04x", PC + 4 + SignExtend32 ((OpCode & 0x3ff) << 1, BIT11)); 5977c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 5983402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 5996f72e28d04348ad4539679949609675b114896e1andrewfish case BRANCH_EXCHANGE: 6006f72e28d04348ad4539679949609675b114896e1andrewfish // A6.3.3 BX|BLX <Rm> 6013402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a", gReg[Rn | (H2 ? 8:0)]); 6027c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 6036f72e28d04348ad4539679949609675b114896e1andrewfish 6046f72e28d04348ad4539679949609675b114896e1andrewfish case DATA_FORMAT1: 6056f72e28d04348ad4539679949609675b114896e1andrewfish // A6.4.3 <Rd>, <Rn>, <Rm> 6063402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, r%d", Rd, Rn, Rm); 6077c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 6086f72e28d04348ad4539679949609675b114896e1andrewfish case DATA_FORMAT2: 6096f72e28d04348ad4539679949609675b114896e1andrewfish // A6.4.3 <Rd>, <Rn>, #3_bit_immed 6103402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", Rd, Rn, Rm); 6117c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 6126f72e28d04348ad4539679949609675b114896e1andrewfish case DATA_FORMAT3: 6137c34497d5de78120879d44ebf4b5e10004894873andrewfish // A6.4.3 <Rd>|<Rn>, #imm8 6143402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, #0x%x", (OpCode >> 8) & 7, OpCode & 0xff); 6157c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 6166f72e28d04348ad4539679949609675b114896e1andrewfish case DATA_FORMAT4: 6176f72e28d04348ad4539679949609675b114896e1andrewfish // A6.4.3 <Rd>|<Rm>, #immed_5 6183402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", Rn, Rd, (OpCode >> 6) & 0x1f); 6197c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 6206f72e28d04348ad4539679949609675b114896e1andrewfish case DATA_FORMAT5: 6216f72e28d04348ad4539679949609675b114896e1andrewfish // A6.4.3 <Rd>|<Rm>, <Rm>|<Rs> 6223402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d", Rd, Rn); 6237c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 6246f72e28d04348ad4539679949609675b114896e1andrewfish case DATA_FORMAT6_SP: 6256f72e28d04348ad4539679949609675b114896e1andrewfish // A6.4.3 <Rd>, <reg>, #<8_Bit_immed> 6263402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, sp, 0x%x", (OpCode >> 8) & 7, (OpCode & 0xff) << 2); 6277c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 6286f72e28d04348ad4539679949609675b114896e1andrewfish case DATA_FORMAT6_PC: 6296f72e28d04348ad4539679949609675b114896e1andrewfish // A6.4.3 <Rd>, <reg>, #<8_Bit_immed> 6303402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, pc, 0x%x", (OpCode >> 8) & 7, (OpCode & 0xff) << 2); 6317c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 6326f72e28d04348ad4539679949609675b114896e1andrewfish case DATA_FORMAT7: 6336f72e28d04348ad4539679949609675b114896e1andrewfish // A6.4.3 SP, SP, #<7_Bit_immed> 6343402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " sp, sp, 0x%x", (OpCode & 0x7f)*4); 6357c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 6366f72e28d04348ad4539679949609675b114896e1andrewfish case DATA_FORMAT8: 6376f72e28d04348ad4539679949609675b114896e1andrewfish // A6.4.3 <Rd>|<Rn>, <Rm> 6383402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rd | (H1 ? 8:0)], gReg[Rn | (H2 ? 8:0)]); 6397c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 6403402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 6416f72e28d04348ad4539679949609675b114896e1andrewfish case CPS_FORMAT: 6426f72e28d04348ad4539679949609675b114896e1andrewfish // A7.1.24 6433402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, "%a %a%a%a", imod ? "ID":"IE", ((OpCode & BIT2) == 0) ? "":"a", ((OpCode & BIT1) == 0) ? "":"i", ((OpCode & BIT0) == 0) ? "":"f"); 6447c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 6456f72e28d04348ad4539679949609675b114896e1andrewfish 6466f72e28d04348ad4539679949609675b114896e1andrewfish case ENDIAN_FORMAT: 6476f72e28d04348ad4539679949609675b114896e1andrewfish // A7.1.24 6483402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a", (OpCode & BIT3) == 0 ? "LE":"BE"); 6497c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 650b32fecd24743853164e151a84cb0e33da556cc74andrewfish 651b32fecd24743853164e151a84cb0e33da556cc74andrewfish case DATA_CBZ: 652b32fecd24743853164e151a84cb0e33da556cc74andrewfish // CB{N}Z <Rn>, <Lable> 653b32fecd24743853164e151a84cb0e33da556cc74andrewfish Target = ((OpCode >> 2) & 0x3e) | (((OpCode & BIT9) == BIT9) ? BIT6 : 0); 6543402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %08x", gReg[Rd], PC + 4 + Target); 655b32fecd24743853164e151a84cb0e33da556cc74andrewfish return; 656b32fecd24743853164e151a84cb0e33da556cc74andrewfish 657b32fecd24743853164e151a84cb0e33da556cc74andrewfish case ADR_FORMAT: 658b32fecd24743853164e151a84cb0e33da556cc74andrewfish // ADR <Rd>, <Label> 659b32fecd24743853164e151a84cb0e33da556cc74andrewfish Target = (OpCode & 0xff) << 2; 6603402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %08x", gReg[(OpCode >> 8) & 7], PCAlign4 (PC) + Target); 661b32fecd24743853164e151a84cb0e33da556cc74andrewfish return; 662f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish 663f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish case IT_BLOCK: 664f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish // ITSTATE = cond:mask OpCode[7:4]:OpCode[3:0] 665f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish // ITSTATE[7:5] == cond[3:1] 6663402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron // ITSTATE[4] == 1st Instruction cond[0] 6673402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron // ITSTATE[3] == 2st Instruction cond[0] 6683402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron // ITSTATE[2] == 3st Instruction cond[0] 669f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish // ITSTATE[1] == 4st Instruction cond[0] 670f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish // ITSTATE[0] == 1 4 instruction IT block. 0 means 0,1,2 or 3 instructions 671f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish // 1st one in ITSTATE low bits defines the number of instructions 672f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish Mask = (OpCode & 0xf); 673f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish if ((Mask & 0x1) == 0x1) { 674f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish *ItBlock = 4; 675f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish Offset += AsciiSPrint (&Buf[Offset], Size - Offset, "%a%a%a", (Mask & BIT3)?"T":"E", (Mask & BIT2)?"T":"E", (Mask & BIT1)?"T":"E"); 676f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish } else if ((OpCode & 0x3) == 0x2) { 677f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish *ItBlock = 3; 678f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish Offset += AsciiSPrint (&Buf[Offset], Size - Offset, "%a%a", (Mask & BIT3)?"T":"E", (Mask & BIT2)?"T":"E"); 679f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish } else if ((OpCode & 0x7) == 0x4) { 680f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish *ItBlock = 2; 681f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish Offset += AsciiSPrint (&Buf[Offset], Size - Offset, "%a", (Mask & BIT3)?"T":"E"); 682f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish } else if ((OpCode & 0xf) == 0x8) { 683f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish *ItBlock = 1; 684f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish } 6853402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a", gCondition[(OpCode >> 4) & 0xf]); 686f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish return; 6876f72e28d04348ad4539679949609675b114896e1andrewfish } 6886f72e28d04348ad4539679949609675b114896e1andrewfish } 6896f72e28d04348ad4539679949609675b114896e1andrewfish } 6907c34497d5de78120879d44ebf4b5e10004894873andrewfish 6913402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 692097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish // Thumb2 are 32-bit instructions 693097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish *OpCodePtrPtr += 1; 694b32fecd24743853164e151a84cb0e33da556cc74andrewfish Rt = (OpCode32 >> 12) & 0xf; 695b32fecd24743853164e151a84cb0e33da556cc74andrewfish Rt2 = (OpCode32 >> 8) & 0xf; 696eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish Rd = (OpCode32 >> 8) & 0xf; 697b32fecd24743853164e151a84cb0e33da556cc74andrewfish Rm = (OpCode32 & 0xf); 698b32fecd24743853164e151a84cb0e33da556cc74andrewfish Rn = (OpCode32 >> 16) & 0xf; 699097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish for (Index = 0; Index < sizeof (gOpThumb2)/sizeof (THUMB_INSTRUCTIONS); Index++) { 700097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish if ((OpCode32 & gOpThumb2[Index].Mask) == gOpThumb2[Index].OpCode) { 701f9f937d243c8c9615119be2f2b35821e7de80925andrewfish if (Extended) { 7023402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Offset = AsciiSPrint (Buf, Size, "0x%04x %-6a", OpCode32, gOpThumb2[Index].Start); 703f9f937d243c8c9615119be2f2b35821e7de80925andrewfish } else { 7043402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Offset = AsciiSPrint (Buf, Size, " %-6a", gOpThumb2[Index].Start); 705f9f937d243c8c9615119be2f2b35821e7de80925andrewfish } 706f9f937d243c8c9615119be2f2b35821e7de80925andrewfish switch (gOpThumb2[Index].AddressMode) { 7077c34497d5de78120879d44ebf4b5e10004894873andrewfish case B_T3: 7087c34497d5de78120879d44ebf4b5e10004894873andrewfish Cond = gCondition[(OpCode32 >> 22) & 0xf]; 7097c34497d5de78120879d44ebf4b5e10004894873andrewfish Buf[Offset-5] = *Cond++; 7107c34497d5de78120879d44ebf4b5e10004894873andrewfish Buf[Offset-4] = *Cond; 7117c34497d5de78120879d44ebf4b5e10004894873andrewfish // S:J2:J1:imm6:imm11:0 7127c34497d5de78120879d44ebf4b5e10004894873andrewfish Target = ((OpCode32 << 1) & 0xffe) + ((OpCode32 >> 4) & 0x3f000); 713c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish Target |= ((OpCode32 & BIT11) == BIT11)? BIT19 : 0; // J2 714c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish Target |= ((OpCode32 & BIT13) == BIT13)? BIT18 : 0; // J1 715c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish Target |= ((OpCode32 & BIT26) == BIT26)? BIT20 : 0; // S 716c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish Target = SignExtend32 (Target, BIT20); 7173402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%08x", PC + 4 + Target); 7187c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 7197c34497d5de78120879d44ebf4b5e10004894873andrewfish case B_T4: 7207c34497d5de78120879d44ebf4b5e10004894873andrewfish // S:I1:I2:imm10:imm11:0 7217c34497d5de78120879d44ebf4b5e10004894873andrewfish Target = ((OpCode32 << 1) & 0xffe) + ((OpCode32 >> 4) & 0x3ff000); 722c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish S = (OpCode32 & BIT26) == BIT26; 723c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish J1 = (OpCode32 & BIT13) == BIT13; 724c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish J2 = (OpCode32 & BIT11) == BIT11; 725c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish Target |= (!(J2 ^ S) ? BIT22 : 0); // I2 726c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish Target |= (!(J1 ^ S) ? BIT23 : 0); // I1 727c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish Target |= (S ? BIT24 : 0); // S 728c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish Target = SignExtend32 (Target, BIT24); 7293402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%08x", PC + 4 + Target); 7307c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 7317c34497d5de78120879d44ebf4b5e10004894873andrewfish 7327c34497d5de78120879d44ebf4b5e10004894873andrewfish case BL_T2: 733eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish // BLX S:I1:I2:imm10:imm11:0 734eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish Target = ((OpCode32 << 1) & 0xffc) + ((OpCode32 >> 4) & 0x3ff000); 735c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish S = (OpCode32 & BIT26) == BIT26; 736c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish J1 = (OpCode32 & BIT13) == BIT13; 737c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish J2 = (OpCode32 & BIT11) == BIT11; 738c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish Target |= (!(J2 ^ S) ? BIT23 : 0); // I2 739c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish Target |= (!(J1 ^ S) ? BIT24 : 0); // I1 740c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish Target |= (S ? BIT25 : 0); // S 741c7ed09e34bf4435db8b0aeed489b99608b0f440eandrewfish Target = SignExtend32 (Target, BIT25); 7423402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%08x", PCAlign4 (PC) + Target); 7437c34497d5de78120879d44ebf4b5e10004894873andrewfish return; 744b32fecd24743853164e151a84cb0e33da556cc74andrewfish 745b32fecd24743853164e151a84cb0e33da556cc74andrewfish case POP_T2: 746b32fecd24743853164e151a84cb0e33da556cc74andrewfish // <reglist> some must be zero, handled in table 747b32fecd24743853164e151a84cb0e33da556cc74andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, " %a", ThumbMRegList (OpCode32 & 0xffff)); 748b32fecd24743853164e151a84cb0e33da556cc74andrewfish return; 749b32fecd24743853164e151a84cb0e33da556cc74andrewfish 750b32fecd24743853164e151a84cb0e33da556cc74andrewfish case POP_T3: 7513402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron // <register> 752b32fecd24743853164e151a84cb0e33da556cc74andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, " %a", gReg[(OpCode32 >> 12) & 0xf]); 753b32fecd24743853164e151a84cb0e33da556cc74andrewfish return; 754b32fecd24743853164e151a84cb0e33da556cc74andrewfish 755b32fecd24743853164e151a84cb0e33da556cc74andrewfish case STM_FORMAT: 756b32fecd24743853164e151a84cb0e33da556cc74andrewfish // <Rn>{!}, <registers> 757b32fecd24743853164e151a84cb0e33da556cc74andrewfish W = (OpCode32 & BIT21) == BIT21; 758eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish AsciiSPrint (&Buf[Offset], Size - Offset, " %a%a, %a", gReg[(OpCode32 >> 16) & 0xf], W ? "!":"", ThumbMRegList (OpCode32 & 0xffff)); 759b32fecd24743853164e151a84cb0e33da556cc74andrewfish return; 760b32fecd24743853164e151a84cb0e33da556cc74andrewfish 761b32fecd24743853164e151a84cb0e33da556cc74andrewfish case LDM_REG_IMM12_SIGNED: 762b32fecd24743853164e151a84cb0e33da556cc74andrewfish // <rt>, <label> 7633402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Target = OpCode32 & 0xfff; 764b32fecd24743853164e151a84cb0e33da556cc74andrewfish if ((OpCode32 & BIT23) == 0) { 765b32fecd24743853164e151a84cb0e33da556cc74andrewfish // U == 0 means subtrack, U == 1 means add 766b32fecd24743853164e151a84cb0e33da556cc74andrewfish Target = -Target; 767b32fecd24743853164e151a84cb0e33da556cc74andrewfish } 768eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[(OpCode32 >> 12) & 0xf], PCAlign4 (PC) + Target); 769b32fecd24743853164e151a84cb0e33da556cc74andrewfish return; 770b32fecd24743853164e151a84cb0e33da556cc74andrewfish 771b32fecd24743853164e151a84cb0e33da556cc74andrewfish case LDM_REG_INDIRECT_LSL: 772b32fecd24743853164e151a84cb0e33da556cc74andrewfish // <rt>, [<rn>, <rm> {, LSL #<imm2>]} 773b32fecd24743853164e151a84cb0e33da556cc74andrewfish Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, [%a, %a", gReg[Rt], gReg[Rn], gReg[Rm]); 774377a32dbed62b66f6d45589d3cae7a8253691422Olivier Martin if (((OpCode32 >> 4) & 3) == 0) { 775b32fecd24743853164e151a84cb0e33da556cc74andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, "]"); 776b32fecd24743853164e151a84cb0e33da556cc74andrewfish } else { 777377a32dbed62b66f6d45589d3cae7a8253691422Olivier Martin AsciiSPrint (&Buf[Offset], Size - Offset, ", LSL #%d]", (OpCode32 >> 4) & 3); 778b32fecd24743853164e151a84cb0e33da556cc74andrewfish } 779b32fecd24743853164e151a84cb0e33da556cc74andrewfish return; 7803402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 781b32fecd24743853164e151a84cb0e33da556cc74andrewfish case LDM_REG_IMM12: 782b32fecd24743853164e151a84cb0e33da556cc74andrewfish // <rt>, [<rn>, {, #<imm12>]} 783b32fecd24743853164e151a84cb0e33da556cc74andrewfish Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, [%a", gReg[Rt], gReg[Rn]); 784377a32dbed62b66f6d45589d3cae7a8253691422Olivier Martin if ((OpCode32 & 0xfff) == 0) { 785b32fecd24743853164e151a84cb0e33da556cc74andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, "]"); 786b32fecd24743853164e151a84cb0e33da556cc74andrewfish } else { 787b32fecd24743853164e151a84cb0e33da556cc74andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, ", #0x%x]", OpCode32 & 0xfff); 788b32fecd24743853164e151a84cb0e33da556cc74andrewfish } 789b32fecd24743853164e151a84cb0e33da556cc74andrewfish return; 790b32fecd24743853164e151a84cb0e33da556cc74andrewfish 791b32fecd24743853164e151a84cb0e33da556cc74andrewfish case LDM_REG_IMM8: 792b32fecd24743853164e151a84cb0e33da556cc74andrewfish // <rt>, [<rn>, {, #<imm8>}]{!} 793b32fecd24743853164e151a84cb0e33da556cc74andrewfish W = (OpCode32 & BIT8) == BIT8; 794b32fecd24743853164e151a84cb0e33da556cc74andrewfish U = (OpCode32 & BIT9) == BIT9; 795b32fecd24743853164e151a84cb0e33da556cc74andrewfish P = (OpCode32 & BIT10) == BIT10; 796b32fecd24743853164e151a84cb0e33da556cc74andrewfish Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, [%a", gReg[Rt], gReg[Rn]); 797b32fecd24743853164e151a84cb0e33da556cc74andrewfish if (P) { 798377a32dbed62b66f6d45589d3cae7a8253691422Olivier Martin if ((OpCode32 & 0xff) == 0) { 799b32fecd24743853164e151a84cb0e33da556cc74andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, "]%a", W?"!":""); 800b32fecd24743853164e151a84cb0e33da556cc74andrewfish } else { 80165e27445877ff101115c79e76928d91bf7625876andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, ", #%a0x%x]%a", U?"":"-" , OpCode32 & 0xff, W?"!":""); 802b32fecd24743853164e151a84cb0e33da556cc74andrewfish } 803b32fecd24743853164e151a84cb0e33da556cc74andrewfish } else { 80465e27445877ff101115c79e76928d91bf7625876andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, "], #%a0x%x", U?"":"-", OpCode32 & 0xff); 805b32fecd24743853164e151a84cb0e33da556cc74andrewfish } 806b32fecd24743853164e151a84cb0e33da556cc74andrewfish return; 807b32fecd24743853164e151a84cb0e33da556cc74andrewfish 808b32fecd24743853164e151a84cb0e33da556cc74andrewfish case LDRD_REG_IMM8_SIGNED: 809b32fecd24743853164e151a84cb0e33da556cc74andrewfish // LDRD <rt>, <rt2>, [<rn>, {, #<imm8>]}{!} 810b32fecd24743853164e151a84cb0e33da556cc74andrewfish P = (OpCode32 & BIT24) == BIT24; // index = P 8113402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron U = (OpCode32 & BIT23) == BIT23; 812b32fecd24743853164e151a84cb0e33da556cc74andrewfish W = (OpCode32 & BIT21) == BIT21; 813b32fecd24743853164e151a84cb0e33da556cc74andrewfish Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, [%a", gReg[Rt], gReg[Rt2], gReg[Rn]); 814b32fecd24743853164e151a84cb0e33da556cc74andrewfish if (P) { 815377a32dbed62b66f6d45589d3cae7a8253691422Olivier Martin if ((OpCode32 & 0xff) == 0) { 816b32fecd24743853164e151a84cb0e33da556cc74andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, "]"); 817b32fecd24743853164e151a84cb0e33da556cc74andrewfish } else { 818b32fecd24743853164e151a84cb0e33da556cc74andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, ", #%a0x%x]%a", U?"":"-", (OpCode32 & 0xff) << 2, W?"!":""); 819b32fecd24743853164e151a84cb0e33da556cc74andrewfish } 820b32fecd24743853164e151a84cb0e33da556cc74andrewfish } else { 821377a32dbed62b66f6d45589d3cae7a8253691422Olivier Martin if ((OpCode32 & 0xff) != 0) { 822b32fecd24743853164e151a84cb0e33da556cc74andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, ", #%a0x%x", U?"":"-", (OpCode32 & 0xff) << 2); 823b32fecd24743853164e151a84cb0e33da556cc74andrewfish } 824b32fecd24743853164e151a84cb0e33da556cc74andrewfish } 825b32fecd24743853164e151a84cb0e33da556cc74andrewfish return; 826b32fecd24743853164e151a84cb0e33da556cc74andrewfish 8273402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron case LDRD_REG_IMM8: 8283402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron // LDRD <rt>, <rt2>, <label> 8293402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Target = (OpCode32 & 0xff) << 2; 830b32fecd24743853164e151a84cb0e33da556cc74andrewfish if ((OpCode32 & BIT23) == 0) { 831b32fecd24743853164e151a84cb0e33da556cc74andrewfish // U == 0 means subtrack, U == 1 means add 832b32fecd24743853164e151a84cb0e33da556cc74andrewfish Target = -Target; 833b32fecd24743853164e151a84cb0e33da556cc74andrewfish } 834b32fecd24743853164e151a84cb0e33da556cc74andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, %a", gReg[Rt], gReg[Rt2], PC + 4 + Target); 835b32fecd24743853164e151a84cb0e33da556cc74andrewfish return; 836b32fecd24743853164e151a84cb0e33da556cc74andrewfish 837b32fecd24743853164e151a84cb0e33da556cc74andrewfish case LDREXB: 838b32fecd24743853164e151a84cb0e33da556cc74andrewfish // LDREXB <Rt>, [Rn] 839b32fecd24743853164e151a84cb0e33da556cc74andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, " %a, [%a]", gReg[Rt], gReg[Rn]); 840b32fecd24743853164e151a84cb0e33da556cc74andrewfish return; 841b32fecd24743853164e151a84cb0e33da556cc74andrewfish 842b32fecd24743853164e151a84cb0e33da556cc74andrewfish case LDREXD: 843b32fecd24743853164e151a84cb0e33da556cc74andrewfish // LDREXD <Rt>, <Rt2>, [<Rn>] 844b32fecd24743853164e151a84cb0e33da556cc74andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, " %a, ,%a, [%a]", gReg[Rt], gReg[Rt2], gReg[Rn]); 845b32fecd24743853164e151a84cb0e33da556cc74andrewfish return; 8463402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 847b32fecd24743853164e151a84cb0e33da556cc74andrewfish case SRS_FORMAT: 848b32fecd24743853164e151a84cb0e33da556cc74andrewfish // SP{!}, #<mode> 849b32fecd24743853164e151a84cb0e33da556cc74andrewfish W = (OpCode32 & BIT21) == BIT21; 850b32fecd24743853164e151a84cb0e33da556cc74andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, " SP%a, #0x%x", W?"!":"", OpCode32 & 0x1f); 851b32fecd24743853164e151a84cb0e33da556cc74andrewfish return; 852b32fecd24743853164e151a84cb0e33da556cc74andrewfish 853b32fecd24743853164e151a84cb0e33da556cc74andrewfish case RFE_FORMAT: 854b32fecd24743853164e151a84cb0e33da556cc74andrewfish // <Rn>{!} 855c639c2def9f9541a8dce49546da0daf11153e2aaandrewfish W = (OpCode32 & BIT21) == BIT21; 856b32fecd24743853164e151a84cb0e33da556cc74andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, " %a%a, #0x%x", gReg[Rn], W?"!":""); 857b32fecd24743853164e151a84cb0e33da556cc74andrewfish return; 8583402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 859eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish case ADD_IMM12: 860eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish // ADD{S} <Rd>, <Rn>, #<const> i:imm3:imm8 861eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish if ((OpCode32 & BIT20) == BIT20) { 862eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish Buf[Offset - 3] = 'S'; // assume %-6a 863eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish } 864eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish Target = (OpCode32 & 0xff) | ((OpCode32 >> 4) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0); 8653402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, #0x%x", gReg[Rd], gReg[Rn], Target); 866eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish return; 867eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish 868fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish case ADD_IMM12_1REG: 869fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish // MOV{S} <Rd>, #<const> i:imm3:imm8 870fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish if ((OpCode32 & BIT20) == BIT20) { 871fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish Buf[Offset - 3] = 'S'; // assume %-6a 872fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish } 873fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish Target = (OpCode32 & 0xff) | ((OpCode32 >> 4) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0); 8743402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #0x%x", gReg[Rd], Target); 875fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish return; 876fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish 877fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish case THUMB2_IMM16: 878fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish // MOVW <Rd>, #<const> i:imm3:imm8 879fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish Target = (OpCode32 & 0xff) | ((OpCode32 >> 4) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0); 880fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish Target |= ((OpCode32 >> 4) & 0xf0000); 8813402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #0x%x", gReg[Rd], Target); 882fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish return; 883fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish 884eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish case ADD_IMM5: 885c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish // ADC{S} <Rd>, <Rn>, <Rm> {,LSL #<const>} imm3:imm2 886eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish if ((OpCode32 & BIT20) == BIT20) { 887eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish Buf[Offset - 3] = 'S'; // assume %-6a 888eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish } 889eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish Target = ((OpCode32 >> 6) & 3) | ((OpCode32 >> 10) & 0x1c0); 8903402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, %a", gReg[Rd], gReg[Rn], gReg[Rm]); 891eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish if (Target != 0) { 8923402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, ", LSL %d", gShiftType[(OpCode >> 5) & 3], Target); 893eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish } 894eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish return; 895eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish 896c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish case ADD_IMM5_2REG: 897c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish // CMP <Rn>, <Rm> {,LSL #<const>} imm3:imm2 898c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish Target = ((OpCode32 >> 6) & 3) | ((OpCode32 >> 10) & 0x1c0); 8993402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rn], gReg[Rm]); 900c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish if (Target != 0) { 9013402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, ", LSL %d", gShiftType[(OpCode >> 5) & 3], Target); 902c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish } 903c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 904c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 905c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish case ASR_IMM5: 906c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish // ARS <Rd>, <Rm> #<const>} imm3:imm2 907c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish if ((OpCode32 & BIT20) == BIT20) { 908c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish Buf[Offset - 3] = 'S'; // assume %-6a 909c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish } 910c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish Target = ((OpCode32 >> 6) & 3) | ((OpCode32 >> 10) & 0x1c0); 9113402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a #%d", gReg[Rd], gReg[Rm], Target); 912c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish return; 913c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 914c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish case ASR_3REG: 915c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish // ARS <Rd>, <Rn>, <Rm> 916c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish if ((OpCode32 & BIT20) == BIT20) { 917c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish Buf[Offset - 3] = 'S'; // assume %-6a 918c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish } 9193402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a %a", gReg[Rd], gReg[Rn], gReg[Rm]); 920c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish return; 921c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 922eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish case ADR_THUMB2: 923eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish // ADDR <Rd>, <label> 924eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish Target = (OpCode32 & 0xff) | ((OpCode32 >> 8) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0); 925eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish if ((OpCode & (BIT23 | BIT21)) == (BIT23 | BIT21)) { 926eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish Target = PCAlign4 (PC) - Target; 927eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish } else { 928eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish Target = PCAlign4 (PC) + Target; 929eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish } 9303402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a, 0x%08x", gReg[Rd], Target); 931eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish return; 932b32fecd24743853164e151a84cb0e33da556cc74andrewfish 933eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish case CMN_THUMB2: 934c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish // CMN <Rn>, #<const>} 93501289ec36fc530aebefa38085655d1d656b3339fHarry Liebel Target = (OpCode32 & 0xff) | ((OpCode >> 4) & 0x700) | ((OpCode & BIT26) == BIT26 ? BIT11 : 0); 9363402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #0x%x", gReg[Rn], Target); 937c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish return; 938c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 939c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish case BFC_THUMB2: 940c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish // BFI <Rd>, <Rn>, #<lsb>, #<width> 941c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish msbit = OpCode32 & 0x1f; 942c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish lsbit = ((OpCode32 >> 6) & 3) | ((OpCode >> 10) & 0x1c); 943c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish if ((Rn == 0xf) & (AsciiStrCmp (gOpThumb2[Index].Start, "BFC") == 0)){ 944c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish // BFC <Rd>, #<lsb>, #<width> 9453402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a, #%d, #%d", gReg[Rd], lsbit, msbit - lsbit + 1); 946c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish } else if (AsciiStrCmp (gOpThumb2[Index].Start, "BFI") == 0) { 9473402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, #%d, #%d", gReg[Rd], gReg[Rn], lsbit, msbit - lsbit + 1); 948c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish } else { 9493402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, #%d, #%d", gReg[Rd], gReg[Rn], lsbit, msbit + 1); 950eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish } 951c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish return; 952c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 953c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish case CPD_THUMB2: 954c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish // <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> 955c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish coproc = (OpCode32 >> 8) & 0xf; 956c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish opc1 = (OpCode32 >> 20) & 0xf; 957c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish opc2 = (OpCode32 >> 5) & 0x7; 958c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish CRd = (OpCode32 >> 12) & 0xf; 959c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish CRn = (OpCode32 >> 16) & 0xf; 960c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish CRm = OpCode32 & 0xf; 961c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " p%d,#%d,c%d,c%d,c%d", coproc, opc1, CRd, CRn, CRm); 962c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish if (opc2 != 0) { 963c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, ",#%d,", opc2); 964eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish } 965eeb78924eca8f2c4d334138100298d8d1cbd1b4aandrewfish return; 966c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 967fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish case MRC_THUMB2: 968fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish // MRC <coproc>,<opc1>,<Rt>,<CRn>,<CRm>,<opc2> 969fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish coproc = (OpCode32 >> 8) & 0xf; 970fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish opc1 = (OpCode32 >> 20) & 0xf; 971fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish opc2 = (OpCode32 >> 5) & 0x7; 972fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish CRn = (OpCode32 >> 16) & 0xf; 973fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish CRm = OpCode32 & 0xf; 974fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " p%d,#%d,%a,c%d,c%d", coproc, opc1, gReg[Rt], CRn, CRm); 975fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish if (opc2 != 0) { 976fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, ",#%d,", opc2); 977fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish } 9783402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron return; 979fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish 980fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish case MRRC_THUMB2: 981fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish // MRC <coproc>,<opc1>,<Rt>,<Rt2>,<CRm>,<opc2> 982fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish coproc = (OpCode32 >> 8) & 0xf; 983fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish opc1 = (OpCode32 >> 20) & 0xf; 984fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish CRn = (OpCode32 >> 16) & 0xf; 985fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish CRm = OpCode32 & 0xf; 986fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish Offset += AsciiSPrint (&Buf[Offset], Size - Offset, " p%d,#%d,%a,%a,c%d", coproc, opc1, gReg[Rt], gReg[Rt2], CRm); 9873402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron return; 988fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish 989c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish case THUMB2_2REGS: 990c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish // <Rd>, <Rm> 991c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rd], gReg[Rm]); 992c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish return; 993c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 994c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish case THUMB2_4REGS: 995c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish // <Rd>, <Rn>, <Rm>, <Ra> 996c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a, %a, %a", gReg[Rd], gReg[Rn], gReg[Rm], gReg[Rt]); 997c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish return; 998c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish 999fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish case THUMB2_MRS: 1000fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish // MRS <Rd>, CPSR 1001fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, " %a, CPSR", gReg[Rd]); 1002fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish return; 10033402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 1004fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish case THUMB2_MSR: 1005fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish // MRS CPSR_<fields>, <Rd> 1006fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish Target = (OpCode32 >> 10) & 3; 1007fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish AsciiSPrint (&Buf[Offset], Size - Offset, " CPSR_%a%a, %a", (Target & 2) == 0 ? "":"f", (Target & 1) == 0 ? "":"s", gReg[Rd]); 1008fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish return; 1009fef5272652ffbbb2cfe827b79f00cf8e1c17a233andrewfish 1010c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish case THUMB2_NO_ARGS: 1011c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish default: 1012c5c902dad22958d301efe961f57dc5b5cf30e115andrewfish break; 1013f9f937d243c8c9615119be2f2b35821e7de80925andrewfish } 1014097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish } 1015097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish } 10167c34497d5de78120879d44ebf4b5e10004894873andrewfish 10177c34497d5de78120879d44ebf4b5e10004894873andrewfish AsciiSPrint (Buf, Size, "0x%08x", OpCode32); 10186f72e28d04348ad4539679949609675b114896e1andrewfish} 10196f72e28d04348ad4539679949609675b114896e1andrewfish 1020097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish 1021097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish 1022097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfishVOID 1023097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfishDisassembleArmInstruction ( 1024097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish IN UINT32 **OpCodePtr, 1025097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish OUT CHAR8 *Buf, 1026f9f937d243c8c9615119be2f2b35821e7de80925andrewfish OUT UINTN Size, 1027f9f937d243c8c9615119be2f2b35821e7de80925andrewfish IN BOOLEAN Extended 1028097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish ); 1029097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish 1030097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish 1031097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish/** 10323402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to 10333402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron point to next instructin. 10343402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 10353402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron We cheat and only decode instructions that access 1036097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish memory. If the instruction is not found we dump the instruction in hex. 10373402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 10383402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron @param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble. 1039097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish @param Thumb TRUE for Thumb(2), FALSE for ARM instruction stream 1040f9f937d243c8c9615119be2f2b35821e7de80925andrewfish @param Extended TRUE dump hex for instruction too. 1041f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish @param ItBlock Size of IT Block 1042097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish @param Buf Buffer to sprintf disassembly into. 10433402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron @param Size Size of Buf in bytes. 10443402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 1045097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish**/ 1046097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfishVOID 1047097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfishDisassembleInstruction ( 1048097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish IN UINT8 **OpCodePtr, 1049097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish IN BOOLEAN Thumb, 1050f9f937d243c8c9615119be2f2b35821e7de80925andrewfish IN BOOLEAN Extended, 1051f3198cba84f56f85281b87c4e9bf96e77a934f16andrewfish IN OUT UINT32 *ItBlock, 1052097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish OUT CHAR8 *Buf, 1053097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish OUT UINTN Size 1054097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish ) 1055097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish{ 1056097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish if (Thumb) { 105785e385f42b3a93dd51d76173eb4083f9caf803d7andrewfish DisassembleThumbInstruction ((UINT16 **)OpCodePtr, Buf, Size, ItBlock, Extended); 1058097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish } else { 1059f9f937d243c8c9615119be2f2b35821e7de80925andrewfish DisassembleArmInstruction ((UINT32 **)OpCodePtr, Buf, Size, Extended); 1060097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish } 1061097bd461c4219edb62f4595ce7ccc6ec3bb34db9andrewfish} 10623402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron 1063