📄 dsmlib.c
字号:
{"srlv", ITYPE16_1(0x1d,0,0,0,0x6), RMASK16(0x0,0x0,0,0x1f), ry_rx}, {"srav", ITYPE16_1(0x1d,0,0,0,0x7), RMASK16(0x0,0x0,0,0x1f), ry_rx}, {"cmp", ITYPE16_1(0x1d,0,0,0,0xa), RMASK16(0x0,0x0,0,0x1f), rx_ry}, {"neg", ITYPE16_1(0x1d,0,0,0,0xb), RMASK16(0x0,0x0,0,0x1f), rx_ry}, {"and", ITYPE16_1(0x1d,0,0,0,0xc), RMASK16(0x0,0x0,0,0x1f), rx_ry}, {"or", ITYPE16_1(0x1d,0,0,0,0xd), RMASK16(0x0,0x0,0,0x1f), rx_ry}, {"xor", ITYPE16_1(0x1d,0,0,0,0xe), RMASK16(0x0,0x0,0,0x1f), rx_ry}, {"not", ITYPE16_1(0x1d,0,0,0,0xf), RMASK16(0x0,0x0,0,0x1f), rx_ry}, /* RR type for multiply and divide instructions */ {"mfhi", ITYPE16_1(0x1d,0,0,0,0x10),RMASK16(0x0,0x0,0,0x1f), rx}, {"mflo", ITYPE16_1(0x1d,0,0,0,0x12),RMASK16(0x0,0x0,0,0x1f), rx}, {"mult", ITYPE16_1(0x1d,0,0,0,0x18),RMASK16(0x0,0x0,0,0x1f), rx_ry}, {"multu",ITYPE16_1(0x1d,0,0,0,0x19),RMASK16(0x0,0x0,0,0x1f), rx_ry}, {"div", ITYPE16_1(0x1d,0,0,0,0x1a),RMASK16(0x0,0x0,0,0x1f), rx_ry}, {"divu", ITYPE16_1(0x1d,0,0,0,0x1b),RMASK16(0x0,0x0,0,0x1f), rx_ry}, /* RRR type */ {"addu", ITYPE16_1(0x1c,0,0,0,0x1), RMASK16(0x0,0x0,0,0x3), rz_rx_ry}, {"subu", ITYPE16_1(0x1c,0,0,0,0x3), RMASK16(0x0,0x0,0,0x3), rz_rx_ry}, /* RRI-A */ {"addiu",0x4000,0xf800,ry_rx_i4}, /* I8-Type instruction */ {"bteqz",I8TYPE(0xc,0,0,0), I8MASK(0x7,0,0),b}, {"btnez",I8TYPE(0xc,1,0,0), I8MASK(0x7,0,0),b}, {"swrasp",I8TYPE(0xc,2,0,0), I8MASK(0x7,0,0),f_i8}, {"adjsp",I8TYPE(0xc,3,0,0), I8MASK(0x7,0,0),f_i8}, {"move",I8TYPE(0xc,5,0,0), I8MASK(0x7,0,0),ro_rn}, {"move",I8TYPE(0xc,7,0,0), I8MASK(0x7,0,0),ry_rm}, /* jal and jalx */ {"jal", 0x1800,0xfc00,j}, {"jalx",0x1c00,0xfc00,j}, /* shift instruction */ {"sll", SFTTYPE(0x6,0,0,0,0), SFTMASK(0,0,0,0x3),rx_ry_sm}, {"srl", SFTTYPE(0x6,0,0,0,2), SFTMASK(0,0,0,0x3),rx_ry_sm}, {"sra", SFTTYPE(0x6,0,0,0,3), SFTMASK(0,0,0,0x3),rx_ry_sm}, /* must follow the 5400 insn's */ {"reserved", ITYPE(18,0,0,0), IMASK(0x10,0x0,0), null}, {"reserved", ITYPE(28,0,0,0),IMASK(0,0,0), null}, {"c2", ITYPE(18,0x10,0,0), IMASK(0x10,0,0), g}, {NULL, 0, 0, NULL} };/* forward declarations */LOCAL char *regName (int regNumber, BOOL);LOCAL char *regCP0Name (int regNumber);LOCAL char *regCP1Name (int regNumber);LOCAL char *regCP2Name (int regNumber);#ifdef HOSTLOCAL void dsmPrint ( int endian, /* endianness of data in buffer */ ULONG * binInst, /* pointer to instruction */ INST * iPtr, /* pointer to inst as returned by dsmFind() */ TGT_ADDR_T address, /* address with which to prepend instruction */ int nwords, /* length of instruction, in words */ VOIDFUNCPTR prtAddress, /* printing function address */ char * pString, /* string to write result in */ BOOL32 appendAddr, /* TRUE appends insts' addresses */ BOOL32 appendOpcodes, /* TRUE appends insts' opcodes */ int symType );LOCAL void nPrtAddress (TGT_ADDR_T address, char * pString);LOCAL int hostByteOrder (void);LOCAL ULONG getCpuMask (void);#endif/******************************************************************************** regName - Converts register number to register name (pointer to string).*/LOCAL char *regName ( int regNumber, /* numerical register representation */ BOOL mips16Mode /* mips16 instruction format, TRUE or FALSE */ ) { static char *registerName [] = { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" }; static char * mode16RegName [] = {"s0","s1","v0","v1","a0","a1","a2","a3"}; if (mips16Mode == TRUE) { if (regNumber < (int) NELEMENTS(mode16RegName)) return (mode16RegName[regNumber]); else return (""); } else { if (regNumber < (int) NELEMENTS(registerName)) return (registerName[regNumber]); else return (""); } }/******************************************************************************** regCP0Name - Converts register number to coprocessor 0 register name* (pointer to string).*/LOCAL char *regCP0Name ( int regNumber ) { static char *registerName [] = { "tlbindex", "tlbrandom", "tlblo0", "tlblo1", "tlbcontext", "tlbpagemask", "wired", "$7", "badvaddr", "count", "tlbhigh", "compare", "sr", "cause", "epc", "prid", "config", "lladdr", "watchlo", "watchhi", "$20", "$21", "$22", "$23", "$24", "$25", "ecc", "cacheerr", "taglo", "taghi", "errpc", "$31" }; if (regNumber < (int) NELEMENTS(registerName)) return (registerName[regNumber]); else return ("unknown"); }/******************************************************************************** regCP1Name - Converts register number to coprocessor 1 register name* (pointer to string).*/LOCAL char *regCP1Name ( int regNumber ) { static char *registerName [] = { "feir", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", "$24", "$25", "$26", "$27", "$28", "$29", "$30", "fsr" }; if (regNumber < (int) NELEMENTS(registerName)) return (registerName[regNumber]); else return ("unknown"); }/******************************************************************************** regCP2Name - Converts register number to coprocessor 2 register name * (pointer to string).*/LOCAL char *regCP2Name ( int regNumber ) { static char *registerName [] = { "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31" }; if (regNumber < (int)(NELEMENTS(registerName))) return (registerName[regNumber]); else return ("unknown"); }#ifdef HOST/******************************************************************************** hostByteOrder - compute host byte order** NOMANUAL*/LOCAL int hostByteOrder (void) { static int endian = -1; /* the result is cached */ if (endian == -1) /* haven't figured it out yet? */ { union { unsigned long l; char c [4]; } u; u.l = 0x12345678; endian = u.c [0] == 0x78 ? LITTLE_ENDIAN : BIG_ENDIAN; } return endian; }/********************************************************************************* dsmFind - disassemble one instruction** This routine figures out which instruction is pointed to by binInst,* and returns a pointer to the INST which describes it. If no INST is* found, returns NULL.**/LOCAL INST *dsmFind ( int endian, /* endianness of data in buffer */ ULONG *binInst, ULONG cpumask, BOOL mips16Mode /* the type of the instruction's preceding symbol */ ) { unsigned long inst; INST *iPtr; int swap; swap = (hostByteOrder () != endian); if (mips16Mode) /* mips16 */ { inst = *(unsigned short *)binInst; SWAB_16_IF (swap,inst); iPtr = itab16; } else { inst = *binInst; SWAB_32_IF (swap, inst); iPtr = itab; } /* Find out which instruction it is */ for (; iPtr->name; iPtr++) { if (((iPtr->mask & inst) == iPtr->op) && /* inst match? */ (!iPtr->cpumask || /* inst not cpu-specific? */ (iPtr->cpumask & cpumask))) /* inst is valid for this cpu? */ return (iPtr); } return (NULL);}/********************************************************************************* dsmPrint - print a disassembled instruction** This routine prints an instruction in disassembled form. It takes* as input a pointer to the instruction, a pointer to the INST* that describes it (as found by dsmFind), and an address with which to* prepend the instruction. If <appendAddr> is set to TRUE, the first member of* the returned string is the address at which code happends. If <appendOpcodes>* is set to TRUE, opcodes are also joined (after addresses) in the returned* string.** This function prints the address, raw instruction, opcode* mnemonic and operands.**/LOCAL void dsmPrint ( int endian, /* endianness of data in buffer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -