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

📄 dbgarmlib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
    /*     * Now examine the instruction     * First, check the current condition codes against the condition     * field of the instruction since, if this instruction is not going     * to be executed, we can return immediately     *     * The following code is a translation of the code supplied by ARM     * for instruction decoding (EAN-26). Note that this version, unlike     * the original assembly language version cannot generate unaligned     * accesses which might be faulted by some systems.     *     * Briefly, there are 16 entries in ccTable, one for each possible     * value of the condition part of an instruction. Each entry has one     * bit for each possible value of the flags in the PSR. The table     * entry is extracted using the condition part of the instruction and     * the bits are indexed using the value obtained by extracting the     * flags from the PSR. If the bit so obtained is 1, the instruction     * will be executed.     */    if (((ccTable[(instr >> 28) & 0xF] >> (pRegs->cpsr >> 28)) & 1) == 0)	return (INSTR *)nPc;	/* instruction will not be executed */    /*     * This instruction WILL be executed so look at its type     * We're looking for anything that affects the PC e.g.     *    B     *    BL     *    any data processing op where PC is the destination     *    any LDR with the PC as the destination     *	  any LDM with the PC in the list of registers to be loaded     *     * Following code is derived from the ARM symbolic debugger.     */    switch (BITS(instr, 24, 27))	{	case 1:		/* check for halfword or signed byte load to PC */	    if (BITSET(instr, 4) && BITSET(instr, 7) && BITSET(instr, 20) &&		    BITS(instr, 5, 6) != 0 && BITS(instr, 12, 15) == 15)		break;		/* bad instruction */	    /* FALL THROUGH */		case 0:	/* data processing */	case 2:	case 3:	    {	    UINT32 rn, op1, op2, cFlag;	    if (BITS(instr, 12, 15) != 15)	/* Rd */		/* operation does not affect PC */		break;	    if (BITS(instr, 22, 25) == 0 && BITS(instr, 4, 7) == 9)		/* multiply with PC as destination not allowed */		break;	    if (BITS(instr, 4, 23) == 0x2FFF1)		{		/* BX */		rn = BITS(instr, 0, 3);		nPc = (rn == 15 ? pc + 8 : pRegs->r[rn]) & ~1;		break;		}	    cFlag = BITSET(pRegs->cpsr, 29);	    rn = BITS(instr, 16, 19);	    op1 = rn == 15 ? pc + 8 : pRegs->r[rn];	    if (BITSET(instr, 25))		{		UINT32 immVal, rotate;		immVal = BITS(instr, 0, 7);		rotate = 2 * BITS(instr, 8, 11);		op2 = (immVal >> rotate) | (immVal << (32 - rotate));		}	    else		op2 = armShiftedRegVal(pRegs, instr, cFlag);	    switch (BITS(instr, 21, 24))		{		case 0x0:	/* AND */		    nPc = op1 & op2;		    break;		case 0x1:	/* EOR */		    nPc = op1 ^ op2;		    break;		case 0x2:	/* SUB */		    nPc = op1 - op2;		    break;		case 0x3:	/* RSB */		    nPc = op2 - op1;		    break;		case 0x4:	/* ADD */		    nPc = op1 + op2;		    break;		case 0x5:	/* ADC */		    nPc = op1 + op2 + cFlag;		    break;		case 0x6:	/* SBC */		    nPc = op1 - op2 + cFlag;		    break;		case 0x7:	/* RSC */		    nPc = op2 - op1 + cFlag;		    break;		case 0x8:	/* TST */		case 0x9:	/* TEQ */		case 0xa:	/* CMP */		case 0xb:	/* CMN */		    break;		case 0xc:	/* ORR */		    nPc = op1 | op2;		    break;		case 0xd:	/* MOV */		    nPc = op2;		    break;		case 0xe:	/* BIC */		    nPc = op1 & ~op2;		    break;		case 0xf:	/* MVN */		    nPc = ~op2;		    break;		}	    }	    break;	case 4:		/* data transfer */	case 5:	case 6:	case 7:	    if (BITSET(instr, 20) && BITS(instr, 12, 15) == 15 &&		!BITSET(instr, 22))		    /* load, PC and not a byte load */		{		UINT32 rn, cFlag, base;		INT32 offset;		rn = BITS(instr, 16, 19);		base = rn == 15 ? pc + 8 : pRegs->r[rn];		cFlag = BITSET(pRegs->cpsr, 29);		offset = BITSET(instr, 25)			    ? armShiftedRegVal(pRegs, instr, cFlag)			    : BITS(instr, 0, 11);		if (!BITSET(instr, 23))	/* down */		    offset = -offset;		if (BITSET(instr, 24))	/* pre-indexed */		    base += offset;		nPc = *(INSTR *)base;		/*		 * don't check for nPc == pc like the ARM debugger does but		 * let the higher level (or user) notice.		 */		}	    break;	case 8:	case 9:		/* block transfer */	    if (BITSET(instr, 20) && BITSET(instr, 15))	/* loading PC */		{		UINT32 rn;		INT32 offset = 0;		rn = BITS(instr, 16, 19);		if (BITSET(instr, 23))	/* up */		    {		    UINT32 regBit, regList;		    for (regList = BITS(instr, 0, 14); regList != 0;							regList &= ~regBit)			{			regBit = regList & (-regList);			offset += 4;			}		    if (BITSET(instr, 24))	/* preincrement */			offset += 4;		    }		else			/* down */		    if (BITSET(instr, 24))	/* predecrement */			offset = -4;		nPc = *(UINT32 *)(pRegs->r[rn] + offset);		/*		 * don't check for nPc == pc like the ARM debugger does but		 * let the higher level (or user) notice.		 */		}	    break;	case 0xA:	/* branch */	case 0xB:	/* branch & link */	    /*	     * extract offset, sign extend it and add it to current PC,	     * adjusting for the pipeline	     */	    nPc = pc + 8 + ((INT32)(instr << 8) >> 6);	    break;	case 0xC:	case 0xD:	case 0xE:           /* coproc ops */	case 0xF:           /* SWI */	    break;	}    return (INSTR *)nPc;    } /* armGetNpc() */#endif	/* (ARM_THUMB) */#if (ARM_THUMB)/********************************************************************************* thumbInstrChangesPc - determine if current instruction changes PC** RETURNS: TRUE if the current instruction changes the PC**/BOOL thumbInstrChangesPc    (    INSTR * pc			/* pointer to instruction */    )    {    INSTR instr;		/* the instruction, itself */    BOOL res;    pc = (INSTR *)((UINT32)pc & ~1);	/* align pc */    instr = *pc;		/* get instruction */    res = FALSE;		/* assume PC is not affected */    /*     * Examine the instruction to determine whether it changes the PC     * other than in the usual incremental fashion. Note that we don't have     * the CPSR value so we just assume the instruction will be executed.     *     * The following code is a cut-down version of the code used by     * thumbGetNpc (above).     */    switch (BITS(instr, 12, 15))	{	case 0x0:	case 0x1:	case 0x2:	case 0x3:	case 0x5:	case 0x6:	case 0x7:	case 0x8:	case 0x9:	case 0xA:	case 0xC:	    /* no effect on PC - next instruction executes */	    break;	case 4:	    if (BITS(instr, 7, 11) == 0x0E)		res = TRUE;	/* BX */	    else		if (BITSET(instr, 7) &&		    (BITS(instr, 0, 11) & 0xC07) == 0x407 &&		    BITS(instr, 8, 9) != 1)		    res = TRUE;	/* does something to PC and is not CMP */	    break;	case 0xB:	    if (BITS(instr, 8, 11) == 0xD)		res = TRUE;	/* POP {rlist, pc} */	    break;	case 0xD:	    if (((instr >> 8) & 0xF) != 0xF)		res = TRUE;	/* conditional branch, not SWI */	    break;	case 0xE:	    if (BITSET(instr, 11) == 0)		res = TRUE;	/* unconditional branch */	    break;	case 0xF:	    if (BITSET(instr, 11) == 0)		res = TRUE;	/* first half of BL */	    break;	} /* switch */    return res;    } /* thumbInstrChangesPc() */#else	/* (ARM_THUMB) *//********************************************************************************* armInstrChangesPc - determine if current instruction changes PC** RETURNS: TRUE if the current instruction changes the PC**/BOOL armInstrChangesPc    (    INSTR * pc			/* pointer to instruction */    )    {    UINT32 instr;		/* the instruction, itself */    BOOL res;    instr = *pc;		/* get instruction */    res = FALSE;		/* assume PC is not affected */    /*     * Examine the instruction to determine whether it changes the PC     * other than in the usual incremental fashion. Note that we don't have     * the CPSR value so we just assume the instruction will be executed.     *     * The following code is a cut-down version of the code used by     * armGetNpc (above).     */    switch (BITS(instr, 24, 27))	{	case 0:	/* data processing */	case 1:	/* includes signed byte/halfword loads */	case 2:	case 3:	/* includes MUL, BX */	    if (BITS(instr, 12, 15) == 15)	/* Rd */		res = TRUE;	    break;	case 4:		/* data transfer */	case 5:	case 6:	case 7:	    if (BITSET(instr, 20) && BITS(instr, 12, 15) == 15 &&		!BITSET(instr, 22))		    /* load, PC and not a byte load */		res = TRUE;	    break;	case 8:	case 9:		/* block transfer */	    if (BITSET(instr, 20) && BITSET(instr, 15))	/* loading PC */		res = TRUE;	    break;	case 0xA:	/* branch */	case 0xB:	/* branch & link */	    res = TRUE;	    break;	case 0xC:	case 0xD:	case 0xE:           /* coproc ops */	case 0xF:           /* SWI */	    break;	}    return res;    } /* armInstrChangesPc() */#endif	/* (ARM_THUMB) */

⌨️ 快捷键说明

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