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

📄 mipsuwnd.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:
            Op->Rd = NOREG;
            Op++;
        } else {
            // Look for a previous definition using SP
            if (NotFirst
             && ((Op-1)->Opcode == OP_ADD || (Op-1)->Opcode == OP_ADDI)
             && (Op-1)->Rd == Op->Rs
             && ((Op-1)->Rs == SP || (Op-1)->Rt == SP)) {
                Op->Rd = NOREG;
                Op++;
            }
        }
        break;
    case ADDIU_OP:
    case DADDIU_OP:
        Op->Rd = Op->Rt;
        if (Op->Rs == Op->Rt || Op->Rs == SP) {
            Op->Opcode = OP_ADDI;
            Op++;
        } else if (Op->Rs == ZERO) {
            Op->Opcode = OP_IMM;
            Op++;
        }
        break;
    case ORI_OP:
        Op->Opcode = OP_IMM;
        Op->Imm &= 0xffff;
        Op->Rd = Op->Rt;
        if (Op->Rs == Op->Rt) {
            // Look for matching LUI
            if (NotFirst && (Op-1)->Opcode == OP_IMM && (Op-1)->Rd == Op->Rd) {
                (Op-1)->Imm |= Op->Imm;
            } else {
                Op++;
            }
        } else if (Op->Rs == ZERO) {
            Op++;
        }
        break;
    case SPEC_OP:
        switch (I32.r_format.Function) {
        case OR_OP:
            Op->Opcode = OP_OR;
            goto spec;
        case ADDU_OP:
            Op->Opcode = OP_ADD;
        spec:
            if (Op->Rs == ZERO) {
                Op->Opcode = OP_MOVE;
                Op->Rs = Op->Rt;
                Op++;
            } else if (Op->Rt == ZERO) {
                Op->Opcode = OP_MOVE;
                Op++;
            } else if (Op->Rs == Op->Rd) {
                Op++;
            } else if (Op->Rt == Op->Rd) {
                Op->Rt = Op->Rs;
                Op->Rs = Op->Rd;
                Op++;
            } else if (Op->Rs == SP || Op->Rt == SP) {
                Op++;
            }
            break;
        case SUBU_OP:
        case DSUBU_OP:
            if (Op->Rs == Op->Rd) {
                Op->Opcode = OP_SUB;
                Op++;
            }
            break;
        }
        break;
    case LUI_OP:
        Op->Opcode = OP_IMM;
        Op->Imm <<= 16;
        Op->Rd = Op->Rt;
        Op++;
        break;
    }
    return Op;
}
    
static INT
BuildOps (
    IN OUT POPERATION Operations,
    IN INT Max,
    IN ULONG Address,
    IN ULONG EndAddress,
    IN ULONG pcOfst)
/*++
Routine Description
    This function constructs an interpreter operation list based upon the machine
    instructions found between a start and end address.  

    The code is smart enough to handle a single level of calls, this is required
    if prolog helpers are being used.

Arguments
    Operations - A pointer to an interpreter operation array to receive the translated
        instructions.

    Max - Size of the operation array.

    Address - The address of the first instruction.

    EndAddress - The address of the last instruction.

Return Value:
    The number of operations generated.
--*/
{
    MIPS16_INSTRUCTION I16;
    MIPS_INSTRUCTION I32;
    ULONG RetAddress = (ULONG) -1;
    ULONG Extend = (ULONG) -1;
    ULONG PCAddress = Address;
    POPERATION Op = Operations;
    POPERATION LastOp = Operations + Max;
 
    while (Address != EndAddress && Op < LastOp) {
        if (Address & 1) {
            // Get MIPS16 instruction
            I16.Short = *((PUSHORT) (Address - 1));
            // Replace any break instruction introduced in the prolog
            // by the debugger with its original instruction
            if (I16.rr_format.Function == BREAK_OP16 &&
                I16.rr_format.Opcode == RR_OP16) {
                (*KDSanitize)((BYTE *)&I16.Short, (void *)(Address - 1), 
                           sizeof(I16.Short), FALSE);
            }
            switch (I16.i_format.Opcode) {
            case EXTEND_OP16:
                Extend = (I16.ei_format.Simmediate11 << 11) | (I16.ei_format.Immediate5 << 5);
                PCAddress = Address;
                Address += 2;
                break;
            case B_OP16:
                if (Extend == (ULONG) -1) {
                    Address += (I16.b_format.Simmediate << 1) + 2;
                } else {
                    Address += (I16.rri_format.Immediate | Extend) + 4;
                }
                PCAddress = Address;
                Extend = (ULONG) -1;
                break;
            case JALX_OP16:
                Op = BuildSimpleOp16 (Op, Address + 3, Address, (ULONG) -1);
                RetAddress = Address + 6;
                Address = (I16.j_format.Target16 << 18) | (I16.j_format.Target21 << 23) | (*(PUSHORT) (Address+1) << 2) | ((Address-pcOfst+3) & 0xf0000000);
                Address += pcOfst;
                Address |= (I16.j_format.Ext == 0);
                PCAddress = Address;
                Extend = (ULONG) -1;
                break;
            case RR_OP16:
                switch (I16.rr_format.Function) {
                case JR_OP16:
                    if (I16.rr_format.Ry == 1 && I16.rr_format.Rx == 0) {
                        // If this is a "JR RA" and we've nested then decode from return address
                        if (RetAddress != (ULONG) -1) {
                            Op = BuildSimpleOp16 (Op, Address + 1, PCAddress, (ULONG) -1);
                            PCAddress = Address = RetAddress;
                            RetAddress = (ULONG) -1;
                            Extend = (ULONG) -1;
                            continue;
                        }
                    }
                    // Anything other than JR RA is not acceptable in helper functions
                    return -1;
                }
                Address += 2;
                PCAddress = Address;
                Extend = (ULONG) -1;
                break;
            default:
                Op = BuildSimpleOp16 (Op, Address - 1, PCAddress, Extend);
                Address += 2;
                PCAddress = Address;
                Extend = (ULONG) -1;
                break;
            }
        } else {
            // Get MIPS32 instruction
            I32.Long = *(PULONG) Address;
            // Replace any break instruction introduced in the prolog
            // by the debugger with its original instruction
            if (I32.r_format.Function == BREAK_OP &&
                I32.r_format.Opcode == SPEC_OP) {
                (*KDSanitize)((BYTE *)&I32.Long, (void *)Address, 
                           sizeof(I32.Long), FALSE);
            }
            switch (I32.i_format.Opcode) {
            case JAL_OP:
                Op = BuildSimpleOp32 (Op, Address + 4, (BOOLEAN)(Op != Operations));
                RetAddress = Address + 8;
                Address = ((I32.j_format.Target << 2) | ((Address - pcOfst + 4) & 0xf0000000)) + pcOfst;
                if (I32.j_format.Target >> 26) Address |= 1;
                PCAddress = Address;
                break;
            case SPEC_OP:
                if (I32.Long == JUMP_RA && RetAddress != (ULONG) -1) {
                    Op = BuildSimpleOp32 (Op, Address + 4, (BOOLEAN)(Op != Operations));
                    Address = PCAddress = RetAddress;
                    RetAddress = (ULONG) -1;
                    continue;
                }
                // Note fallthrough
            default:
                Op = BuildSimpleOp32 (Op, Address, (BOOLEAN)(Op != Operations));
                Address += 4;
                break;
            }
        }
    }
    if (Address != EndAddress) {
        return -1;
    }
    return Op - Operations;
}

static void
FindValue (
    IN POPERATION Ops,
    IN DWORD NumOps,
    IN DWORD RegNum,
    IN OUT REG_TYPE *Regs)
/*++
Routine Description
    This function searches backwards through the Op array trying to deduce
    the value of an expression targeting a register.  Here, instructions
    must be executed forwards.

Arguments
    Ops - A pointer to an interpreter operation array.

    NumOps - Number of operations in the array.

    RegNum - Register to search for.

    Regs - Register value array to update.
--*/
{
    if (!IsScratchReg(RegNum)) return;
    
    while (NumOps-- > 0) {
        if (Ops->Rd == RegNum) {
            switch (Ops->Opcode) {
                case OP_IMM:
                    Regs [RegNum] = Ops->Imm;
                    break;

                case OP_ADD:
                case OP_SUB:
                    FindValue (Ops - 1, NumOps, Ops->Rs, Regs);
                    FindValue (Ops - 1, NumOps, Ops->Rt, Regs);
                    Regs [RegNum] = (Ops->Opcode == OP_ADD) ?
                                        Regs [Ops->Rs] + Regs [Ops->Rt] :
                                        Regs [Ops->Rs] - Regs [Ops->Rt];
                    break;

                case OP_ADDI:
                    FindValue (Ops - 1, NumOps, Ops->Rs, Regs);
                    Regs [RegNum] = Regs [Ops->Rs] + Ops->Imm;
                    break;

                case OP_MOVE:
                    FindValue (Ops - 1, NumOps, Ops->Rs, Regs);
                    Regs [RegNum] = Regs [Ops->Rs];
                    break;
            }
            // stop once we've found the definition of our register
            return;
        }
        Ops--;
    }
}

ULONG
Reverse (
    IN POPERATION Op,
    IN DWORD NumOps,
    IN OUT PCONTEXT Context)
/*++
Routine Description
Arguments
--*/
{
    REG_TYPE * IntRegs = &Context->IntZero;
    FREG_TYPE * FpRegs = &Context->FltF0;
    ULONG NextPc;
    BOOL RestoredRa = FALSE;
    
    Op += NumOps - 1;
    while (NumOps-- > 0) {
        switch (Op->Opcode) {
        case OP_ADD:
            if (Op->Rd == Op->Rs) {
                FindValue (Op-1, NumOps, Op->Rt, IntRegs);
                IntRegs [Op->Rd] -= IntRegs [Op->Rt];
            }
            break;
        case OP_SUB:
            if (Op->Rd == Op->Rs) {
                FindValue (Op-1, NumOps, Op->Rt, IntRegs);
                IntRegs [Op->Rd] += IntRegs [Op->Rt];
            }
            break;
        case OP_ADDI:
            if (Op->Rd == Op->Rs) {

⌨️ 快捷键说明

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