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

📄 mpc.c

📁 motorola 针对coldfire 5275 评估板的Dbug bootloader源程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * File:        mpc.c
 * Purpose:     PowerPC assembly and disassembly.
 *
 * Notes:
 *
 */

#include "src/include/dbug.h"
#include "src/uif/cpu.h"
#include "src/uif/sym.h"

/********************************************************************/

#define SYMBOL_TABLE

#define REG_INT     (1)
#define REG_FLOAT   (2)

#define EA_OFFSET   (30)    /* offset before appending EA */
static const char
COMMA[] = ",";

typedef struct
{
    uint32  keepers;
    uint32  match;
    char    *instruction;
    void    (*dishandler)(unsigned int);
    int     (*asmhandler)(void);
} INSTRENTRY;

extern const
INSTRENTRY isa[];

/********************************************************************/

static char
dstr[80];

static ADDRESS
disasm_pc;

static int
valid_instruction;

static INSTRUCTION
asm_insn;

static ADDRESS
asm_pc;

/********************************************************************/

#define append_string(a,b)  strcat(a,b)

/********************************************************************/
static uint32
get_gpr(int gpr)
{
    extern REGISTERS context;

    switch (gpr)
    {
        case 0: return context.r0; break;
        case 1: return context.r1; break;
        case 2: return context.r2; break;
        case 3: return context.r3; break;
        case 4: return context.r4; break;
        case 5: return context.r5; break;
        case 6: return context.r6; break;
        case 7: return context.r7; break;
        case 8: return context.r8; break;
        case 9: return context.r9; break;
        case 10: return context.r10; break;
        case 11: return context.r11; break;
        case 12: return context.r12; break;
        case 13: return context.r13; break;
        case 14: return context.r14; break;
        case 15: return context.r15; break;
        case 16: return context.r16; break;
        case 17: return context.r17; break;
        case 18: return context.r18; break;
        case 19: return context.r19; break;
        case 20: return context.r20; break;
        case 21: return context.r21; break;
        case 22: return context.r22; break;
        case 23: return context.r23; break;
        case 24: return context.r24; break;
        case 25: return context.r25; break;
        case 26: return context.r26; break;
        case 27: return context.r27; break;
        case 28: return context.r28; break;
        case 29: return context.r29; break;
        case 30: return context.r30; break;
        case 31: return context.r31; break;
        default:
            return 0; break;
    }
}

/********************************************************************/
static void
append_eastr (char *buf, uint32 ea)
{
    char eastr[20];
    int index;

    /* Pad out to EA_OFFSET */
    for (index = strlen(buf); index < EA_OFFSET; ++index)
        append_string(buf," ");

    sprintf(eastr,"(EA: %08X)", ea);
    append_string(buf,eastr);
}

/********************************************************************/
static void
append_ea_rA_0_d (char *buf, int d, int rA)
{
    /*
     * EA = (rA|0) + d
     */
    uint32 ea;

    if (rA == 0)
        ea = 0;
    else
        ea = get_gpr(rA);

    if (d < 0)
        ea -= (~d+1);
    else
        ea += d;

    append_eastr(buf,ea);
}

/********************************************************************/
static void
append_ea_rA_d (char *buf, int d, int rA)
{
    /*
     * EA = (rA) + d
     */
    uint32 ea;

    ea = get_gpr(rA);

    if (d < 0)
        ea -= (~d+1);
    else
        ea += d;

    append_eastr(buf,ea);
}

/********************************************************************/
static void
append_ea_rA_0_rB (char *buf, int rA, int rB)
{
    /*
     * EA = (rA|0) + (rB)
     */
    uint32 ea;

    if (rA == 0)
        ea = 0;
    else
        ea = get_gpr(rA);

    ea += get_gpr(rB);

    append_eastr(buf,ea);
}

/********************************************************************/
static void
append_ea_rA_rB (char *buf, int rA, int rB)
{
    /*
     * EA = (rA) + (rB)
     */
    uint32 ea;
    
    ea = get_gpr(rA) + get_gpr(rB);

    append_eastr(buf,ea);
}

/********************************************************************/
static void
append_instruction (char *buf, char *instruction)
{
    sprintf(buf,"%-10s",instruction);
}

/********************************************************************/
static void
append_Xbit_number (char *buf, int opword, int bits, int offset)
{
    /*
     * This field accepts `opword' and then determines according
     * to the offsets what size 'bit' number is.
     * The number is then concatenated to the end of the
     * disasm_stmt.
     *
     * The `offset' is given by the bit number as listed in the
     * PowerPC Microprocessor Family: Programming Environments, Ch. 8
     * (Bit 0 is on the left, bit 31/63 is on the right)
     */
    unsigned int i, mask;
    char regnum[15];

    /*
     * Determine register number.  The offset is the bit number of the
     * left-most bit of the X-bit register field.
     */
    mask = 0x80000000;
    for (i = 0; i < bits; i++)
    {
        mask = (mask >> 1) | 0x80000000;
    }
    for (i = 0; i < offset; i++)
    {
        mask = mask >> 1;
    }
    i = (opword & mask) >> (31-(offset+bits-1));
    sprintf(regnum,"%d",i);
    strcat(buf,regnum);
}

/********************************************************************/
static int
append_register (char *buf, int opword, int reg, int offset)
{
    /*
     * This field accepts `opword' and then determines according
     * to the offsets which register (r0 .. r31) is specified.
     * The register name is then concatenated to the end of the
     * disasm_stmt.
     *
     * The `offset' is given by the bit number as listed in the
     * PowerPC Microprocessor Family: Programming Environments, Ch. 8
     * (Bit 0 is on the left, bit 31/63 is on the right)
     *
     * This routine also returns the register number.
     */
    unsigned int i, mask;
    char regnum[5];

    /*
     * Determine register number.  The offset is the bit number of the
     * left-most bit of the 5-bit register field.
     */
#if 0
    mask = 0xF8000000;  /* 5 bits */
    for (i = 0; i < offset; i++)
    {
        mask = mask >> 1;
    }
#else
    mask = (0xF8000000 >> offset);
#endif
    i = (opword & mask) >> (31-(offset+5-1));

    if (buf != NULL)
    {
        switch (reg)
        {
            case REG_FLOAT:
                sprintf(regnum,"f%d",i);
                break;
            case REG_INT:
            default:
                sprintf(regnum,"r%d",i);
                break;
        }
        strcat(buf,regnum);
    }

    return i;
}

/********************************************************************/
static void
append_value (char *buf, unsigned int value, int size)
{
    char vbuf[10];
    switch (size)
    {
        case 16:
            sprintf(vbuf,"0x%04X",value & 0x0000FFFF);
            break;
        case 32:
        default:
            sprintf(vbuf,"0x%08X",value);
            break;
    }
    append_string(buf,vbuf);
}

/********************************************************************/
static void
func (unsigned int opword)
{
    /* The instruction name has already been printed. */

    (void)opword;
}

/********************************************************************/
static void
func1 (unsigned int opword)
{
    append_register(dstr,opword,REG_INT,6);
    append_string(dstr,COMMA);
    append_register(dstr,opword,REG_INT,11);
    append_string(dstr,COMMA);
    append_register(dstr,opword,REG_INT,16);
}

/********************************************************************/
static void
func2 (unsigned int opword)
{
    append_register(dstr,opword,REG_INT,6);
    append_string(dstr,COMMA);
    append_register(dstr,opword,REG_INT,11);
    append_string(dstr,COMMA);
    append_value(dstr,opword & 0x0000FFFF,16);
}

/********************************************************************/
static void
func3 (unsigned int opword)
{
    append_register(dstr,opword,REG_INT,6);
    append_string(dstr,COMMA);
    append_register(dstr,opword,REG_INT,11);
}

/********************************************************************/
static void
func4 (unsigned int opword)
{
    append_register(dstr,opword,REG_INT,11);
    append_string(dstr,COMMA);
    append_register(dstr,opword,REG_INT,6);
    append_string(dstr,COMMA);
    append_register(dstr,opword,REG_INT,16);
}

/********************************************************************/
static void
func5 (unsigned int opword)
{
    append_register(dstr,opword,REG_INT,11);
    append_string(dstr,COMMA);
    append_register(dstr,opword,REG_INT,6);
    append_string(dstr,COMMA);
    append_value(dstr,opword & 0x0000FFFF,16);
}

/********************************************************************/
static void
func6 (unsigned int opword)
{
    uint32 li;
    uint32 target;
    char sstr[40];

    li = opword & 0x03FFFFFC;
    if (li & 0x02000000)
    {
        /* sign extend */
        li = li | 0xFC000000;
    }

    if (0x00000002 & opword)
    {
        /* AA = 1 */
        target = li;
    }
    else
    {
        /* AA = 0 */
        target = (uint32)disasm_pc + li;
    }

#ifdef SYMBOL_TABLE
    if (symtab_convert_address(target,sstr))
    {
        append_string(dstr,sstr);
    }
    else
    {
        append_value(dstr,target,32);
    }
#else
    append_value(dstr,target,32);
#endif
}

/********************************************************************/
static void
func7 (unsigned int opword)
{
    int bd;
    unsigned int target;

    append_Xbit_number(dstr,opword,5,6);
    append_string(dstr,COMMA);
    append_Xbit_number(dstr,opword,5,11);
    append_string(dstr,COMMA);

    bd = opword & 0x0000FFFC;
    if (bd & 0x00008000)
    {
        /* sign extend */
        bd = bd | 0xFFFF0000;
    }

    if (0x00000002 & opword)
    {
        /* AA = 1 */
        target = (unsigned int)bd;
    }
    else
    {
        /* AA = 0 */
        target = (unsigned int)((int)disasm_pc + (int)bd);
    }
    append_value(dstr,target,32);
}

/********************************************************************/
static void
func8 (unsigned int opword)
{
    append_Xbit_number(dstr,opword,5,6);
    append_string(dstr,COMMA);
    append_Xbit_number(dstr,opword,5,11);
}

/********************************************************************/
static void
func9 (unsigned int opword)
{
    append_Xbit_number(dstr,opword,3,6);
    append_string(dstr,COMMA);
    if (opword & 0x00200000)
    {
        append_string(dstr,"1");
    }
    else
    {
        append_string(dstr,"0");
    }
    append_string(dstr,COMMA);
    append_register(dstr,opword,REG_INT,11);
    append_string(dstr,COMMA);
    append_register(dstr,opword,REG_INT,16);
}

/********************************************************************/
static void
func10 (unsigned int opword)
{
    append_Xbit_number(dstr,opword,3,6);
    append_string(dstr,COMMA);
    if (opword & 0x00200000)
    {
        append_string(dstr,"1");
    }
    else
    {
        append_string(dstr,"0");
    }
    append_string(dstr,COMMA);
    append_register(dstr,opword,REG_INT,11);
    append_string(dstr,COMMA);
    append_value(dstr,opword & 0x0000FFFF,16);
}

/********************************************************************/
static void
func11 (unsigned int opword)
{
    append_register(dstr,opword,REG_INT,11);
    append_string(dstr,COMMA);
    append_register(dstr,opword,REG_INT,6);
}

/********************************************************************/
static void
func12 (unsigned int opword)
{
    append_Xbit_number(dstr,opword,5,6);
    append_string(dstr,COMMA);
    append_Xbit_number(dstr,opword,5,11);
    append_string(dstr,COMMA);
    append_Xbit_number(dstr,opword,5,16);
}

/********************************************************************/
static void
func13 (unsigned int opword)
{
    int rA, rB;
    rA = append_register(dstr,opword,REG_INT,11);
    append_string(dstr,COMMA);
    rB = append_register(dstr,opword,REG_INT,16);
    append_ea_rA_rB(dstr, rA, rB);
}

/********************************************************************/
static void
func14 (unsigned int opword)
{
    append_register(dstr,opword,REG_FLOAT,6);
    append_string(dstr,COMMA);
    append_register(dstr,opword,REG_FLOAT,16);
}

/********************************************************************/
static void
func15 (unsigned int opword)
{
    append_register(dstr,opword,REG_FLOAT,6);
    append_string(dstr,COMMA);
    append_register(dstr,opword,REG_FLOAT,11);
    append_string(dstr,COMMA);

⌨️ 快捷键说明

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