⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dis_ppc.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Power PC (403-GA) disassembler. * *  General notice: *  This code is part of a boot-monitor package developed as a generic base *  platform for embedded system designs.  As such, it is likely to be *  distributed to various projects beyond the control of the original *  author.  Please notify the author of any enhancements made or bugs found *  so that all may benefit from the changes.  In addition, notification back *  to the author will allow the new user to pick up changes that may have *  been made by other users after this version of the code was distributed. * *  Note1: the majority of this code was edited with 4-space tabs. *  Note2: as more and more contributions are accepted, the term "author" *         is becoming a mis-representation of credit. * *  Original author:    Ed Sutter *  Email:              esutter@lucent.com */#include "config.h"#include "genlib.h"#include "stddefs.h"#if INCLUDE_DISASSEMBLER#ifndef USE_SPRDCR_NAMES#define USE_SPRDCR_NAMES 0#endifvoid prdata();/* Instruction fields taken from  chapter 10: */#define AA              0x00000002#define BA              0x001F0000#define BB              0x0000F800#define BD              0x0000FFFC#define BD_NEGATIVE     0x00008000#define BF              0x03800000#define BFA             0x001C0000#define BI              0x001F0000#define BO              0x03E00000#define BO_0            0x02000000#define BO_1            0x01000000#define BO_2            0x00800000#define BO_3            0x00400000#define BO_4            0x00200000#define BT              0x03E00000#define D               0x0000FFFF#define DCRN            0x001FF800#define FXM             0x000FF000#define IM              0x0000FFFF#define LI              0x03FFFFFC#define LI_NEGATIVE     0x02000000#define LK              0x00000001#define MB              0x000007C0#define ME              0x0000003E#define NB              0x0000F800#define OPCD            0xFC000000#define OE              0x00000400#define RA              0x001F0000#define RB              0x0000F800#define RC              0x00000001#define RSRT            0x03E00000#define SH              0x0000F800#define SPRF            0x001FF800#define TO              0x03E00000#define XO_OE           0x000007FE#define XO_NOOE         0x000003FE#define XO_SC           0x00000002#define XO_STWCX        0x00000001#define SYNC            0x7c0004ac#define ISYNC           0x4c00012c#define rs  rsrt#define rt  rsrtint opcodeXX(), opcode03(), opcode07();int opcode08(), opcode10(), opcode11();int opcode12(), opcode13(), opcode14(), opcode15();int opcode16(), opcode17(), opcode18(), opcode19();int opcode20(), opcode21(), opcode23();int opcode24(), opcode25(), opcode26(), opcode27();int opcode28(), opcode29(), opcode31();int opcode32(), opcode33(), opcode34(), opcode35();int opcode36(), opcode37(), opcode38(), opcode39();int opcode40(), opcode41(), opcode42(), opcode43();int opcode44(), opcode45(), opcode46(), opcode47();int (*opfuncs[])() = {    opcodeXX, opcodeXX, opcodeXX, opcode03,    opcodeXX, opcodeXX, opcodeXX, opcode07,    opcode08, opcodeXX, opcode10, opcode11,    opcode12, opcode13, opcode14, opcode15,    opcode16, opcode17, opcode18, opcode19,    opcode20, opcode21, opcodeXX, opcode23,    opcode24, opcode25, opcode26, opcode27,    opcode28, opcode29, opcodeXX, opcode31,    opcode32, opcode33, opcode34, opcode35,    opcode36, opcode37, opcode38, opcode39,    opcode40, opcode41, opcode42, opcode43,    opcode44, opcode45, opcode46, opcode47,    opcodeXX, opcodeXX, opcodeXX, opcodeXX,    opcodeXX, opcodeXX, opcodeXX, opcodeXX,    opcodeXX, opcodeXX, opcodeXX, opcodeXX,    opcodeXX, opcodeXX, opcodeXX, opcodeXX,};#if USE_SPRDCR_NAMESstruct sprdat {    ushort  val;    char    *name;} sprtbl[] = {    { 0x03d7,       "cdbcr" },    { 0x0009,       "ctr" },    { 0x03f6,       "dac1" },    { 0x03f7,       "dac2" },    { 0x03f2,       "dbcr" },    { 0x03f0,       "dbsr" },    { 0x03fa,       "dccr" },    { 0x03d5,       "dear" },    { 0x03d4,       "esr" },    { 0x03d6,       "evpr" },    { 0x03f4,       "iac1" },    { 0x03f5,       "iac2" },    { 0x03fb,       "iccr" },    { 0x03d3,       "icdbdr" },    { 0x0008,       "lr" },    { 0x03fc,       "pbl1" },    { 0x03fe,       "pbl2" },    { 0x03fd,       "pbu1" },    { 0x03ff,       "pbu2" },    { 0x03db,       "pit" },    { 0x011f,       "pvr" },    { 0x0110,       "sprg0" },    { 0x0111,       "sprg1" },    { 0x0112,       "sprg2" },    { 0x0113,       "sprg3" },    { 0x001a,       "srr0" },    { 0x001b,       "srr1" },    { 0x03de,       "srr2" },    { 0x03df,       "srr3" },    { 0x03dc,       "tbhi" },    { 0x03dd,       "tblo" },    { 0x03da,       "tcr" },    { 0x03d8,       "tsr" },    { 0x0001,       "xer" },    { 0x03b9,       "sgr" },        /* 403-GC only */    { 0x03ba,       "dcwr" },       /* 403-GC only */    { 0x0000,       "rsvd0" },    { 0x0010,       "rsvd1" },    { 0x03d0,       "rsvd2" },    { 0x03d1,       "rsvd3" },    { 0x03d2,       "rsvd4" },    { 0x03d9,       "rsvd5" },    { 0x03f1,       "rsvd6" },    { 0x03f3,       "rsvd7" },    { 0x03f8,       "rsvd8" },    { 0x03f9,       "rsvd9" },};struct dcrdat {    ushort  val;    char    *name;} dcrtbl[] = {    { 0x0090,       "bear" },    { 0x0091,       "besr" },    { 0x0080,       "br0" },    { 0x0081,       "br1" },    { 0x0082,       "br2" },    { 0x0083,       "br3" },    { 0x0084,       "br4" },    { 0x0085,       "br5" },    { 0x0086,       "br6" },    { 0x0087,       "br7" },    { 0x00c4,       "dmacc0" },    { 0x00cc,       "dmacc1" },    { 0x00d4,       "dmacc2" },    { 0x00dc,       "dmacc3" },    { 0x00c0,       "dmacr0" },    { 0x00c8,       "dmacr1" },    { 0x00d0,       "dmacr2" },    { 0x00d8,       "dmacr3" },    { 0x00c1,       "dmact0" },    { 0x00c9,       "dmact1" },    { 0x00d1,       "dmact2" },    { 0x00d9,       "dmact3" },    { 0x00c2,       "dmada0" },    { 0x00ca,       "dmada1" },    { 0x00d2,       "dmada2" },    { 0x00da,       "dmada3" },    { 0x00c3,       "dmasa0" },    { 0x00cb,       "dmasa1" },    { 0x00d3,       "dmasa2" },    { 0x00db,       "dmasa3" },    { 0x00e0,       "dmasr" },    { 0x0042,       "exier" },    { 0x0040,       "exisr" },    { 0x00a0,       "iocr" },    { 0x0041,       "rsvd" },    { 0x00e1,       "rsvd" },};#endifchar *crfld[] = {    "CRf00", "CRf01", "CRf02", "CRf03",    "CRf04", "CRf05", "CRf06", "CRf07",};char *crbit[] = {    "CRb00", "CRb01", "CRb02", "CRb03",    "CRb04", "CRb05", "CRb06", "CRb07",    "CRb08", "CRb09", "CRb10", "CRb11",    "CRb12", "CRb13", "CRb14", "CRb15",    "CRb16", "CRb17", "CRb18", "CRb19",    "CRb20", "CRb21", "CRb22", "CRb23",    "CRb24", "CRb25", "CRb26", "CRb27",    "CRb28", "CRb29", "CRb30", "CRb31",};char *Regs[] = {    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",    "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",    "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",};char    *tbl1[] = { "add", "add.", "addo", "addo." };char    *tbl2[] = { "addc", "addc.", "addco", "addco." };char    *tbl3[] = { "adde", "adde.", "addeo", "addeo." };char    *tbl4[] = { "addme", "addme.", "addmeo", "addmeo." };char    *tbl5[] = { "addze", "addze.", "addzeo", "addzeo." };char    *tbl6[] = { "b", "bl", "ba", "bla" };char    *tbl7[] = { "bc", "bca", "bcl", "bcla" };char    *tbl8[] = { "divw", "divw.", "divwo", "divwo." };char    *tbl9[] = { "divwu", "divwu.", "divwuo", "divwuo." };char    *tbl10[] = { "mullw", "mullw.", "mullwo", "mullwo." };char    *tbl11[] = { "neg", "neg.", "nego", "nego." };char    *tbl12[] = { "subf", "subf.", "subfo", "subfo." };char    *tbl13[] = { "subfc", "subfc.", "subfco", "subfco." };char    *tbl14[] = { "subfe", "subfe.", "subfeo", "subfeo." };char    *tbl15[] = { "subfme", "subfme.", "subfmeo", "subfmeo." };char    *tbl16[] = { "subfze", "subfze.", "subfzeo", "subfzeo." };char    *tbl17[] = { "bdnz", "bdnza", "bdnzl", "bdnzla" };char    *tbl18[] = { "bdnzf", "bdnzfa", "bdnzfl", "bdnzfla" };char    *tbl19[] = { "bdnzt", "bdnzta", "bdnztl", "bdnztla" };char    *tbl20[] = { "bdz", "bdza", "bdzl", "bdzla" };char    *tbl21[] = { "bdzf", "bdzfa", "bdzfl", "bdzfla" };char    *tbl22[] = { "bdzt", "bdzta", "bdztl", "bdztla" };char *DisHelp[] = {    "Disassemble memory",    "-[m] {address} [linecount]",    0,};/* DisAddr: * This variable can be used by the opcodeXX() functions if there is * good reason to know the address of the disassembly. */static ulong    *DisAddr;/* disppc.c: * Disassembler for POWER-PC * * Dis(): * Use the upper 6 bits of the opcode as an offset into a table of  * function pointers.  Opon entry into the function, break down the * remaining fields and print the mnemonic.  Note that the program is * intentionally left un-optimized.  There's absolutely nothing tricky * about it so it should be trivial to add other POWER-PC instructions * to this disassembler.   * NOTE: The branch instructions need work. */intDis(argc,argv)int argc;char    *argv[];{    extern  int optind;    int     opt, i, count, more;    uchar   *cp;    more = 0;    while ((opt = getopt(argc,argv,"m")) != -1) {        switch(opt) {        case 'm':            more = 1;            break;        default:            return(0);        }    }    if (argc == optind+1)        count = 1;    else if (argc == optind+2)        count = strtol(argv[optind+1],0,0);    else        return(-1);    DisAddr = (ulong *)strtoul(argv[optind],0,0);again:    for(i=0;i<count;i++) {        cp = (uchar *)DisAddr;        printf("%08lx: %02x%02x%02x%02x ",            (ulong)DisAddr,cp[0],cp[1],cp[2],cp[3]);        opfuncs[((cp[0] & 0xfc) >> 2)](*DisAddr);        DisAddr++;    }    if (more) {        if (More())            goto again;    }        return(0);}intaalk(ulong instr){    switch (instr & (AA | LK)) {    case (AA | LK):        return(3);    case (AA):        return(2);    case (LK):        return(1);    default:        return(0);    }}shortd(ulong instr)  /* 16 bit 2's compliment */{    return(instr & D);}/* sprf(): * This function attempts to replace the SPR number with some * name.  Since this is somewhat CPU dependent, I have turned * this off for now.. */char *sprf(ulong instr){    static uchar    buf[16];    ushort  hi, lo, sprval;    hi = lo = (ushort)((instr & DCRN) >> 11);    hi &= 0x03e0;    lo &= 0x001f;    hi >>= 5;    lo <<= 5;    sprval = hi | lo;#if USE_SPRDCR_NAMES    /* see above note */    for(int i=0;i<sizeof sprtbl/sizeof(struct sprdat);i++) {        if (sprval == sprtbl[i].val)             return(sprtbl[i].name);    }    sprintf(buf,"spr    %d",sprval);#else    sprintf(buf,"%d",sprval);#endif    return(buf);}char *dcrn(ulong instr){    static uchar    buf[16];    ushort  hi, lo, dcrnval;    hi = lo = (ushort)((instr & DCRN) >> 11);    hi &= 0x03e0;    lo &= 0x001f;    hi >>= 5;    lo <<= 5;    dcrnval = hi | lo;#if USE_SPRDCR_NAMES    for(int i=0;i<sizeof dcrtbl/sizeof(struct dcrdat);i++) {        if (dcrnval == dcrtbl[i].val)             return(dcrtbl[i].name);    }    sprintf(buf,"dcrn=0x%x",dcrnval);#else    sprintf(buf,"%d",dcrnval);#endif    return(buf);}ushortnb(ulong instr){    return((instr & NB) >> 11);}intoerc(ulong instr){    switch (instr & (OE | RC)) {    case (OE | RC):        return(3);    case (OE):        return(2);    case (RC):        return(1);    default:        return(0);    }}ushortxo_nooe(ulong instr){    return((ushort)((instr & XO_NOOE) >> 1));}ushortxo_oe(ulong instr){    return((ushort)((instr & XO_OE) >> 1));}shortmb(ulong instr){    return((instr & MB) >> 6);}shortme(ulong instr){    return((instr & ME) >> 1);}shortto(ulong instr){    return((instr & TO) >> 21);}shortsh(ulong instr){    return((instr & SH) >> 11);}ushortfxm(ulong instr){    return((instr & FXM) >> 12);}char *ra(ulong instr)     /* GPR used as source or target */{    return(Regs[(uchar)((instr & RA) >> 16)]);}char *rb(ulong instr)     /* GPR used as source */{    return(Regs[(uchar)((instr & RB) >> 11)]);}char *ba(ulong instr){    return(crbit[(uchar)(((instr & BA) >> 16) & 0x1f)]);}char *bb(ulong instr){    return(crbit[(uchar)(((instr & BB) >> 11) & 0x1f)]);}char *bt(ulong instr){    return(crbit[(uchar)(((instr & BT) >> 21) & 0x1f)]);}char *bo(ulong instr){    static char bostr[32];    bostr[0] = 0;    if ((instr & BO_0) == 0) {        if (instr & BO_1)            strcat(bostr,"if crbit=1 ");        else            strcat(bostr,"if crbit!=1 ");    }    if ((instr & BO_2) == 0) {        if (instr & BO_3)            strcat(bostr,"if --ctr=0 ");        else            strcat(bostr,"if --ctr!=0 ");    }    if (instr & BO_4)        strcat(bostr,"bpr");    return(bostr);}char *bfa(ulong instr){    return(crfld[(uchar)(((instr & BFA) >> 18) & 0x3)]);}char *bf(ulong instr){    return(crfld[(uchar)(((instr & BF) >> 23) & 0x3)]);}char *bi(ulong instr){    return(crbit[(uchar)(((instr & BI) >> 16) & 0x1f)]);}char *rsrt(ulong instr)   /* GPR used as source (rs) or destination (rt) */{    return(Regs[(uchar)(((instr & RSRT) >> 21) & 0x1f)]);}/* prnem(): * Print the mnemonic and append the number of spaces needed * so that the total length is 8 characters. */voidprnem(char *mnem){    int spacecount;    spacecount = 8 - strlen(mnem);    puts(mnem);    while(spacecount > 0) {        putchar(' ');        spacecount--;    }}voidprnemdot(char *mnem, int dot){    int spacecount;    spacecount = 8 - strlen(mnem);    puts(mnem);    if (dot) {        putchar('.');        spacecount--;    }    while(spacecount > 0) {        putchar(' ');        spacecount--;    }}intbf_ra(char *mnemonic, ulong instr){    prnem(mnemonic);    printf("%s,0,%s,0x%04X\n",bf(instr),ra(instr),(ushort)(instr&IM));    return(0);}intrt_ra_x(char *mnemonic, ulong instr){    prnem(mnemonic);    printf("%s,%s,0x%04X\n",rt(instr),ra(instr),(ushort)(instr&IM));    return(0);}intrt_d_ra(char *mnemonic, ulong instr){    prnem(mnemonic);    printf("%s,%d(%s)\n",rt(instr),d(instr),ra(instr));    return(0);}intrs_d_ra(char *mnemonic, ulong instr){    prnem(mnemonic);    printf("%s,%d(%s)\n",rs(instr),d(instr),ra(instr));    return(0);}intbt_ba_bb(char *mnemonic, ulong instr){    prnem(mnemonic);    printf("%s,%s,%s\n",bt(instr),ba(instr),bb(instr));    return(0);}intra_rs_sh_mb_me(char *mnemonic, ulong instr){    prnemdot(mnemonic,instr & RC);    printf("%s,%s,0x%04X,0x%04X,0x%04X\n",        ra(instr),rs(instr),sh(instr),mb(instr),me(instr));    return(0);}intra_rs(char *mnemonic, ulong instr){    prnem(mnemonic);    printf("%s,%s,0x%04X\n",ra(instr),rs(instr),(ushort)(instr&IM));    return(0);}intrt_ra_rb(char *mnemonic, ulong instr){    prnem(mnemonic);    printf("%s,%s,%s\n", rt(instr),ra(instr),rb(instr));    return(0);}intrs_ra_rb(char *mnemonic,ulong instr){    prnem(mnemonic);    printf("%s,%s,%s\n",rs(instr),ra(instr),rb(instr));    return(0);}intra_rb(char *mnemonic,ulong instr){    prnem(mnemonic);    printf("%s,%s\n",ra(instr),rb(instr));    return(0);}intrt_ra(char *mnemonic, ulong instr){    prnem(mnemonic);    printf("%s,%s\n", rt(instr),ra(instr));    return(0);}intopcodeXX(ulong instr){    uchar   *cp;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -