home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "formats.h"
-
- /*
- * Given 32 bit instruction to decode, and current program counter,
- * put a string in "buf" that represents the decoded intstruction.
- * Hopefully, this is enough separation from the executable image
- * format for this to be re-usable if/when Sun switches to another
- * format (ELF?).
- */
- char *
- decode_instr(instr, pc, buf)
- unsigned long instr, pc;
- char *buf;
- {
- struct format1 *instr1;
- struct format2 *instr2;
-
- char *user_mode(), *bicc(), *fbfcc(), *cbcc();
- void memory(), arithmetic();
-
- instr1 = (struct format1 *)&instr;
-
- /*
- * handle simpler instructions here inside a switch, call
- * a function to do lookups for memory load/stores and
- * the arithmetic instructions.
- * This switch() is essentially tables F-1 and F-2 of
- * "The SPARC Architecture Manual: Version 8".
- */
- switch (instr1->op) {
- case 0:
- /* op == 0, UNIMP, Bicc, SETHI, NOP, FBfcc, CBccc */
- instr2 = (struct format2 *)&instr;
- switch (instr2->op2) {
- case 0:
- strcpy(buf, "UNIMP");
- break;
- case 1:
- strcpy(buf, "unimplemented, op2 = 1");
- break;
- case 2:
- /* BRANCH On Integer Condition Codes */
- sprintf(buf, "%s 0x%08x", bicc(instr2->rd),
- (unsigned int)pc + (unsigned int)(4 * (unsigned int)(SIGN_EXT22(instr2->imm22))));
- break;
- case 3:
- strcpy(buf, "unimplemented, op2 = 3");
- break;
- case 4:
- /* SETHI */
- if (instr2->rd == 0 && instr2->imm22 == 0)
- sprintf(buf, "nop");
- else
- sprintf(buf, "sethi %%hi(0x%x) %s",
- instr2->imm22 << 10, user_mode(instr2->rd));
- break;
- case 5:
- strcpy(buf, "unimplemented, op2 = 5");
- break;
- case 6:
- /* BRANCH On Floating-point Condition Codes */
- sprintf(buf, "%s 0x%08x", fbfcc(instr2->rd),
- (unsigned int)pc + (unsigned int)(4 * (unsigned int)SIGN_EXT22(instr2->imm22)));
- break;
- case 7:
- /* BRANCH On Coprocessor Condition Codes */
- sprintf(buf, "%s 0x%08x", cbcc(instr2->rd),
- (unsigned int)pc + (unsigned int)(4 * (unsigned int)SIGN_EXT22(instr2->imm22)));
- break;
- default:
- /* bogus instruction */
- sprintf(buf, "bogus instruction: op = %d, op2 = %d",
- instr2->op, instr2->op2);
- break;
- }
-
- break;
-
- case 1:
- /* op == 1, CALL AND LINK */
- sprintf(buf, "call 0x%08x", 4 * instr1->disp30 + (unsigned int)pc);
- break;
-
- case 2:
- /* op == 2, Arithmetic, logical, shift, misc */
- arithmetic(instr, buf);
- break;
-
- case 3:
- /* op == 3, Memory Instructions */
- memory(instr, buf);
- break;
-
- default:
- /* bogus */
- sprintf(buf, "bogus instruction: op = %d, bad value",
- instr1->op);
- }
-
-
- return buf;
- }
-
- static char bozo[32];
-
- /*
- * take a register number and transliterate it into a "user-mode" type of
- * register name: the user mode is the name inside the current "window"
- */
- char *
- user_mode(rd)
- unsigned int rd;
- {
- char *ptr;
-
- switch (rd) {
- case 0:
- ptr = "%g0";
- break;
- case 1:
- ptr = "%g1";
- break;
- case 2:
- ptr = "%g2";
- break;
- case 3:
- ptr = "%g3";
- break;
- case 4:
- ptr = "%g4";
- break;
- case 5:
- ptr = "%g5";
- break;
- case 6:
- ptr = "%g6";
- break;
- case 7:
- ptr = "%g7";
- break;
- case 8:
- ptr = "%o0";
- break;
- case 9:
- ptr = "%o1";
- break;
- case 10:
- ptr = "%o2";
- break;
- case 11:
- ptr = "%o3";
- break;
- case 12:
- ptr = "%o4";
- break;
- case 13:
- ptr = "%o5";
- break;
- case 14:
- ptr = "%sp";
- break;
- case 15:
- ptr = "%o7";
- break;
- case 16:
- ptr = "%l0";
- break;
- case 17:
- ptr = "%l1";
- break;
- case 18:
- ptr = "%l2";
- break;
- case 19:
- ptr = "%l3";
- break;
- case 20:
- ptr = "%l4";
- break;
- case 21:
- ptr = "%l5";
- break;
- case 22:
- ptr = "%l6";
- break;
- case 23:
- ptr = "%l7";
- break;
- case 24:
- ptr = "%i0";
- break;
- case 25:
- ptr = "%i1";
- break;
- case 26:
- ptr = "%i2";
- break;
- case 27:
- ptr = "%i3";
- break;
- case 28:
- ptr = "%i4";
- break;
- case 29:
- ptr = "%i5";
- break;
- case 30:
- ptr = "%fp";
- break;
- case 31:
- ptr = "%i7";
- break;
- default:
- sprintf(bozo, "bozotic value: %d (0x%x)", rd, rd);
- ptr = bozo;
- break;
- }
-
- return ptr;
- }
-