📄 dsmlib.c
字号:
break; case D_DZ: printf ("%s", dz [(insn & ZZ_F) >> ZZ_SHIFT]); break; case D_IMM: imm = (insn >> 4) & 0x7f; if (imm & 0x40) printf ("#%ld", ((imm << 25) >> 25)); else printf ("#%ld", imm); break; case D_MACH: printf ("mach"); break; case D_MACL: printf ("macl"); break; case D_SE: printf ("%s", se [(insn & EE_3) >> EE_SHIFT]); break; case D_SF: printf ("%s", sf [(insn & FF_3) >> FF_SHIFT]); break; case D_SX: printf ("%s", sx [(insn & XX_3) >> XX_SHIFT]); break; case D_SY: printf ("%s", sy [(insn & YY_3) >> YY_SHIFT]); break; default: printf ("<illegal>"); break; } } }/********************************************************************************* dsmPrintDsp - print a disassembled SH3 DSP instruction** This routine prints an instruction in disassembled form. It takes* as input a pointer to the instruction, an address with which to* prepend the instruction, a pointer to a function for printing the* address.** INTERNAL* The format of the disassembled output starts with the address and hexadecimal* representation of the instruction. The mnemonic and any instruction modifiers* typically follow, then the operands. The output should reflect the syntax of* the assembler input. Use spacing to align and enhance the readability of the* disassembly. [Arch Port Kit]**/LOCAL int dsmPrintDsp ( USHORT *memaddr, /* pointer to instruction */ int address, /* Address prepended to instruction */ VOIDFUNCPTR prtAddress /* Address printing function */ ) { ULONG insn; int size = 2; SH_DSP_OPCODE_INFO *op; BOOL slotInst; /* TRUE if instruction is in delayed slot */ slotInst = (delaySlot == TRUE) && ((address - lastAddress) == 2); delaySlot = FALSE; /* No branches in DSP insn's */ lastAddress = address; /* Print the address, in hex */ printf ("%06x ", address); insn = *memaddr & 0xfc00; if (insn == 0xf800) { size = 2; insn = (*memaddr << 16) | (*(memaddr + 1)); printf ("%04x %04x ", *memaddr, *(memaddr + 1)); } else { size = 1; insn = *memaddr; printf ("%04x ", *memaddr); } if (slotInst) printf (" ("); else printf (" "); op = dsmFindDsp (insn, 0); if (!op) /* if not found, then print 16 bit word and advance by 2 bytes */ { printf (" .short 0x%04x", *memaddr); if (slotInst) printf (")\n"); else printf ("\n"); return 2; } /* found match */ if (op->flags & SH_DCT) printf ("dct "); else if (op->flags & SH_DCF) printf ("dcf "); if (op->flags & (SH_MOVX | SH_MOVY)) insn &= 0x03ff; else { if (op->flags & (SH_DCF | SH_DCT)) printf ("%-6s ", op->name); else printf ("%-10s ", op->name); printDspArgs (insn, op, prtAddress); if (!(op->flags & SH_MOVS)) insn = (insn >> 16) & 0x03ff; } /* extract and print parallel moves if needed */ if (!(op->flags & SH_MOVS)) { int nopy; int nopx; int first; SH_DSP_OPCODE_INFO *mov_op; nopx = !(insn & MOVX_MASK); nopy = !(insn & MOVY_MASK); first = (op->flags & (SH_MOVX | SH_MOVY)); /* MOVX */ if (!nopx) { mov_op = dsmFindDsp ((insn & MOVX_MASK) | 0xf000, SH_MOVX); if (!first) printf (" %s ", mov_op->name); else printf ("%-10s ", mov_op->name); printDspArgs (insn, mov_op, prtAddress); first = 0; } if (!nopy) { mov_op = dsmFindDsp ((insn & MOVY_MASK) | 0xf000, SH_MOVY); if (!first) printf (" %s ", mov_op->name); else printf ("%-10s ", mov_op->name); printDspArgs (insn, mov_op, prtAddress); first = 0; } if (nopx && nopy && (op->flags & (SH_MOVX | SH_MOVY))) { if (!first) printf (" "); printf ("nopx"); } } if (slotInst) printf (")\n"); else printf ("\n"); return size; } #endif /* CPU==SH7700 || CPU==SH7600 *//********************************************************************************* nPrtAddress - print addresses as numbers*/LOCAL void nPrtAddress ( int address ) { printf ("%#x", address); }/********************************************************************************* dsmNwords - return the length (in words) of an instruction*/LOCAL int dsmNwords ( USHORT binInst [], FAST INST *iPtr ) { return (1); }#if (CPU==SH7700 || CPU==SH7750)/********************************************************************************* dsmFppNwords - return the length (in words) of an instruction*/LOCAL int dsmFppNwords ( USHORT binInst [], FAST INST *fppPtr ) { return (1); }#endif /* (CPU==SH7700 || CPU==SH7750) *//********************************************************************************* dsmInst - disassemble and print a single instruction** This routine disassembles and prints a single instruction on standard* output. The function passed as parameter <prtAddress> is used to print any* operands that might be construed as addresses. The function could be a* subroutine that prints a number or looks up the address in a symbol table.* The disassembled instruction will be prepended with the address passed as* a parameter.** If <prtAddress> is zero, dsmInst() will use a default routine that prints* addresses as hex numbers.** ADDRESS-PRINTING ROUTINE* Many assembly language operands are addresses. In order to print these* addresses symbolically, dsmInst() calls a user-supplied routine, passed as a* parameter, to do the actual printing. The routine should be declared as:* .CS* void prtAddress (address)* int address; /@ address to print @/* .CE** When called, the routine prints the address on standard output in either* numeric or symbolic form. For example, the address-printing routine used* by l() looks up the address in the system symbol table and prints the* symbol associated with it, if there is one. If not, the routine prints the* address as a hex number.** If the <prtAddress> argument to dsmInst() is NULL, a default print routine is* used, which prints the address as a hexadecimal number.** The directive .short (declare short) is printed for unrecognized instructions.** RETURNS : The number of 16-bit words occupied by the instruction.*/int dsmInst ( FAST USHORT *binInst, /* Pointer to the instruction */ int address, /* Address prepended to instruction */ VOIDFUNCPTR prtAddress /* Address printing function */ ) { FAST INST *iPtr; FAST int size; if (prtAddress == NULL) prtAddress = nPrtAddress;#if (CPU==SH7700 || CPU==SH7600) if (dspProbe () == OK) { if ((*binInst & 0xf000) == 0xf000) return (dsmPrintDsp (binInst, address, prtAddress)); }#endif /* CPU==SH7700 || CPU==SH7600 */#if (CPU==SH7700 || CPU==SH7750) if (fppProbe () == OK) { if ((iPtr = dsmFindFpp (binInst)) != NULL) { size = dsmFppNwords (binInst, iPtr); dsmPrintFpp (binInst, iPtr, address, size); return (size); } }#endif /* CPU==SH7700 || CPU==SH7750 */ iPtr = dsmFind (binInst); size = dsmNwords (binInst, iPtr); dsmPrint (binInst, iPtr, address, size); return (size); }/********************************************************************************* dsmNbytes - determine the size of an instruction** This routine determines the size, in bytes, of an instruction.* It returns a constant, 4, if the instruction is found, and is preserved for* compatibility with the 680x0 version.** RETURNS:* A constant, or 0 if the instruction is unrecognized.** INTERNAL* The number os bytes in an instruction is returned by this function. For RISCs* this is often a constant. For CISCs, this function may be a simplified version* of the dsmFind() routine. The type should be a key to the number of bytes, or* an explicit entry in the INST structure may be necessary. Make a design trade-* off between complexity and the amount of space needed to use the LOCAL array* INST. [Arch Port Kit]** This function appears to be obsolete; it is no longer* used in dbgLib.c.*/int dsmNbytes ( USHORT *binInst /* pointer to the instruction */ ) { FAST INST *iPtr; if (binInst == NULL) return (0);#if (CPU==SH7700 || CPU==SH7600) if (dspProbe () == OK) { /* DSP instructions start with 0xf000 */ if ((*binInst & 0xf000) == 0xf000) { ULONG insn; if ((*binInst & 0xfc00) == 0xf800) insn = (ULONG) (*binInst << 16) | (*(binInst + 1)); else insn = (ULONG) *binInst; if (dsmFindDsp (insn, 0) != NULL) return ((*binInst & 0xfc00) ? 4 : 2); } }#endif /* CPU==SH7700 || CPU==SH7600 */#if (CPU==SH7700 || CPU==SH7750) if (fppProbe () == OK) { /* FP instructions start with 0xf000 */ if ((*binInst & 0xf000) == 0xf000) if (dsmFindFpp (binInst) != NULL) return (2); }#endif /* CPU==SH7700 || CPU==SH7750 */ /* Not DSP, nor FP */ if ((iPtr = dsmFind (binInst)) != NULL) { /* Make sure to skip delay slot instructions */ if (iPtr->type & itDelay) return (4); else return (2); } /* Nothing found */ return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -