home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume42 / elfdis / part02 / decode.c < prev    next >
C/C++ Source or Header  |  1994-05-08  |  3KB  |  137 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <assert.h>
  5. #include <dis.h>
  6. #include <formats.h>
  7.  
  8. #ifdef __STDC__
  9. static void table_f2(unsigned long instr, unsigned long pc, char *buf);
  10. #endif
  11.  
  12. /*
  13.  * Given 32 bit instruction to decode, and current program counter,
  14.  * put a string in "buf" that represents the decoded intstruction.
  15.  *
  16.  * Hopefully, this is enough separation from the executable image
  17.  * format for this to be re-usable if/when Sun switches to another
  18.  * format (ELF?).
  19.  * $Log: decode.c,v $
  20.  * Revision 1.1  1993/12/16  23:45:42  bediger
  21.  * Initial revision
  22.  *
  23.  */
  24. static char rcsident[] = "@(#)  $Id$";
  25. char *
  26. decode_instr(instr, pc, buf, nosynthetic)
  27. unsigned long   instr, pc; 
  28. char           *buf;
  29. int             nosynthetic;
  30. {
  31.     struct format1  *instr1;
  32.  
  33.     assert(NULL != buf);
  34.  
  35.     buf[0] = '\0';  /* make buffer a zero-length string */
  36.  
  37.     instr1 = (struct format1  *)&instr;
  38.  
  39.     /*
  40.      * handle simpler instructions here inside a switch, call
  41.      * a function to do lookups for memory load/stores and
  42.      * the arithmetic instructions.
  43.      * This switch() is essentially table F-1 of
  44.      * "The SPARC Architecture Manual: Version 8".
  45.      */
  46.     switch (instr1->op) {
  47.     case 0:
  48.         /* op == 0, UNIMP, Bicc, SETHI, NOP, FBfcc, CBccc: see Table F-2 */
  49.         table_f2(instr, pc, buf);
  50.         break;
  51.  
  52.     case 1:
  53.         /* op == 1, CALL AND LINK */
  54.         sprintf(buf, "call 0x%08x", 4 * instr1->disp30 + (unsigned int)pc);
  55.         break;
  56.  
  57.     case 2:
  58.         /* op == 2, Arithmetic, logical, shift, misc: see Table F-3 */
  59.         arithmetic(instr, buf, nosynthetic);
  60.         break;
  61.  
  62.     case 3:
  63.         /* op == 3, Memory Instructions: see Table F-4 */
  64.         memory(instr, buf);
  65.         break;
  66.  
  67.     default:
  68.         /* bogus */
  69.         sprintf(buf, "!bogus instruction: op = %d, bad value",
  70.             instr1->op);
  71.     }
  72.  
  73.     return buf;
  74. }
  75.  
  76. /*
  77.  *  Table F-2 of Appendix F, SPARC Architecture Manual, v8
  78.  */
  79. static void
  80. table_f2(instr, pc, buf)
  81. unsigned long instr, pc;
  82. char *buf;
  83. {
  84.     struct format2  *instr2;
  85.  
  86.     assert(NULL != buf);
  87.     assert(0 == ((struct format1 *)&instr)->op);
  88.  
  89.     instr2 = (struct format2  *)&instr;
  90.  
  91.     switch (instr2->op2) {
  92.     case 0:
  93.         strcpy(buf, "!UNIMP");
  94.         break;
  95.     case 1:
  96.         strcpy(buf, "!unimplemented, op2 = 1");
  97.         break;
  98.     case 2:
  99.         /* BRANCH On Integer Condition Codes */
  100.         sprintf(buf, "%s 0x%08x", bicc(instr2->rd),
  101.             (unsigned int)pc
  102.             + (unsigned int)(4 * (unsigned int)(SIGN_EXT22(instr2->imm22))));
  103.         break;
  104.     case 3:
  105.         strcpy(buf, "!unimplemented, op2 = 3");
  106.         break;
  107.     case 4:
  108.         /* SETHI: nop is a special case of sethi */
  109.         if (instr2->rd == 0 && instr2->imm22 == 0)
  110.             sprintf(buf, "nop");
  111.         else
  112.             sprintf(buf, "sethi %%hi(0x%x) %s",
  113.                  instr2->imm22 << 10, user_mode(instr2->rd));
  114.         break;
  115.     case 5:
  116.         strcpy(buf, "unimplemented, op2 = 5");
  117.         break;
  118.     case 6:
  119.         /* BRANCH On Floating-point Condition Codes */
  120.         sprintf(buf, "%s 0x%08x", fbfcc(instr2->rd),
  121.             (unsigned int)pc
  122.             + (unsigned int)(4 * (unsigned int)SIGN_EXT22(instr2->imm22)));
  123.         break;
  124.     case 7:
  125.         /* BRANCH On Coprocessor Condition Codes */
  126.         sprintf(buf, "%s 0x%08x", cbcc(instr2->rd),
  127.             (unsigned int)pc
  128.             + (unsigned int)(4 * (unsigned int)SIGN_EXT22(instr2->imm22)));
  129.         break;
  130.     default:
  131.         /* bogus instruction */
  132.         sprintf(buf, "!bogus instruction: op = %d, op2 = %d",
  133.             instr2->op, instr2->op2);
  134.         break;
  135.     }
  136. }
  137.