Guest User

thumb_disassm.cpp

a guest
Jul 5th, 2013
127
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //
  2. // instruction format documentation from this source:
  3. // http://bear.ces.cwru.edu/eecs_382/ARM7-TDMI-manual-pt3.pdf
  4. //
  5. #include <stdio.h>
  6.  
  7. // ----------------------------------------------------------------
  8. //
  9. //
  10. // ----------------------------------------------------------------
  11.  
  12. //
  13. #define thsint32   signed       int
  14. #define thsint16   signed short int
  15. #define thuint16 unsigned short int
  16. #define thbyte   unsigned       char
  17. #define thbool                  bool
  18.  
  19. //
  20. #define FINLINE inline
  21.  
  22. // ----------------------------------------------------------------
  23. // the following section defines the bit masks used in decoding the
  24. // instruction formats. the use of namespaces is purely because I
  25. // like fully qualified enums since it looks more readable.
  26. // ----------------------------------------------------------------
  27.  
  28. //
  29. namespace mask
  30. {
  31.     enum
  32.     {
  33.         //
  34.         insdsc1    = 0xE000,    // 1110000000000000
  35.         insdsc2    = 0x1C00,    // 0001110000000000
  36.         insdsc3    = 0x0200,    // 0000001000000000
  37.         insdsc4    = 0x1000,    // 0001000000000000
  38.         insdsc5    = 0x1000,    // 0001000000000000
  39.         insdsc6    = 0x0400,    // 0000010000000000
  40.         insdsc7    = 0x1000,    // 0001000000000000
  41.         insdsc8    = 0x1000,    // 0001000000000000
  42.  
  43.         //
  44.         ins01opdsc = 0x1800,    // 0001100000000000
  45.         ins02opdsc = 0x0200,    // 0000000100000000
  46.         ins03opdsc = 0x1800,    // 0001100000000000
  47.         ins04opdsc = 0x03C0,    // 0000001111000000
  48.         ins05opdsc = 0x0300,    // 0000001100000000
  49.  
  50.         //
  51.         ins16cond  = 0x0F00,    // 0000111100000000
  52.     };
  53. };
  54.  
  55. //
  56. #define INSDSC1( x ) (x<<13)
  57. namespace insdsc1
  58. {
  59.     enum
  60.     {
  61.         ins00   = INSDSC1( 0x0 ),
  62.         ins03   = INSDSC1( 0x1 ),
  63.         ins04   = INSDSC1( 0x2 ),
  64.         ins09   = INSDSC1( 0x3 ),
  65.         ins10   = INSDSC1( 0x4 ),
  66.         ins12   = INSDSC1( 0x5 ),
  67.         ins15   = INSDSC1( 0x6 ),
  68.         ins18   = INSDSC1( 0x7 )
  69.     };
  70. };
  71.  
  72. //
  73. #define INSDSC2( x ) (x<<10)
  74. namespace insdsc2
  75. {
  76.     enum
  77.     {
  78.         ins4     = INSDSC2( 0x0 ),
  79.         ins5     = INSDSC2( 0x1 ),
  80.         ins6_a   = INSDSC2( 0x2 ),
  81.         ins6_b   = INSDSC2( 0x3 ),
  82.         dsc7_8_a = INSDSC2( 0x4 ),
  83.         dsc7_8_b = INSDSC2( 0x5 ),
  84.         dsc7_8_c = INSDSC2( 0x6 ),
  85.         dsc7_8_d = INSDSC2( 0x7 ),
  86.     };
  87. };
  88.  
  89. //
  90. #define INS01OP( x ) (x<<11)
  91. namespace ins01op
  92. {
  93.     enum
  94.     {
  95.         lsl     = INS01OP( 0x0 ),
  96.         lsr     = INS01OP( 0x1 ),
  97.         asr     = INS01OP( 0x2 ),
  98.         ins02op = INS01OP( 0x3 )
  99.     };
  100. };
  101.  
  102. //
  103. #define INS02OP( x ) (x<<8)
  104. namespace ins02op
  105. {
  106.     enum
  107.     {
  108.         add     = INS02OP( 0x0 ),
  109.         sub     = INS02OP( 0x1 )
  110.     };
  111. };
  112.  
  113. //
  114. #define INS03OP( x ) (x<<11)
  115. namespace ins03op
  116. {
  117.     enum
  118.     {
  119.         mov     = INS03OP( 0x0 ),
  120.         cmp     = INS03OP( 0x1 ),
  121.         add     = INS03OP( 0x2 ),
  122.         sub     = INS03OP( 0x3 )
  123.     };
  124. };
  125.  
  126. //
  127. #define INS04OP( x ) (x<<6)
  128. namespace ins4op
  129. {
  130.     enum
  131.     {
  132.         and     = INS04OP( 0x0 ),
  133.         eor     = INS04OP( 0x1 ),
  134.         lsl     = INS04OP( 0x2 ),
  135.         lsr     = INS04OP( 0x3 ),
  136.         asr     = INS04OP( 0x4 ),
  137.         adc     = INS04OP( 0x5 ),
  138.         sbc     = INS04OP( 0x6 ),
  139.         ror     = INS04OP( 0x7 ),
  140.         tst     = INS04OP( 0x8 ),
  141.         neg     = INS04OP( 0x9 ),
  142.         cmp     = INS04OP( 0xA ),
  143.         cmn     = INS04OP( 0xB ),
  144.         orr     = INS04OP( 0xC ),
  145.         mul     = INS04OP( 0xD ),
  146.         bic     = INS04OP( 0xE ),
  147.         mvn     = INS04OP( 0xF ),
  148.     };
  149. };
  150.  
  151. //
  152. #define INS05OP( x ) (x<<8)
  153. namespace ins5op
  154. {
  155.     enum
  156.     {
  157.         add     = INS05OP( 0 ),
  158.         cmp     = INS05OP( 1 ),
  159.         mov     = INS05OP( 2 ),
  160.         bx      = INS05OP( 3 ),
  161.     };
  162. };
  163.  
  164. //
  165. #define INS16COND( x ) (x<<8)
  166. namespace ins16cond
  167. {
  168.     enum
  169.     {
  170.         beq     = INS16COND( 0x0 ),
  171.         bne     = INS16COND( 0x1 ),
  172.         bcs     = INS16COND( 0x2 ),
  173.         bcc     = INS16COND( 0x3 ),
  174.         bmi     = INS16COND( 0x4 ),
  175.         bpl     = INS16COND( 0x5 ),
  176.         bvs     = INS16COND( 0x6 ),
  177.         bvc     = INS16COND( 0x7 ),
  178.         bhi     = INS16COND( 0x8 ),
  179.         bls     = INS16COND( 0x9 ),
  180.         bge     = INS16COND( 0xA ),
  181.         blt     = INS16COND( 0xB ),
  182.         bgt     = INS16COND( 0xC ),
  183.         ble     = INS16COND( 0xD ),
  184.         ins17op = INS16COND( 0xF ),
  185.     };
  186. };
  187.  
  188. // ----------------------------------------------------------------
  189. // the following code is for the instruction format decoders. they
  190. // are declared in reverse so as to avoid forward declarations.
  191. // these should all be forced inline where possible since they are
  192. // defined as a sepourate function only for clarity.
  193. // ----------------------------------------------------------------
  194.  
  195. // decode format 19 instructions
  196. static FINLINE
  197. void decodeF19( thuint16 *stream )
  198. {
  199.     // decode operand
  200.     thsint32 s11 = (*stream);           // 0000011111111111
  201.     //
  202.     if ( *stream & 0x0800 ) // H set
  203.     {
  204. //      s11 = (s11 << 19) >> 4;
  205.         printf( "bl1 \t#%d\n", s11 );
  206.     }
  207.     else
  208.     {
  209. //      s11 = (s11 << 19) >> 15;
  210.         printf( "bl2 \t#%d\n", s11 );
  211.     }
  212. }
  213.  
  214. // decode format 18 instructions
  215. static FINLINE
  216. void decodeF18( thuint16 *stream )
  217. {
  218.     // decode operand
  219.     thsint16 s11 = (*stream<<5)>>4; // 0000011111111111 signed
  220.     //
  221.     printf( "b   \t#%d\n", s11 );
  222. }
  223.  
  224. // decode format 17 instructions
  225. static FINLINE
  226. void decodeF17( thuint16 *stream )
  227. {
  228.     //
  229.     thbyte u8 = *stream & 0x00FF;
  230.     //
  231.     printf( "swi \t#%d\n", u8 );
  232. }
  233.  
  234. // decode format 16 instructions
  235. static FINLINE
  236. void decodeF16( thuint16 *stream )
  237. {
  238.     // sign extended shift
  239.     thsint16 s8 = (*stream<<8)>>6;  // signed
  240.     //
  241.     switch ( *stream & mask::ins16cond )
  242.     {
  243.     case ( ins16cond::beq ):
  244.         //
  245.         printf( "beq \t%d\n", s8 );
  246.         break;
  247.     case ( ins16cond::bne ):
  248.         //
  249.         printf( "bne \t%d\n", s8 );
  250.         break;
  251.     case ( ins16cond::bcs ):
  252.         //
  253.         printf( "bcs \t%d\n", s8 );
  254.         break;
  255.     case ( ins16cond::bcc ):
  256.         //
  257.         printf( "bcc \t%d\n", s8 );
  258.         break;
  259.     case ( ins16cond::bmi ):
  260.         //
  261.         printf( "bmi \t%d\n", s8 );
  262.         break;
  263.     case ( ins16cond::bpl ):
  264.         //
  265.         printf( "bpl \t%d\n", s8 );
  266.         break;
  267.     case ( ins16cond::bvs ):
  268.         //
  269.         printf( "bvs \t%d\n", s8 );
  270.         break;
  271.     case ( ins16cond::bvc ):
  272.         //
  273.         printf( "bvc \t%d\n", s8 );
  274.         break;
  275.     case ( ins16cond::bhi ):
  276.         //
  277.         printf( "bhi \t%d\n", s8 );
  278.         break;
  279.     case ( ins16cond::bls ):
  280.         //
  281.         printf( "bls \t%d\n", s8 );
  282.         break;
  283.     case ( ins16cond::bge ):
  284.         //
  285.         printf( "bgt \t%d\n", s8 );
  286.         break;
  287.     case ( ins16cond::blt ):
  288.         //
  289.         printf( "blt \t%d\n", s8 );
  290.         break;
  291.     case ( ins16cond::bgt ):
  292.         //
  293.         printf( "bgt \t%d\n", s8 );
  294.         break;
  295.     case ( ins16cond::ble ):
  296.         //
  297.         printf( "ble \t%d\n", s8 );
  298.         break;
  299.     case ( ins16cond::ins17op ):
  300.         // format 17 decode
  301.         decodeF17( stream );
  302.         break;
  303.     }
  304. }
  305.  
  306. // decode format 15 instructions
  307. static FINLINE
  308. void decodeF15( thuint16 *stream )
  309. {
  310.     thbyte rb = (*stream >> 8) & 0x07;  // 0000011100000000
  311.     //
  312.     if ( *stream & 0x0800 )
  313.     {
  314.         printf( "ldmia\tr%d!, { \n", rb );
  315.         if ( *stream & 0x01 ) { printf( "r0 " ); }
  316.         if ( *stream & 0x02 ) { printf( "r1 " ); }
  317.         if ( *stream & 0x04 ) { printf( "r2 " ); }
  318.         if ( *stream & 0x08 ) { printf( "r3 " ); }
  319.         if ( *stream & 0x10 ) { printf( "r4 " ); }
  320.         if ( *stream & 0x20 ) { printf( "r5 " ); }
  321.         if ( *stream & 0x40 ) { printf( "r6 " ); }
  322.         if ( *stream & 0x80 ) { printf( "r7 " ); }
  323.         printf( "}\n" );
  324.     }
  325.     else
  326.     {
  327.         //
  328.         printf( "stmia\tr%d!, { \n", rb );
  329.         if ( *stream & 0x01 ) { printf( "r0 " ); }
  330.         if ( *stream & 0x02 ) { printf( "r1 " ); }
  331.         if ( *stream & 0x04 ) { printf( "r2 " ); }
  332.         if ( *stream & 0x08 ) { printf( "r3 " ); }
  333.         if ( *stream & 0x10 ) { printf( "r4 " ); }
  334.         if ( *stream & 0x20 ) { printf( "r5 " ); }
  335.         if ( *stream & 0x40 ) { printf( "r6 " ); }
  336.         if ( *stream & 0x80 ) { printf( "r7 " ); }
  337.         printf( "}\n" );
  338.     }
  339. }
  340.  
  341. // decode format 14 instructions
  342. static FINLINE
  343. void decodeF14( thuint16 *stream )
  344. {
  345.     // decode operands
  346.     if (! (*stream & 0x0800) )  // L set
  347.     {
  348.         printf( "push \t{ " );
  349.         if ( *stream & 0x01 ) { printf( "r0 " ); }
  350.         if ( *stream & 0x02 ) { printf( "r1 " ); }
  351.         if ( *stream & 0x04 ) { printf( "r2 " ); }
  352.         if ( *stream & 0x08 ) { printf( "r3 " ); }
  353.         if ( *stream & 0x10 ) { printf( "r4 " ); }
  354.         if ( *stream & 0x20 ) { printf( "r5 " ); }
  355.         if ( *stream & 0x40 ) { printf( "r6 " ); }
  356.         if ( *stream & 0x80 ) { printf( "r7 " ); }
  357.         //
  358.         if ( *stream & 0x0100 ) // R set
  359.         {
  360.             printf( "lr " );
  361.         }
  362.         printf( "}\n" );
  363.     }
  364.     else
  365.     {
  366.         printf( "pop \t{ " );
  367.         if ( *stream & 0x01 ) { printf( "r0 " ); }
  368.         if ( *stream & 0x02 ) { printf( "r1 " ); }
  369.         if ( *stream & 0x04 ) { printf( "r2 " ); }
  370.         if ( *stream & 0x08 ) { printf( "r3 " ); }
  371.         if ( *stream & 0x10 ) { printf( "r4 " ); }
  372.         if ( *stream & 0x20 ) { printf( "r5 " ); }
  373.         if ( *stream & 0x40 ) { printf( "r6 " ); }
  374.         if ( *stream & 0x80 ) { printf( "r7 " ); }
  375.         //
  376.         if ( *stream & 0x0100 ) // R set
  377.         {
  378.             printf( "lr " );
  379.         }
  380.         printf( "}\n" );
  381.     }
  382. }
  383.  
  384. // decode format 13 instructions
  385. static FINLINE
  386. void decodeF13( thuint16 *stream )
  387. {
  388.     // decode register operands
  389.     thuint16 u7 = (*stream << 2 ) & 0x01FC; // 0000000001111111 unsigned
  390.     //
  391.     if ( *stream & 0x0080 ) // S set
  392.     {
  393.         printf( "sub \tsp, #%d\n", u7 );
  394.     }
  395.     else
  396.     {
  397.         printf( "add \tsp, #%d\n", u7 );
  398.     }
  399. }
  400.  
  401. // decode format 12 instructions
  402. static FINLINE
  403. void decodeF12( thuint16 *stream )
  404. {
  405.     // decode register operands
  406.     thuint16 u8 = (*stream << 2) & 0x03FC;  // 0000000011111111 unsigned
  407.     thbyte   rd = (*stream >> 8) & 0x0007;  // 0000011100000000
  408.     //
  409.     if ( *stream & 0x0800 ) // SP set
  410.     {
  411.         printf( "add \tr%d, sp, #%d\n", rd, u8 );
  412.     }
  413.     else
  414.     {
  415.         printf( "add \tr%d, pc, #%d\n", rd, u8 );
  416.     }
  417. }
  418.  
  419. // decode format 11 instructions
  420. static FINLINE
  421. void decodeF11( thuint16 *stream )
  422. {
  423.     // decode register operands
  424.     thuint16 u8 = (*stream << 2) & 0x03FC;  // 0000000011111111 unsigned
  425.     thbyte   rd = (*stream >> 8) & 0x0007;  // 0000011100000000
  426.     //
  427.     if ( *stream & 0x0800 ) // L set
  428.     {
  429.         printf( "LDR \tr%d, [sp, #%d]\n", rd, u8 );
  430.     }
  431.     else
  432.     {
  433.         printf( "STR \tr%d, [sp, #%d]\n", rd, u8 );
  434.     }
  435. }
  436.  
  437. // decode format 10 instructions
  438. static FINLINE
  439. void decodeF10( thuint16 *stream )
  440. {
  441.     // decode register operands
  442.     thbyte rd = (*stream     ) & 0x07;  // 0000000000000111
  443.     thbyte rb = (*stream >> 3) & 0x07;  // 0000000000111000
  444.     thbyte u5 = (*stream >> 5) & 0x3E;  // 0000011111000000 unsigned
  445.     //
  446.     if ( *stream & 0x0800 ) // L set
  447.     {
  448.         printf( "LDRH\tr%d, [r%d, #%d]\n", rd, rb, u5 );
  449.     }
  450.     else
  451.     {
  452.         printf( "STRH\tr%d, [r%d, #%d]\n", rd, rb, u5 );
  453.     }
  454. }
  455.  
  456. // decode format 9 instructions
  457. static FINLINE
  458. void decodeF09( thuint16 *stream )
  459. {
  460.     // decode register operands
  461.     thbyte   rd = (*stream     ) & 0x07;    // 0000000000000111
  462.     thbyte   rb = (*stream >> 3) & 0x07;    // 0000000000111000
  463.     thuint16 u5 = (*stream >> 4) & 0x7C;    // 0000011111000000 unsigned
  464.     //
  465.     switch
  466.     (
  467.         (((*stream & 0x0800)!=0)<<1) +  // L set
  468.          ((*stream & 0x1000)!=0)        // B set
  469.     )
  470.     {
  471.     case ( 0 ):
  472.         printf( "str \tr%d, [r%d, #%d]\n", rd, rb, u5 );
  473.         break;
  474.     case ( 1 ):
  475.         printf( "strb\tr%d, [r%d, #%d]\n", rd, rb, u5 );
  476.         break;
  477.     case ( 2 ):
  478.         printf( "ldr \tr%d, [r%d, #%d]\n", rd, rb, u5 );
  479.         break;
  480.     case ( 3 ):
  481.         printf( "ldrb\tr%d, [r%d, #%d]\n", rd, rb, u5 );
  482.         break;
  483.     }
  484. }
  485.  
  486. // decode format 8 instructions
  487. static FINLINE
  488. void decodeF08( thuint16 *stream )
  489. {
  490.     // decode register operands
  491.     thbyte rd = (*stream     ) & 0x07;  // 0000000000000111
  492.     thbyte rb = (*stream >> 3) & 0x07;  // 0000000000111000
  493.     thbyte ro = (*stream >> 6) & 0x07;  // 0000000111000000
  494.     //
  495.     if ( *stream & 0x0800 ) // H set
  496.     {
  497.  
  498.     }
  499.     if ( *stream & 0x0400 ) // S set
  500.     {
  501.     }
  502.     //
  503.     printf( "[format 8]\n" );
  504. }
  505.  
  506. // decode format 7 instructions
  507. static FINLINE
  508. void decodeF07( thuint16 *stream )
  509. {
  510.     // decode register operands
  511.     thbyte rd = (*stream     ) & 0x07;  // 0000000000000111
  512.     thbyte rb = (*stream >> 3) & 0x07;  // 0000000000111000
  513.     thbyte ro = (*stream >> 6) & 0x07;  // 0000000111000000
  514.     //
  515.     switch
  516.     (
  517.         (((*stream & 0x0800)!=0)<<1) +  // L set
  518.          ((*stream & 0x0400)!=0)        // B set
  519.     )
  520.     {
  521.     case ( 0 ):
  522.         printf( "str \tr%d, [r%d, r%d]\n", rd, rb, ro );
  523.         break;
  524.     case ( 1 ):
  525.         printf( "strb\tr%d, [r%d, r%d]\n", rd, rb, ro );
  526.         break;
  527.     case ( 2 ):
  528.         printf( "ldr \tr%d, [r%d, r%d]\n", rd, rb, ro );
  529.         break;
  530.     case ( 3 ):
  531.         printf( "ldrb\tr%d, [r%d, r%d]\n", rd, rb, ro );
  532.         break;
  533.     }
  534. }
  535.  
  536. // decode format 6 instructions
  537. static FINLINE
  538. void decodeF06( thuint16 *stream )
  539. {
  540.     // decode register operands
  541.     thbyte   rd = (*stream >> 8) & 0x07;    // 0000011100000000
  542.     thuint16 u8 = (*stream     ) & 0xFF;    // 0000000011111111 unsigned
  543.              u8 = u8 << 2;
  544.     //
  545.     printf( "ldr \tr%d, [pc, #%d]\n", rd, u8 );
  546. }
  547.  
  548. // decode format 5 instructions
  549. static FINLINE
  550. void decodeF05( thuint16 *stream )
  551. {
  552.     // decode register operands
  553.     thbyte rd =  *stream       & 0x07;  // 0000000000000111
  554.     thbyte rs = (*stream >> 3) & 0x07;  // 0000000000111000
  555.     //
  556.     if ( *stream & 0x80 ) // H1 Set
  557.     {
  558.     }
  559.     if ( *stream & 0x40 ) // H2 Set
  560.     {
  561.     }
  562.     //
  563.     switch ( *stream & mask::ins05opdsc )
  564.     {
  565.     case ( ins5op::add ):
  566.         printf( "add \t?r%d, ?r%d\n", rd, rs );
  567.         //
  568.         break;
  569.     case ( ins5op::cmp ):
  570.         printf( "cmp \t?r%d, ?r%d\n", rd, rs );
  571.         //
  572.         break;
  573.     case ( ins5op::mov ):
  574.         printf( "mov \t?r%d, ?r%d\n", rd, rs );
  575.         //
  576.         break;
  577.     case ( ins5op::bx  ):
  578.         printf( "bx  \t?r%d, ?r%d\n", rd, rs );
  579.         //
  580.         break;
  581.     }
  582. }
  583.  
  584. // decode format 4 instructions
  585. static FINLINE
  586. void decodeF04( thuint16 *stream )
  587. {
  588.     // decode register operands
  589.     thbyte rd =  *stream       & 0x07;  // 0000000000000111
  590.     thbyte rs = (*stream >> 3) & 0x07;  // 0000000000111000
  591.     // branch based on opcode
  592.     switch ( *stream & mask::ins04opdsc )
  593.     {
  594.     case ( ins4op::and ):
  595.         // [rd = rd AND rs]
  596.         printf( "and \tr%d, r%d\n", rd, rs );
  597.         break;
  598.     case ( ins4op::eor ):
  599.         // [rd = rd XOR rs]
  600.         printf( "eor \tr%d, r%d\n", rd, rs );
  601.         break;
  602.     case ( ins4op::lsl ):
  603.         // [rd = rd << rs]
  604.         printf( "lsl \tr%d, r%d\n", rd, rs );
  605.         break;
  606.     case ( ins4op::lsr ):
  607.         // [rd = rd >> rs]
  608.         printf( "lsr \tr%d, r%d\n", rd, rs );
  609.         break;
  610.     case ( ins4op::asr ):
  611.         // [rd = rd AND rs]
  612.         printf( "asr \tr%d, r%d\n", rd, rs );
  613.         break;
  614.     case ( ins4op::adc ):
  615.         // [rd = rd + rs + c-bit]
  616.         printf( "adc \tr%d, r%d\n", rd, rs );
  617.         break;
  618.     case ( ins4op::sbc ):
  619.         // [rd = rd - rs - NOT c-bit]
  620.         printf( "sbc \tr%d, r%d\n", rd, rs );
  621.         break;
  622.     case ( ins4op::ror ):
  623.         // [rd = rd ROR rs]
  624.         printf( "ror \tr%d, r%d\n", rd, rs );
  625.         break;
  626.     case ( ins4op::tst ):
  627.         // set condition codes on [rd AND rs]
  628.         printf( "tst \tr%d, r%d\n", rd, rs );
  629.         break;
  630.     case ( ins4op::neg ):
  631.         // [rd = -rs]
  632.         printf( "neg \tr%d, r%d\n", rd, rs );
  633.         break;
  634.     case ( ins4op::cmp ):
  635.         // set condition codes on [rd - rs]
  636.         printf( "cmp \tr%d, r%d\n", rd, rs );
  637.         break;
  638.     case ( ins4op::cmn ):
  639.         // set condition codes on [rd + rs]
  640.         printf( "cmn \tr%d, r%d\n", rd, rs );
  641.         break;
  642.     case ( ins4op::orr ):
  643.         // [rd = rd OR rs]
  644.         printf( "orr \tr%d, r%d\n", rd, rs );
  645.         break;
  646.     case ( ins4op::mul ):
  647.         // [rd = rd * rs]
  648.         printf( "mul \tr%d, r%d\n", rd, rs );
  649.         break;
  650.     case ( ins4op::bic ):
  651.         // [rd = rd AND NOT rs]
  652.         printf( "bic \tr%d, r%d\n", rd, rs );
  653.         break;
  654.     case ( ins4op::mvn ):
  655.         // [rd = NOT rs]
  656.         printf( "mvn \tr%d, r%d\n", rd, rs );
  657.         break;
  658.     }
  659. }
  660.  
  661. // decode format 3 instructions
  662. static FINLINE
  663. void decodeF03( thuint16 *stream )
  664. {
  665.     // decode operands
  666.     thbyte rd = (*stream >> 8 ) & 0x0007;   // 0000011100000000
  667.     thbyte u8 =  *stream        & 0x00FF;   // 0000000011111111 unsigned
  668.     // decode opcode
  669.     switch ( *stream & mask::ins03opdsc )
  670.     {
  671.     case ( ins03op::mov ):
  672.         // [rd = o8]
  673.         printf( "mov \tr%d, #%d\n", rd, u8 );
  674.         break;
  675.     case ( ins03op::cmp ):
  676.         // compare contentse of rd with o8
  677.         printf( "cmp \tr%d, #%d\n", rd, u8 );
  678.         break;
  679.     case ( ins03op::add ):
  680.         // [rd = rd + o8]
  681.         printf( "add \tr%d, #%d\n", rd, u8 );
  682.         break;
  683.     case ( ins03op::sub ):
  684.         // [rd = rd - o8]
  685.         printf( "sub \tr%d, #%d\n", rd, u8 );
  686.         break;
  687.     }
  688. }
  689.  
  690. // decode format 2 instructions
  691. static FINLINE
  692. void decodeF02( thuint16 *stream )
  693. {
  694.     // decode the operands
  695.     thbyte rd =  *stream        & 0x07; // 0000000000000111
  696.     thbyte rs = (*stream >> 3 ) & 0x07; // 0000000000111000
  697.     thbyte u3 = (*stream >> 6 ) & 0x07; // 0000000111000000 unsigned
  698.     // decode the I flag
  699.     if ( *stream & 0x0200 )             // 0000010000000000
  700.     {
  701.         // index into rs
  702.     }
  703.     // decode the opcode
  704.     switch ( *stream & mask::ins02opdsc )
  705.     {
  706.     case ( ins02op::add ):
  707.         // [rd = rs + rn]
  708.         printf( "add \tr%d, r%d, ?r%d\n", rd, rs, u3 );
  709.         break;
  710.     case ( ins02op::sub ):
  711.         // [rd = rs - rn]
  712.         printf( "sub \tr%d, r%d, ?r%d\n", rd, rs, u3 );
  713.         break;
  714.     };
  715. }
  716.  
  717. // decode format 1 instructions
  718. static FINLINE
  719. void decodeF01( thuint16 *stream )
  720. {
  721.     // decode register operands
  722.     thbyte rd =  *stream        & 0x0007;   // 0000000000000111
  723.     thbyte rs = (*stream >> 3 ) & 0x0007;   // 0000000000111000
  724.     thbyte u5 = (*stream >> 6 ) & 0x001F;   // 0000011111000000 unsigned
  725.     // decode the opcode
  726.     switch ( *stream & mask::ins01opdsc )
  727.     {
  728.     case ( ins01op::lsl ):
  729.         // [rd = rs << o5] shift
  730.         printf( "lsl \tr%d, r%d, #%d\n", rd, rs, u5 );
  731.         break;
  732.     case ( ins01op::lsr ):
  733.         // [rd = rs >> o5] logical
  734.         printf( "lsr \tr%d, r%d, #%d\n", rd, rs, u5 );
  735.         break;
  736.     case ( ins01op::asr ):
  737.         // [rd = rs >> o5] arythmetic
  738.         printf( "asr \tr%d, r%d, #%d\n", rd, rs, u5 );
  739.         break;
  740.  
  741.     // this is format 2
  742.     case ( ins01op::ins02op ):
  743.         decodeF02( stream );
  744.     }
  745. }
  746.  
  747. // ----------------------------------------------------------------
  748. //
  749. //
  750. // ----------------------------------------------------------------
  751.  
  752. //
  753. static FINLINE
  754. void decode( thuint16 *stream )
  755. {
  756.     //
  757.     thuint16 ins = (*stream);
  758.     // level 1 descriminator
  759.     switch ( ins & mask::insdsc1 )
  760.     {
  761.     case ( insdsc1::ins00 ):
  762.         // format 1 decode
  763.         decodeF01( stream );
  764.         break;
  765.     case ( insdsc1::ins03 ):
  766.         // format 3 decode
  767.         decodeF03( stream );
  768.         break;
  769.     case ( insdsc1::ins04 ):
  770.         // level 2 descriminator
  771.         switch ( ins & mask::insdsc2 )
  772.         {
  773.         case ( insdsc2::ins4 ):
  774.             // format 4 decode
  775.             decodeF04( stream );
  776.             break;
  777.         case ( insdsc2::ins5 ):
  778.             // format 5 decode
  779.             decodeF05( stream );
  780.             break;
  781.         case ( insdsc2::ins6_a ):
  782.         case ( insdsc2::ins6_b ):
  783.             // format 6 decode
  784.             decodeF06( stream );
  785.             break;
  786.         case ( insdsc2::dsc7_8_a ):
  787.         case ( insdsc2::dsc7_8_b ):
  788.         case ( insdsc2::dsc7_8_c ):
  789.         case ( insdsc2::dsc7_8_d ):
  790.             // stage 3 descriminator
  791.             if (! (ins & mask::insdsc3) )
  792.                 // format 7
  793.                 decodeF07( stream );
  794.             else
  795.                 // format 8
  796.                 decodeF08( stream );
  797.             break;
  798.         }
  799.         break;
  800.     case ( insdsc1::ins09 ):
  801.         // format 9 decode
  802.         decodeF09( stream );
  803.         break;
  804.     case ( insdsc1::ins10 ):
  805.         // stage 4 descriminator
  806.         if (! (ins & mask::insdsc4) )
  807.             // format 10 decode
  808.             decodeF10( stream );
  809.         else
  810.             // format 11 decode
  811.             decodeF11( stream );
  812.         break;
  813.     case ( insdsc1::ins12 ):
  814.         // stage 5 descriminator
  815.         if (! (ins & mask::insdsc5) )
  816.             // format 12 decode
  817.             decodeF12( stream );
  818.         else
  819.         {
  820.             // stage 6 descriminator
  821.             if (! (ins & mask::insdsc6) )
  822.                 // format 13 decode
  823.                 decodeF13( stream );
  824.             else
  825.                 // format 14 decode
  826.                 decodeF14( stream );
  827.         }
  828.         break;
  829.     case ( insdsc1::ins15 ):
  830.         // stage 7 descriminator
  831.         if (! (ins & mask::insdsc7) )
  832.             // format 15 decode
  833.             decodeF15( stream );
  834.         else
  835.             // format 16 decode
  836.             decodeF16( stream );
  837.         break;
  838.     case ( insdsc1::ins18 ):
  839.         // stage 8 descriminator
  840.         if (! (ins & mask::insdsc8) )
  841.             // format 18 decode
  842.             decodeF18( stream );
  843.         else
  844.             // format 19 decode
  845.             decodeF19( stream );
  846.         break;
  847.     }
  848.  
  849. }
  850.  
  851. unsigned char data[] =
  852. {
  853.     0x80,0xB5,0x00,0xAF,0x02,0x23,0x18,0x1C,0xBD,0x46,0x80,0xBC,0x02,0xBC,0x08,0x47,
  854.     0x80,0xB5,0x82,0xB0,0x00,0xAF,0x78,0x60,0x7B,0x68,0x5B,0x00,0x18,0x1C,0xBD,0x46,
  855.     0x02,0xB0,0x80,0xBC,0x02,0xBC,0x08,0x47,0x80,0xB5,0x84,0xB0,0x00,0xAF,0x78,0x60,
  856.     0x3B,0x1C,0x08,0x33,0x01,0x22,0x1A,0x60,0x3B,0x1C,0x08,0x33,0x00,0x22,0x5A,0x60,
  857.     0x3B,0x1C,0x08,0x33,0x7A,0x68,0x92,0x00,0xD3,0x58,0x18,0x1C,0xBD,0x46,0x04,0xB0,
  858.     0x80,0xBC,0x02,0xBC,0x08,0x47,0xC0,0x46,0x80,0xB5,0x82,0xB0,0x00,0xAF,0x00,0x23,
  859.     0x7B,0x60,0x05,0xE0,0xFF,0xF7,0xCC,0xFF,0x03,0x1C,0x7A,0x68,0xD3,0x18,0x7B,0x60,
  860.     0x7B,0x68,0x09,0x2B,0xF6,0xDD,0x7B,0x68,0x18,0x1C,0xBD,0x46,0x02,0xB0,0x80,0xBC,
  861.     0x02,0xBC,0x08,0x47
  862. };
  863.  
  864. //
  865. int main( int argc, char** args )
  866. {
  867.     int i=0;
  868.     thuint16 *ptr = (thuint16*) data;
  869.     while ( ptr < (thuint16*)(data+sizeof(data)) )
  870.     {
  871.         printf( " %4X:  %04X    ", i, *ptr );
  872.         decode( ptr );
  873.         ptr++;
  874.         i += 2;
  875.     }
  876.     getchar( );
  877.     return 0;
  878. }
RAW Paste Data