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

📄 mpc.c

📁 motorola 针对coldfire 5275 评估板的Dbug bootloader源程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    append_register(dstr,opword,REG_INT,11);
    append_string(dstr,COMMA);
    append_register(dstr,opword,REG_INT,6);
    append_string(dstr,COMMA);
    append_Xbit_number(dstr,opword,5,16);
}

/********************************************************************/
static void
func43 (unsigned int opword)
{
    append_Xbit_number(dstr,opword,5,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
func44 (unsigned int opword)
{
    append_Xbit_number(dstr,opword,5,6);
    append_string(dstr,COMMA);
    append_register(dstr,opword,REG_INT,11);
    append_string(dstr,COMMA);
    append_value(dstr,opword & 0x0000FFFF,16);
}

/********************************************************************/
static void
func45 (unsigned int opword)
{
    append_register(dstr,opword,REG_INT,16);
}

/********************************************************************/
static void
func46 (unsigned int opword)
{
    /*
     * This routine processes ADDIS, and also looks for
     * a following ORI in order to do symbol table lookups.
     */
    /* int reg1, reg2; */
    INSTRUCTION opword2;
    char sstr[40];

    /*reg1 =*/ append_register(dstr,opword,REG_INT,6);
    append_string(dstr,COMMA);
    /*reg2 =*/ append_register(dstr,opword,REG_INT,11);
    append_string(dstr,COMMA);

#ifdef SYMBOL_TABLE
    opword2 = *(INSTRUCTION *)(disasm_pc + 4);
    if ((opword2 & 0xFC000000) == 0x60000000)
    {
        /*
         * We have an ADDIS ORI pair, do symbol table lookup
         */
        uint32 address;

        address = (opword & 0x0000FFFF) << 16;
        address |= (opword2 & 0x0000FFFF);

        if (symtab_convert_address(address,sstr))
        {
            append_string(dstr,"(");
            append_string(dstr,sstr);
            append_string(dstr,")@h");
        }
        else
        {
            append_value(dstr,opword & 0x0000FFFF,16);
        }
    }
    else
    {
        append_value(dstr,opword & 0x0000FFFF,16);
    }
#else
    append_value(dstr,opword & 0x0000FFFF,16);
#endif
}

/********************************************************************/
static void
func47 (unsigned int opword)
{
    /*
     * This routine processes ORI, and also looks for
     * a preceding ADDIS in order to do symbol table lookups.
     */
    /*int reg1, reg2;*/
    INSTRUCTION opword2;
    char sstr[40];

    /*reg1 =*/ append_register(dstr,opword,REG_INT,11);
    append_string(dstr,COMMA);
    /*reg2 =*/ append_register(dstr,opword,REG_INT,6);
    append_string(dstr,COMMA);

#ifdef SYMBOL_TABLE
    opword2 = *(INSTRUCTION *)(disasm_pc - 4);
    if ((opword2 & 0xFC000000) == 0x3C000000)
    {
        /*
         * We have an ADDIS ORI pair, do symbol table lookup
         */
        uint32 address;

        address = (opword2 & 0x0000FFFF) << 16;
        address |= (opword & 0x0000FFFF);

        if (symtab_convert_address(address,sstr))
        {
            append_string(dstr,"(");
            append_string(dstr,sstr);
            append_string(dstr,")@l");
        }
        else
        {
            append_value(dstr,opword & 0x0000FFFF,16);
        }
    }
    else
    {
        append_value(dstr,opword & 0x0000FFFF,16);
    }
#else
    append_value(dstr,opword & 0x0000FFFF,16);
#endif
}

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

#define rDshift 21
#define rAshift 16
#define rBshift 11
#define rSshift 21
#define BOshift 21
#define BIshift 16
#define Lshift  21
#define crfDshift  23
#define crfSshift  18
#define crbDshift 21
#define crbAshift 16
#define crbBshift 11
#define frDshift 21
#define frAshift 16
#define frBshift 11
#define frCshift 6
#define SRshift 16
#define SHshift 11
#define MBshift 6
#define MEshift 1
#define TOshift 21

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

static int
parse_args (
    char **tok1, char **tok2, char **tok3, char **tok4, char **tok5)
{
    /*
     * This routine examines 'dstr' for upto 5 comma separated tokens.
     * Examples:
     *
     * arg1,arg2
     * arg1,arg2,arg3
     * arg1,arg2,arg3,arg4
     * arg1,arg2,arg3,arg4,arg5
     *
     * The number of args found is returned.
     */
    int arg = 0;
    char *p = dstr;
    char **tokens[5];

    tokens[0] = tok1;
    tokens[1] = tok2;
    tokens[2] = tok3;
    tokens[3] = tok4;
    tokens[4] = tok5;

    *tok1 = dstr;
    if (tok2 != NULL) *tok2 = NULL;
    if (tok3 != NULL) *tok3 = NULL;
    if (tok4 != NULL) *tok4 = NULL;
    if (tok5 != NULL) *tok5 = NULL;

    while (*p != '\0')
    {
        if (*p == ',')
        {
            *p = '\0';
            if (++arg < 5)
            {
                if (tokens[arg] != NULL)
                    *tokens[arg] = (p + 1);
            }
            else
                return -1;
        }
        ++p;
    }
    return arg+1;
}

/********************************************************************/
static int
parse_offset (char *drA, char **d, char **rA)
{
    /*
     * This routine breaks 'drA' into 'd' and 'rA', with 'drA'
     * expecting format d(rA).
     */
    int retval = -1;
    char *p = drA;

    *d  = drA;
    *rA = NULL;

    while (*p != '\0')
    {
        if ((*p == '(') || (*p == ')'))
        {
            if (*p == '(')
            {
                *rA = (p + 1);
            }
            else
            {
                if (*(p + 1) == '\0')   /* no trailing garbage */
                    retval = 0;
            }
            *p = '\0';
        }
        ++p;
    }
    return retval;
}

/********************************************************************/
static int
gpr_value (char *regstr)
{
    int reg;
    char *p;

    reg = strtoul(regstr, &p, 10);
    if ((reg == 0) && (p == regstr))
    {
        /* invalid numeric value, check for 'r' */
        if ((*regstr == 'r') || (*regstr == 'R'))
        {
            reg = strtoul(&regstr[1], &p, 10);
            if ((reg == 0) && (p == &regstr[1]))
                return -1;
        }
        else
            return -1;
    }
    if ((reg < 0) || (reg > 31))
        return -1;

    return reg;
}

/********************************************************************/
static int
fpr_value (char *regstr)
{
    int reg; char *p;

    reg = strtoul(regstr, &p, 10);
    if ((reg == 0) && (p == regstr))
    {
        /* invalid numeric value, check for 'f' */
        if ((*regstr == 'f') || (*regstr == 'F'))
        {
            reg = strtoul(&regstr[1], &p, 10);
            if ((reg == 0) && (p == &regstr[1]))
                return -1;
        }
        else
            return -1;
    }
    if ((reg < 0) || (reg > 31))
        return -1;

    return reg;
}

/********************************************************************/
static int
crb_value (char *crbstr)
{
    int crb;
    char *p, *p2;

    crb = strtoul(crbstr, &p, 10);
    if ((crb == 0) && (p == crbstr))
    {
        /* invalid numeric value, check for 'cr' */
        p2 = crbstr;
        if (strncasecmp(crbstr,"c",1) == 0)
            p2 = &crbstr[1];
        if (strncasecmp(crbstr,"cr",2) == 0)
            p2 = &crbstr[2];
        crb = strtoul(p2, &p, 10);
        if ((crb == 0) && (p == p2))
            return -1;
    }
    if ((crb < 0) || (crb > 31))
        return -1;
    return crb;
}

/********************************************************************/
static int
sr_value (char *srstr)
{
    int sr;
    char *p, *p2;

    sr = strtoul(srstr, &p, 10);
    if ((sr == 0) && (p == srstr))
    {
        /* invalid numeric value, check for 'cr' */
        p2 = srstr;
        if (strncasecmp(srstr,"s",1) == 0)
            p2 = &srstr[1];
        if (strncasecmp(srstr,"sr",2) == 0)
            p2 = &srstr[2];
        sr = strtoul(p2, &p, 10);
        if ((sr == 0) && (p == p2))
            return -1;
    }
    if ((sr < 0) || (sr > 15))
        return -1;
    return sr;
}

/********************************************************************/
static int
fivebit_value (char *numstr)
{
    char *p;
    int num;

    num = strtoul(numstr,&p,10);
    if ((num == 0) && (p == numstr))
        return -1;
    if ((num < 0) || (num > 31))
        return -1;

    return num;
}

/********************************************************************/
static int
eightbit_value (char *numstr)
{
    char *p;
    int num;

    num = strtoul(numstr,&p,10);
    if ((num == 0) && (p == numstr))
        return -1;
    if ((num < 0) || (num > 255))
        return -1;

    return num;
}

/********************************************************************/
static int
crf_value (char *crfstr)
{
    int crf;
    char *p, *p2;

    crf = strtoul(crfstr, &p, 10);
    if ((crf == 0) && (p == crfstr))
    {
        /* invalid numeric value, check for 'cr' */
        p2 = crfstr;
        if (strncasecmp(crfstr,"c",1) == 0)
            p2 = &crfstr[1];
        if (strncasecmp(crfstr,"cr",2) == 0)
            p2 = &crfstr[2];
        crf = strtoul(p2, &p, 10);
        if ((crf == 0) && (p == p2))
            return -1;
    }
    if ((crf < 0) || (crf > 7))
        return -1;
    return crf;
}


/********************************************************************/
static int
afunc (void)
{
    return TRUE;
}

/********************************************************************/
static int
afunc_rD_rA_rB (void)
{
    /*
     * This works for instructions with the following formats:
     *
     * insn rD,rA,rB (rD bits 6-10, rA bits 11-15, rB bits 16-20)
     * insn rS,rA,rB (rS bits 6-10, rA bits 11-15, rB bits 16-20)
     * insn rD,rA,NB
     */

    char *rDs, *rAs, *rBs;
    int rD, rA, rB;

    if (parse_args(&rDs,&rAs,&rBs,NULL,NULL) != 3)
        return FALSE;

    if ((rD = gpr_value(rDs)) < 0)
        return FALSE;

    if ((rA = gpr_value(rAs)) < 0)
        return FALSE;

    if ((rB = gpr_value(rBs)) < 0)
        return FALSE;

    asm_insn |= (rD << rDshift);
    asm_insn |= (rA << rAshift);
    asm_insn |= (rB << rBshift);

    return TRUE;
}

/********************************************************************/
static int
afunc_rD_rA_SIMM (void)
{
    /*
     * This works for instructions with the following formats:
     *
     * insn rD,rA,SIMM (rD bits 6-10, rA bits 11-15, SIMM bits 16-31)
     */

    char *rDs, *rAs, *p, *simm;
    int rD, rA;
    uint32 value;

    if (parse_args(&rDs,&rAs,&simm,NULL,NULL) != 3)
        return FALSE;

    if ((rD = gpr_value(rDs)) < 0)
        return FALSE;

    if ((rA = gpr_value(rAs)) < 0)
        return FALSE;

    value = strtoul(simm,&p,0);
    if ((value == 0) && (p == simm))
        return FALSE;

    /* FIX !!! check for SIMM out of bounds */

    asm_insn |= (rD << rDshift);
    asm_insn |= (rA << rAshift);
    asm_insn |= (value & 0x0000FFFF);

    return TRUE;
}

/********************************************************************/
static int
afunc_rA_rS_rB (void)
{
    /*
     * This works for instructions with the following formats:
     *
     * insn rA,rS,rB (rA bits 11-15, rS bits 6-10, rB bits 16-20)
     */

    char *rAs, *rSs, *rBs;
    int rA, rS, rB;

    if (parse_args(&rAs,&rSs,&rBs,NULL,NULL) != 3)
        return FALSE;

    if ((rA = gpr_value(rAs)) < 0)
        return FALSE;

    if ((rS = gpr_value(rSs)) < 0)
        return FALSE;

    if ((rB = gpr_value(rBs)) < 0)
        return FALSE;

    asm_insn |= (rA << rAshift);
    asm_insn |= (rS << rSshift);
    asm_insn |= (rB << rBshift);

    return TRUE;
}

/********************************************************************/
static int
afunc_rD_rA (void)
{
    /*
     * This works for instructions with the following formats:
     *
     * insn rD,rA (rD bits 6-10, rA bits 11-15)
     */

    char *rDs, *rAs;
    int rD, rA;

    if (parse_args(&rDs,&rAs,NULL,NULL,NULL) != 2)
        return FALSE;

    if ((rD = gpr_value(rDs)) < 0)
        return FALSE;

⌨️ 快捷键说明

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