\ ARM Disassembler. \ \ This program is distributed under the terms of the 'MIT license'. The text \ of this licence follows... \ \ Copyright (c) 2005 J.D.Medhurst (a.k.a. Tixy) \ \ Permission is hereby granted, free of charge, to any person obtaining a copy \ of this software and associated documentation files (the "Software"), to deal \ in the Software without restriction, including without limitation the rights \ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell \ copies of the Software, and to permit persons to whom the Software is \ furnished to do so, subject to the following conditions: \ \ The above copyright notice and this permission notice shall be included in \ all copies or substantial portions of the Software. \ \ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR \ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, \ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE \ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER \ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN \ THE SOFTWARE. \ \ \ ---------------------------------------------------------------------------- \ REQUIREMENTS and DEPENDECIES \ \ This code requires ANS wordsets: CORE, CORE-EXT, SEARCH-ORDER and \ SEARCH-ORDER-EXT. It also uses the non-standard word VOCABULARY. \ \ The code is dependent on the size of a CELL being at least 32 bits. \ \ \ ---------------------------------------------------------------------------- \ USAGE \ \ Two words are provided to produce a disassembly, ARM-DISASM and \ ARM-DISASM-OP. \ \ \ ---------------------------------------------------------------------------- \ CHANGES \ \ 2006-11-09 \ Fixed some ANS Forth Standard compliancey issues. \ * Made all hex values use upper-case letters. HEX \ ---------------------------------------------------------------------------- \ Place disassembler in its own vocabulary VOCABULARY ARM-DISASSEMBLER ALSO ARM-DISASSEMBLER DEFINITIONS \ ---------------------------------------------------------------------------- \ Helpers words... : RROTATE ( x1 u -- x2 ) \ rotate the bits of x1 right by u bits 1F AND 2DUP RSHIFT ROT ROT 20 SWAP - LSHIFT OR ; : ARSHIFT ( x1 u -- x2 ) \ shift x1 right by u bits, propagating the sign OVER 0< IF TRUE OVER RSHIFT INVERT >R RSHIFT R> OR EXIT THEN RSHIFT ; \ ---------------------------------------------------------------------------- \ Variables which indicate validity of instruction being disassembled VARIABLE UNDEFINED \ Set TRUE if instruction is undefined VARIABLE UNPREDICTABLE \ Mask of bits which make instruction unpredictable : UNDEFINED-OP ( -- ) TRUE UNDEFINED ! ; : ?UNPREDICTABLE ( x flags -- ) IF UNPREDICTABLE @ OR UNPREDICTABLE ! EXIT THEN DROP ; : -UNDEFINED ( x -- x ) \ Set undefined instruction if x is zero DUP 0= IF UNDEFINED-OP THEN ; : SBO ( x1 x2 -- x1 ) \ All bits set in x2 should be one in x1 2DUP AND OVER <> ?UNPREDICTABLE ; : SBZ ( x1 x2 -- x1 ) \ All bits set in x2 should be zero in x1 2DUP AND ?UNPREDICTABLE ; \ ---------------------------------------------------------------------------- \ Text output \ \ Disassembled code is stored as a counted string at BUFFER CREATE BUFFER 81 CHARS ALLOT \ room for 128 characters : OUT ( -- c-addr ) \ Address to store next output char at BUFFER COUNT CHARS + ; : +OUT ( n -- ) \ Advance OUT by n chars CHARS BUFFER C@ + BUFFER C! ; : C. ( char -- ) \ Append a char to disassembled text OUT C! 1 +OUT ; : S. ( c-addr u -- ) \ Append a string to disassembled text OUT SWAP DUP +OUT CHARS MOVE ; : BL. ( -- ) \ Append a space BL C. ; : C.BL. ( char -- ) \ Append char then a space C. BL. ; : S.BL. ( c-addr u -- ) \ Append string then a space S. BL. ; : NUM. ( n flag -- ) \ Append n DUP >R 0< IF NEGATE THEN 0 <# #S R> SIGN #> OVER C@ [CHAR] 9 U> \ number starts with letter? OVER 8 < AND \ and less that 8 chars long? IF [CHAR] 0 C. THEN \ ... If so, add '0' prefix S.BL. ; : TAB. ( -- ) \ Append spaces to make number of chars a multiple of 8 BUFFER BEGIN BL. DUP C@ 7 AND 0= UNTIL DROP ; \ ---------------------------------------------------------------------------- \ Text output for parts of disassembled instruction : -TRAILING ( c-addr u1 -- c-addr u2 ) \ Remove a single trailing space BEGIN DUP WHILE 1- 2DUP CHARS + C@ BL = WHILE REPEAT 1+ THEN ; : (select") ( u1 c-addr1 -- c-addr2 u2 ) CHAR+ COUNT [CHAR] 0 - >R SWAP R@ * CHARS + R> -TRAILING DUP 0= IF UNDEFINED-OP THEN ; : SELECT" ( Compilation: "ccc" -- ) ( Run-time: u1 -- c-addr u2 ) \ Treat "ccc" as an array of strings, the size of each string is the \ given by the first ascii character in "ccc". From this array, return \ the element given by u1, (removing a trailing space if present). POSTPONE C" POSTPONE (select") ; IMMEDIATE : (?select") ( x c-addr1 -- c-addr2 u ) COUNT 2/ >R SWAP 0<> R@ AND CHARS + R> -TRAILING ; : ?SELECT" ( Compilation: "ccc" -- ) ( Run-time: x -- c-addr2 u ) \ Treat "ccc" as two strings of equal length. If x is false, return \ the first string, otherwise return the second. Any trailing space \ is removed. POSTPONE C" POSTPONE (?select") ; IMMEDIATE : SARRAY ( "name" -- ) \ Create array of counted strings CREATE DOES> ( n - c-addr u ) BEGIN OVER WHILE COUNT CHARS + SWAP 1- SWAP REPEAT SWAP DROP COUNT ; : ," ( "ccc" -- ) \ Compile a counted string [CHAR] " PARSE DUP C, HERE SWAP DUP ALLOT CHARS MOVE ; : (flags.") ( x c-addr -- ) COUNT CHARS OVER + SWAP DO DUP 1 AND IF I C@ C. THEN 2/ LOOP DROP ; : FLAGS." ( Compilation: "ccc" -- ) ( Run-time: x -- ) \ Output characters from "ccc" if corresponding bit is set in x POSTPONE C" POSTPONE (flags.") ; IMMEDIATE : REG. ( u -- ) \ Output name for ARM register given by bottom 4 bits of u 0F AND SELECT" 3r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10r11r12r13lr pc " S.BL. ; : REG0. ( x -- x ) \ Output name of ARM register given by bits 0-3 of x DUP REG. ; : REG8. ( x -- x ) \ Output name of ARM register given by bits 8-11 of x DUP 8 RSHIFT REG. ; : REG12. ( x -- x ) \ Output name of ARM register given by bits 12-15 of x DUP 0C RSHIFT REG. ; : REG16. ( x -- x ) \ Output name of ARM register given by bits 16-23 of x DUP 10 RSHIFT REG. ; : #. ( n -- ) \ Output n as an assembler immediate argument "nnn # " S>D NUM. [CHAR] # C.BL. ; : U#. ( n -- ) \ Output n as an assembler immediate argument "nnn # " 0 NUM. [CHAR] # C.BL. ; : ?-. ( x -- x ) \ Output a '-' if the U bit is clear in op-code x DUP 00800000 AND 0= IF [CHAR] - C. THEN ; : INDEX#. ( x n -- x ) \ Output n as an immediate operand, if not zero ?DUP IF OVER 00800000 AND 0= IF NEGATE THEN #. THEN ; : [. ( -- ) \ Output a [ char [CHAR] [ C.BL. ; : ]. ( -- ) \ Output a ] char [CHAR] ] C.BL. ; : CC. ( x -- x) \ Output condition code mnemonic for op-code x DUP 1C RSHIFT DUP 0E < IF SELECT" 2eqnecsccmiplvsvchilsgeltgtle" S.BL. ELSE 0F = IF UNDEFINED-OP THEN THEN ; : S.BL.CC. ( x c-addr u -- x ) \ Output string followed by condition code S.BL. CC. ; : IMMEDIATE. ( x -- x ) \ Output data processing instruction immediate arg DUP 0FF AND OVER F00 AND 7 RSHIFT RROTATE #. ; : SHIFT. ( x -- x ) \ Output mnemonic for shift operand in op-code x DUP 5 RSHIFT 3 AND SELECT" 3lsllsrasrror" S.BL. ; : SHIFT#. ( x -- x ) \ Output mnemonic for immediate shift operand DUP FE0 AND DUP 0= IF DROP EXIT THEN \ asl 0 # is ignored 060 = IF \ ror 0 # is an rrx... S" rrx" S.BL. ELSE SHIFT. DUP 7 RSHIFT 1F AND \ immediate shift value OVER 60 AND IF DUP 0= IF DROP 20 THEN \ convert shift 0 into 32 for lsr and asr THEN #. THEN ; : RM-SHIFT. ( x -- x ) \ Output register and shift operands in bits 0-11 REG0. DUP 10 AND IF \ shift by register... SHIFT. REG8. ELSE \ shift by constant... SHIFT#. THEN ; : BIT20? ( x1 -- x1 x2 ) \ Return bit 20 of x1 DUP 00100000 AND ; : BIT22? ( x1 -- x1 x2 ) \ Return bit 22 of x1 DUP 00400000 AND ; \ ---------------------------------------------------------------------------- \ Data processing instructions... : DATA-OP. ( x -- x ) DUP 15 RSHIFT 0F AND SELECT" 3andeorsubrsbaddadcsbcrsctstteqcmpcmnorrmovbicmvn" S.BL.CC. ; : SFLAG. ( x -- x ) \ Output and 's' char if S bit is set in op-code x BIT20? IF [CHAR] s C.BL. THEN ; : DATA-OPERANDS. ( x -- x ) DUP 02000000 AND IF IMMEDIATE. ELSE RM-SHIFT. THEN ; : MOV-OP ( x -- x ) \ Decode MOV and MVN instructions 000F0000 SBZ DATA-OP. SFLAG. TAB. REG12. DATA-OPERANDS. ; : CMP-TST-OP ( x -- x ) \ Decode CMP, CMN, TEQ and TST instructions 0000F000 SBZ DATA-OP. TAB. REG16. DATA-OPERANDS. ; : DATA-OP ( x -- x ) \ Decode data processing instructions DATA-OP. SFLAG. TAB. REG12. REG16. DATA-OPERANDS. ; : QADD/SUB-OP ( x -- x) \ Decode QADD, QDADD, QSUB and QDSUB intructions 00000F00 SBZ DUP 15 RSHIFT 3 AND SELECT" 5qadd qsub qdaddqdsub" S.BL.CC. TAB. REG12. REG0. REG16. ; \ ---------------------------------------------------------------------------- \ Decode Multiply instructions... : MUL-OP ( x -- x ) \ Decode MUL and MLA instructions 0000F000 SBZ S" mul" S.BL.CC. SFLAG. TAB. REG16. REG0. REG8. ; : MLA-OP ( x -- x ) \ Decode MUL and MLA instructions S" mla" S.BL.CC. SFLAG. TAB. REG16. REG0. REG8. REG12. ; : LONG-MUL-OP ( x -- x ) \ Decode UMULL, UMLAL, SMULL & SMLAL instructions DUP 15 RSHIFT 3 AND SELECT" 5umullumlalsmullsmlal" S.BL.CC. SFLAG. TAB. REG12. REG16. REG0. REG8. ; : B/T. ( x1 x2 -- x1 ) OVER AND IF [CHAR] t ELSE [CHAR] b THEN C. ; : SMUL-OPERANDS ( x -- x ) 40 B/T. BL. CC. TAB. REG16. REG0. REG8. ; : SMLAXY-OP ( x -- x ) \ Decode SMLA instruction S" smla" S. 20 B/T. SMUL-OPERANDS REG12. ; : SMLAWY-OP ( x -- x ) \ Decode SMLA instruction S" smlaw" S. SMUL-OPERANDS REG12. ; : SMULXY-OP ( x -- x ) \ Decode SMLA instruction 0000F000 SBZ S" smul" S. 20 B/T. SMUL-OPERANDS ; : SMULWY-OP ( x -- x ) \ Decode SMLA instruction 0000F000 SBZ S" smulw" S. SMUL-OPERANDS ; : SMLALXY-OP ( x -- x ) \ Decode SMLAL instruction S" smlal" S. 20 B/T. 40 B/T. BL. CC. TAB. REG12. REG16. REG0. REG8. ; : UMAAL-OP ( x -- x ) \ Decode UMAAL-OP instruction S" umaal" S.BL.CC. TAB. REG12. REG16. REG0. REG8. ; : DUAL-MUL-OP ( x -- x ) \ Decode dual multiply instruction DUP 5 RSHIFT 3 AND SELECT" 6smuad smuadxsmusd smusdx" S.BL.CC. TAB. REG16. REG0. REG8. ; : DUAL-MULA-OP ( x -- x ) \ Decode dual multiply accumulate instruction DUP 5 RSHIFT 3 AND SELECT" 6smlad smladxsmlsd smlsdx" S.BL.CC. TAB. REG16. REG0. REG8. REG12. ; : MOST-SIG-MULA-OP ( x -- x ) \ Decode most significaant multiply accumulate instruction DUP 5 RSHIFT 3 AND SELECT" 6smmla smmlarsmmls smmlsr" S.BL.CC. TAB. REG16. REG0. REG8. REG12. ; : MOST-SIG-MUL-OP ( x -- x ) \ Decode most significaant multiply instruction DUP 20 AND ?SELECT" smmul smmulr" S.BL.CC. TAB. REG16. REG0. REG8. ; : LONG-DUAL-MULA-OP ( x -- x ) \ Decode long dual multiply accumulate instruction DUP 5 RSHIFT 3 AND SELECT" 7smlald smlaldxsmlsld smlsldx" S.BL.CC. TAB. REG12. REG16. REG0. REG8. ; \ ---------------------------------------------------------------------------- \ Decode load/store instructions... : MEM-OP. ( x -- ) \ Output LDR op if x is true, STR if false ?SELECT" strldr" S.BL.CC. ; : !. ( x -- x ) \ Output a ! character if op-code x contains a set W bit DUP 00200000 AND IF [CHAR] ! C.BL. THEN ; : MEM-OPERANDS. ( x xt - x ) \ Output operands for memory op \ xt outputs the index >R TAB. REG12. [. REG16. R> OVER 01000000 AND \ pre/post index selection IF EXECUTE ]. !. ELSE ]. EXECUTE THEN ; : MEM-INDEX. ( x -- x ) \ Output address index for load/stores DUP 02000000 AND IF ?-. RM-SHIFT. ELSE DUP 0FFF AND INDEX#. THEN ; : MEM-OP ( x -- x ) \ Decode LDR and STR (word and unsigned byte forms) BIT20? MEM-OP. FALSE OVER 00400000 AND IF [CHAR] b C. DROP TRUE THEN OVER 01200000 AND 00200000 = IF [CHAR] t C. DROP TRUE THEN IF BL. THEN ['] MEM-INDEX. MEM-OPERANDS. ; : PLD-OP ( x -- x) \ Decode PLD instructions S" pld" S. TAB. [. REG16. MEM-INDEX. ]. ; : EXTRA-MEM-INDEX. ( x -- x ) \ Output address index for extra load/stores BIT22? IF DUP 4 RSHIFT F0 AND OVER 0F AND OR INDEX#. ELSE 00000F00 SBZ ?-. REG0. THEN ; : EXTRA-MEM-OP ( x -- x ) \ Decode LDR & STR (half word, and signed forms) BIT20? MEM-OP. DUP 5 RSHIFT 3 AND SELECT" 2sbh sbsh" S.BL. ['] EXTRA-MEM-INDEX. MEM-OPERANDS. ; : DOUBLE-MEM-OP ( x -- x ) \ Decode LDRD and STRD DUP INVERT 20 AND MEM-OP. [CHAR] d C.BL. ['] EXTRA-MEM-INDEX. MEM-OPERANDS. ; : SWAP-OP ( x -- x ) \ Decode SWAP instruction 00000F00 SBZ S" swp" S.BL.CC. BIT22? IF [CHAR] b C.BL. THEN TAB. REG12. REG0. [. REG16. ]. ; : STREX-OP ( x -- x ) \ Decode SWAP instruction 00000F00 SBO S" strex" S.BL.CC. TAB. REG12. REG0. [. REG16. ]. ; : LDREX-OP ( x -- x ) \ Decode SWAP instruction 00000F0F SBO S" ldrex" S.BL.CC. TAB. REG12. [. REG16. ]. ; : MULTI-MODE. ( x -- x ) \ Output LDM/STM address mode DUP 17 RSHIFT 3 AND SELECT" 2daiadbib" S.BL. ; : MULTI-OP ( x -- x ) \ Decode LDM and STM instructions BIT20? ?SELECT" stmldm" S.BL.CC. MULTI-MODE. TAB. REG16. !. [CHAR] { C.BL. 10 0 DO 1 I LSHIFT OVER AND IF I REG. THEN LOOP [CHAR] } C.BL. BIT22? IF [CHAR] ^ C. THEN ; : RFE-OP ( x -- x ) \ Decode RFE instruction 0000F0FF SBZ S" rfe" S.BL. MULTI-MODE. TAB. REG16. !. ; : SRS-OP ( x -- x ) \ Decode SRS instruction 0000F0E0 SBZ S" srs" S.BL. MULTI-MODE. TAB. DUP 1F AND #. !. ; \ ---------------------------------------------------------------------------- \ Branch instructions... : BRANCH-OP ( a-addr x -- a-addr x ) \ Decode B,BL and BLX(1) instructions 2DUP 8 LSHIFT 6 ARSHIFT + 8 + >R DUP F0000000 U< IF DUP 01000000 AND ?SELECT" b bl" S.BL.CC. ELSE \ blx instruction... DUP 17 RSHIFT 2 AND R> + >R \ add in the half-word bit to target S" blx" S.BL. THEN TAB. R> U#. ; : BX-OP ( x -- x ) \ Decode BX instruction (register form) 000FFF00 SBO DUP 4 RSHIFT 3 AND SELECT" 3 bx bxjblx" S.BL.CC. TAB. REG0. ; : SWI-OP ( x -- x ) \ Decode SWI instructions S" swi" S.BL.CC. TAB. DUP 00FFFFFF AND #. ; \ ---------------------------------------------------------------------------- \ Decode MRS and MSR instructions... : PSR. ( x -- x ) BIT22? ?SELECT" cpsrspsr" S. ; : MRS-OP ( x -- x ) \ Decode MRS instruction 000F0000 SBO 00000FFF SBZ S" mrs" S.BL.CC. TAB. REG12. PSR. ; : MSR-OP ( x -- x ) 0000F000 SBO S" msr" S.BL.CC. TAB. PSR. [CHAR] _ C.BL. 000F0000 2DUP AND 0= ?UNPREDICTABLE \ treat no flags as unpredictable DUP 10 RSHIFT FLAGS." cxsf" BL. ; : MSR-IMM-OP ( x -- x) \ Decode MSR immediate instruction MSR-OP IMMEDIATE. ; : MSR-REG-OP ( x -- x) \ Decode MSR immediate instruction 00000F00 SBZ MSR-OP REG0. ; \ ---------------------------------------------------------------------------- \ Coprocessor instructions... : 0-15. ( x -- ) \ Output bottom 4 bits of x as decimal number 0F AND SELECT" 20 1 2 3 4 5 6 7 8 9 101112131415" S.BL. ; : CREG. ( x -- ) \ Output coprocessor register given by bottom 4 bits of x [CHAR] c C. 0-15. ; : CP. ( x -- x ) \ Output coprocessor number in op-code x [CHAR] p C. DUP 8 RSHIFT 0-15. ; : COP. ( x c-addr u - u ) \ Output coprocessor op name and condition code S. DUP 1C RSHIFT 0F = IF [CHAR] 2 C.BL. \ Append '2' for condition code = 0F ELSE BL. CC. THEN ; : CO-MEM-OP ( x -- x ) \ Decode LDC and STC instructions BIT20? ?SELECT" stcldc" COP. BIT22? IF [CHAR] l C.BL. THEN TAB. CP. DUP 0C RSHIFT CREG. [. REG16. DUP 0FF AND 2 LSHIFT OVER 01000000 AND IF INDEX#. ]. !. ELSE ]. OVER 00200000 AND IF INDEX#. ELSE [CHAR] { C.BL. 2 ARSHIFT #. [CHAR] } C.BL. DUP 00800000 AND 0= IF UNDEFINED-OP THEN THEN THEN ; : CO-OPERANDS. ( x -- x ) \ Output final coprocessor instruction arguments DUP 10 RSHIFT CREG. DUP CREG. DUP 5 RSHIFT 7 AND #. ; : CDP-OP ( x -- x ) \ Decode CDP instruction S" cdp" COP. TAB. CP. DUP 14 RSHIFT 0F AND #. DUP 0C RSHIFT CREG. CO-OPERANDS. ; : CO-REG-OP ( x -- x ) \ Decode MRC and MCR instructions BIT20? ?SELECT" mcrmrc" COP. TAB. CP. DUP 15 RSHIFT 7 AND #. REG12. CO-OPERANDS. ; : CO-REG2-OP ( x -- x ) \ Decode MRRC and MCRR instructions BIT20? ?SELECT" mcrrmrrc" COP. TAB. CP. DUP 4 RSHIFT 0F AND #. REG12. REG16. DUP CREG. ; \ ---------------------------------------------------------------------------- \ Miscelaneous instructions... : CLZ-OP ( x -- x ) \ Decode CLZ instruction 000F0F00 SBO S" clz" S.BL.CC. TAB. REG12. REG0. ; : BKPT-OP ( x -- x ) \ Decode BKPT instruction F0000000 2DUP AND E0000000 <> ?UNPREDICTABLE DUP 0000000F AND OVER 000FFF00 AND 4 RSHIFT OR S" bkpt" S.BL. TAB. #. ; : CPSI-OP ( x -- x ) \ Decode CPS instruction 0000FE00 SBZ DUP 00040000 AND ?SELECT" cpsiecpsid" S. TAB. 1C0 2DUP AND 0= ?UNPREDICTABLE \ treat no flags changed as unpredictable DUP 6 RSHIFT FLAGS." fia" BL. DUP 1F AND OVER 00020000 AND IF #. ELSE 1 ?UNPREDICTABLE \ mode SBZ if not changing it THEN ; : CPS-OP ( x -- x ) \ Decode CPS instruction 0004FFC0 SBZ 00020000 SBO S" cps" S. TAB. DUP 1F AND #. ; : SETEND-OP ( x -- x ) \ Decode SETEND instruction 0000FC0F SBZ S" setend" S. TAB. DUP 00000200 AND ?SELECT" lebe" S. ; \ ---------------------------------------------------------------------------- \ Media instructions SARRAY PAS1 ," " ," s" ," q" ," sh" ," " ," u" ," uq" ," uh" SARRAY PAS2 ," add16" ," addsubx" ," subaddx" ," sub16" ," add8" ," " ," " ," sub8" : PARALLEL-ADD-SUB-OP ( x -- x ) \ Decode parallel add/sub instructions 00000F00 SBO DUP 14 RSHIFT 7 AND PAS1 -UNDEFINED S. DUP 5 RSHIFT 7 AND PAS2 -UNDEFINED S.BL.CC. TAB. REG12. REG16. REG0. ; : PACK-HALFWORD-OP ( x -- x ) \ Decode PKHBT and PKHTB instruction DUP 40 AND ?SELECT" pkhbtpkhtb" S.BL.CC. TAB. REG12. REG16. REG0. SHIFT#. ; : WORD-SATURATE-OP ( x -- x ) \ Decode SSAT and USAT instruction BIT22? ?SELECT" ssatusat" S.BL.CC. TAB. REG12. DUP 10 RSHIFT 1F AND #. REG0. SHIFT#. ; : HALF-WORD-SATURATE-OP ( x -- x ) \ Decode SSAT16 and USAT16 instructions 00000F00 SBO BIT22? ?SELECT" ssat16usat16" S.BL.CC. TAB. REG12. DUP 10 RSHIFT F AND #. REG0. ; : SEL-OP ( x -- x) \ Decode SEL instruction 00000F00 SBO S" sel" S.BL.CC. TAB. REG12. REG16. REG0. ; : EXTEND-OP ( x -- x ) \ Decode extend instructions 00000300 SBZ DUP 10 RSHIFT F AND F <> >R \ flag true if extend with add BIT22? ?SELECT" sxtuxt" S. R@ IF [CHAR] a C. THEN DUP 14 RSHIFT 3 AND SELECT" 3b16 b h " -UNDEFINED S.BL.CC. TAB. REG12. R> IF REG16. THEN REG0. DUP C00 AND IF SHIFT#. THEN ; : REV-OP. ( x c-addr u -- x ) S.BL.CC. 000F0F00 SBO TAB. REG12. REG0. ; : REV-OP ( x -- x ) \ Decode extend instructions S" rev" REV-OP. ; : REV16-OP ( x -- x ) \ Decode extend instructions S" rev16" REV-OP. ; : REVH-OP ( x -- x ) \ Decode extend instructions S" revsh" REV-OP. ; : USAD8-OP ( x -- x ) \ Decode USDA instruction S" usad8" S.BL.CC. TAB. REG16. REG0. REG8. ; : USADA8-OP ( x -- x ) \ Decode USDA8 instruction S" usada8" S.BL.CC. TAB. REG16. REG0. REG8. REG12. ; \ ---------------------------------------------------------------------------- \ Top level functions... : PATTERN ( "name" -- ) \ Define a list of patterns to match CREATE DOES> ( x -- x ) \ Find match for x in list of patterns BEGIN 2DUP @ AND OVER CELL+ @ <> WHILE CELL+ CELL+ CELL+ REPEAT CELL+ CELL+ @ EXECUTE ; PATTERN PATTERN-0E000090-00000090 ( x -- x ) \ Multiplies and extra load/store instructions... 0FE000F0 , 00000090 , ' MUL-OP , 0FE000F0 , 00200090 , ' MLA-OP , 0FF000F0 , 00400090 , ' UMAAL-OP , 0F8000F0 , 00800090 , ' LONG-MUL-OP , 0FB000F0 , 01000090 , ' SWAP-OP , 0FF000F0 , 01800090 , ' STREX-OP , 0FF000F0 , 01900090 , ' LDREX-OP , 000000F0 , 00000090 , ' UNDEFINED-OP , 01200000 , 00200000 , ' UNDEFINED-OP , \ post index without writeback 00100040 , 00000040 , ' DOUBLE-MEM-OP , 0 , 0 , ' EXTRA-MEM-OP , PATTERN MISCELANEOUS-OP ( x -- x ) \ Miscelaneous instructions... FFF90020 , F1080000 , ' CPSI-OP , FFF90020 , F1000000 , ' CPS-OP , FFFFFDFF , F1010000 , ' SETEND-OP , 0FB000F0 , 01000000 , ' MRS-OP , 0FF000C0 , 01200000 , ' BX-OP , 0FF000F0 , 01600010 , ' CLZ-OP , 0F9000F0 , 01000050 , ' QADD/SUB-OP , 0FF000F0 , 01200070 , ' BKPT-OP , 0FF00090 , 01000080 , ' SMLAXY-OP , 0FF000B0 , 01200080 , ' SMLAWY-OP , 0FF000B0 , 012000A0 , ' SMULWY-OP , 0FF00090 , 01400080 , ' SMLALXY-OP , 0FF00090 , 01600080 , ' SMULXY-OP , 0 , 0 , ' UNDEFINED-OP , PATTERN MEDIA-OP ( x -- x ) \ Media instructions... 0F800010 , 06000010 , ' PARALLEL-ADD-SUB-OP , 0FF00030 , 06800010 , ' PACK-HALFWORD-OP , 0FA00030 , 06A00010 , ' WORD-SATURATE-OP , 0FF000F0 , 06B00030 , ' REV-OP , 0FF000F0 , 06B000B0 , ' REV16-OP , 0FF000F0 , 06F000B0 , ' REVH-OP , 0FB000F0 , 06A00030 , ' HALF-WORD-SATURATE-OP , 0FF000F0 , 068000B0 , ' SEL-OP , 0F8000F0 , 06800070 , ' EXTEND-OP , 0FF0F090 , 0700F010 , ' DUAL-MUL-OP , 0FF00090 , 07000010 , ' DUAL-MULA-OP , 0FF0F0D0 , 0750F010 , ' MOST-SIG-MUL-OP , 0FF000D0 , 07500010 , ' MOST-SIG-MULA-OP , 0FF000D0 , 075000D0 , ' MOST-SIG-MULA-OP , 0FF00090 , 07400010 , ' LONG-DUAL-MULA-OP , 0FF0F0F0 , 0780F010 , ' USAD8-OP , 0FF000F0 , 07800010 , ' USADA8-OP , 0 , 0 , ' UNDEFINED-OP , PATTERN (disasm-op) ( a-addr x -- a-addr x ) \ Decode op-code x with origin a-addr 0E000090 , 00000090 , ' PATTERN-0E000090-00000090 , 0FB00000 , 03200000 , ' MSR-IMM-OP , 0FB000F0 , 01200000 , ' MSR-REG-OP , 0F900000 , 01000000 , ' MISCELANEOUS-OP , 0DA00000 , 01A00000 , ' MOV-OP , 0D900000 , 01000000 , ' UNDEFINED-OP , \ CMP/TST without S flag 0D900000 , 01100000 , ' CMP-TST-OP , 0C000000 , 00000000 , ' DATA-OP , 0E000010 , 06000010 , ' MEDIA-OP , FD70F000 , F550F000 , ' PLD-OP , 0C000000 , 04000000 , ' MEM-OP , FE500F00 , F8100A00 , ' RFE-OP , FE5F0F00 , F84D0A00 , ' SRS-OP , 0E000000 , 08000000 , ' MULTI-OP , 0E000000 , 0A000000 , ' BRANCH-OP , 0FE00000 , 0C400000 , ' CO-REG2-OP , 0E000000 , 0C000000 , ' CO-MEM-OP , 0F000010 , 0E000000 , ' CDP-OP , 0F000010 , 0E000010 , ' CO-REG-OP , 0F000000 , 0F000000 , ' SWI-OP , : BEGIN-DISASM ( -- ) \ Initialise disassembler state 0 BUFFER C! FALSE UNDEFINED ! FALSE UNPREDICTABLE ! ; : END-DISASM ( -- c-addr u ) \ Return text for disassembly of instruction BUFFER COUNT -TRAILING ; : DISASM-OP ( a-addr x -- a-addr x ) BUFFER C@ >R (disasm-op) 2DROP UNDEFINED @ IF R> BUFFER C! S" UNDEFINED" S. EXIT THEN R> DROP UNPREDICTABLE @ IF TAB. S" \ UNPREDICTABLE" S. THEN ; : H32. ( x -- ) \ Output x as a 32 bit hexadecimal value BASE @ >R HEX 0 <# # # # # # # # # #> S.BL. R> BASE ! ; \ ---------------------------------------------------------------------------- \ Public words for producing disassembly PREVIOUS DEFINITIONS ALSO ARM-DISASSEMBLER : ARM-DISASM-OP ( a-addr x -- c-addr u ) \ Disassemble a single opcode \ Disassemble op-code x with origin a-addr BEGIN-DISASM DISASM-OP END-DISASM ; : ARM-DISASM ( a-addr u -- ) \ Disassemble memory \ Disassemble instructions a-addr thru a-addr+u-1 OVER + SWAP BEGIN 2DUP U> WHILE BEGIN-DISASM DUP H32. BL. DUP @ H32. BL. DUP DUP @ DISASM-OP END-DISASM TYPE CR CELL+ REPEAT 2DROP ; \ ---------------------------------------------------------------------------- PREVIOUS DEFINITIONS DECIMAL