home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume35 / dis / part02 / decode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-04  |  4.0 KB  |  224 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "formats.h"
  5.  
  6. /*
  7.  * Given 32 bit instruction to decode, and current program counter,
  8.  * put a string in "buf" that represents the decoded intstruction.
  9.  * Hopefully, this is enough separation from the executable image
  10.  * format for this to be re-usable if/when Sun switches to another
  11.  * format (ELF?).
  12.  */
  13. char *
  14. decode_instr(instr, pc, buf)
  15. unsigned long   instr, pc; 
  16. char           *buf;
  17. {
  18.     struct format1  *instr1;
  19.     struct format2  *instr2;
  20.  
  21.     char *user_mode(), *bicc(), *fbfcc(), *cbcc();
  22.     void  memory(), arithmetic();
  23.  
  24.     instr1 = (struct format1  *)&instr;
  25.  
  26.     /*
  27.      * handle simpler instructions here inside a switch, call
  28.      * a function to do lookups for memory load/stores and
  29.      * the arithmetic instructions.
  30.      * This switch() is essentially tables F-1 and F-2 of
  31.      * "The SPARC Architecture Manual: Version 8".
  32.      */
  33.     switch (instr1->op) {
  34.     case 0:
  35.         /* op == 0, UNIMP, Bicc, SETHI, NOP, FBfcc, CBccc */
  36.         instr2 = (struct format2  *)&instr;
  37.         switch (instr2->op2) {
  38.         case 0:
  39.             strcpy(buf, "UNIMP");
  40.             break;
  41.         case 1:
  42.             strcpy(buf, "unimplemented, op2 = 1");
  43.             break;
  44.         case 2:
  45.             /* BRANCH On Integer Condition Codes */
  46.             sprintf(buf, "%s 0x%08x", bicc(instr2->rd),
  47.                 (unsigned int)pc + (unsigned int)(4 * (unsigned int)(SIGN_EXT22(instr2->imm22))));
  48.             break;
  49.         case 3:
  50.             strcpy(buf, "unimplemented, op2 = 3");
  51.             break;
  52.         case 4:
  53.             /* SETHI */
  54.             if (instr2->rd == 0 && instr2->imm22 == 0)
  55.                 sprintf(buf, "nop");
  56.             else
  57.                 sprintf(buf, "sethi %%hi(0x%x) %s",
  58.                      instr2->imm22 << 10, user_mode(instr2->rd));
  59.             break;
  60.         case 5:
  61.             strcpy(buf, "unimplemented, op2 = 5");
  62.             break;
  63.         case 6:
  64.             /* BRANCH On Floating-point Condition Codes */
  65.             sprintf(buf, "%s 0x%08x", fbfcc(instr2->rd),
  66.                 (unsigned int)pc + (unsigned int)(4 * (unsigned int)SIGN_EXT22(instr2->imm22)));
  67.             break;
  68.         case 7:
  69.             /* BRANCH On Coprocessor Condition Codes */
  70.             sprintf(buf, "%s 0x%08x", cbcc(instr2->rd),
  71.                 (unsigned int)pc + (unsigned int)(4 * (unsigned int)SIGN_EXT22(instr2->imm22)));
  72.             break;
  73.         default:
  74.             /* bogus instruction */
  75.             sprintf(buf, "bogus instruction: op = %d, op2 = %d",
  76.                 instr2->op, instr2->op2);
  77.             break;
  78.         }
  79.  
  80.         break;
  81.  
  82.     case 1:
  83.         /* op == 1, CALL AND LINK */
  84.         sprintf(buf, "call 0x%08x", 4 * instr1->disp30 + (unsigned int)pc);
  85.         break;
  86.  
  87.     case 2:
  88.         /* op == 2, Arithmetic, logical, shift, misc */
  89.         arithmetic(instr, buf);
  90.         break;
  91.  
  92.     case 3:
  93.         /* op == 3, Memory Instructions */
  94.         memory(instr, buf);
  95.         break;
  96.  
  97.     default:
  98.         /* bogus */
  99.         sprintf(buf, "bogus instruction: op = %d, bad value",
  100.             instr1->op);
  101.     }
  102.  
  103.  
  104.     return buf;
  105. }
  106.  
  107. static char     bozo[32];
  108.  
  109. /*
  110.  * take a register number and transliterate it into a "user-mode" type of
  111.  * register name: the user mode is the name inside the current "window"
  112.  */
  113. char *
  114. user_mode(rd)
  115. unsigned int rd;
  116. {
  117.     char           *ptr;
  118.  
  119.     switch (rd) {
  120.     case 0:
  121.         ptr = "%g0";
  122.         break;
  123.     case 1:
  124.         ptr = "%g1";
  125.         break;
  126.     case 2:
  127.         ptr = "%g2";
  128.         break;
  129.     case 3:
  130.         ptr = "%g3";
  131.         break;
  132.     case 4:
  133.         ptr = "%g4";
  134.         break;
  135.     case 5:
  136.         ptr = "%g5";
  137.         break;
  138.     case 6:
  139.         ptr = "%g6";
  140.         break;
  141.     case 7:
  142.         ptr = "%g7";
  143.         break;
  144.     case 8:
  145.         ptr = "%o0";
  146.         break;
  147.     case 9:
  148.         ptr = "%o1";
  149.         break;
  150.     case 10:
  151.         ptr = "%o2";
  152.         break;
  153.     case 11:
  154.         ptr = "%o3";
  155.         break;
  156.     case 12:
  157.         ptr = "%o4";
  158.         break;
  159.     case 13:
  160.         ptr = "%o5";
  161.         break;
  162.     case 14:
  163.         ptr = "%sp";
  164.         break;
  165.     case 15:
  166.         ptr = "%o7";
  167.         break;
  168.     case 16:
  169.         ptr = "%l0";
  170.         break;
  171.     case 17:
  172.         ptr = "%l1";
  173.         break;
  174.     case 18:
  175.         ptr = "%l2";
  176.         break;
  177.     case 19:
  178.         ptr = "%l3";
  179.         break;
  180.     case 20:
  181.         ptr = "%l4";
  182.         break;
  183.     case 21:
  184.         ptr = "%l5";
  185.         break;
  186.     case 22:
  187.         ptr = "%l6";
  188.         break;
  189.     case 23:
  190.         ptr = "%l7";
  191.         break;
  192.     case 24:
  193.         ptr = "%i0";
  194.         break;
  195.     case 25:
  196.         ptr = "%i1";
  197.         break;
  198.     case 26:
  199.         ptr = "%i2";
  200.         break;
  201.     case 27:
  202.         ptr = "%i3";
  203.         break;
  204.     case 28:
  205.         ptr = "%i4";
  206.         break;
  207.     case 29:
  208.         ptr = "%i5";
  209.         break;
  210.     case 30:
  211.         ptr = "%fp";
  212.         break;
  213.     case 31:
  214.         ptr = "%i7";
  215.         break;
  216.     default:
  217.         sprintf(bozo, "bozotic value: %d (0x%x)", rd, rd);
  218.         ptr = bozo;
  219.         break;
  220.     }
  221.  
  222.     return ptr;
  223. }
  224.