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

📄 mipsuwnd.c

📁 wince下的源代码集合打包
💻 C
📖 第 1 页 / 共 3 页
字号:
/*++    Copyright (c) 1997-2000 Microsoft Corporation.  All rights reserved.Module Name:    mipsuwnd.cAbstract:    This module implements the unwinding of procedure call frames for    exception processing on MIPS processors.--*/#include "kernel.h"// Define stack register and zero register numbers.#define RA 0x1f                         // integer register 31#define SP 0x1d                         // integer register 29#define ZERO 0x0                        // integer register 0#define NOREG -1                        // invalid register number#if defined(MIPS16SUPPORT)extern PRUNTIME_FUNCTION NKLookupFunctionEntry(PPROCESS, ULONG, PRUNTIME_FUNCTION);// Maximum number of instructions encoded by block with given start and end addresses#define BYTES_TO_OPCOUNT(_begin, _end)  (((_end) - (_begin)) >> (2 >> ((_end) & 1)))// Op count of longest prologue helper function called from the current mode#define MIPS_PROLHELPER_OPCOUNT(_pc) 13 // store 9 callee-saved regs, store RA, subtract saved-reg and arg area                                        // size from SP, subtract local var area size from SP, and return                                        // = 13 instructions.// Address of instruction adjacent to _pc: +/- 4 for MIPS32, +/- 2 for MIPS16#define MIPS_PREV_INSTR(_pc)  ((_pc) - (4 >> ((_pc) & 1)))#define MIPS_NEXT_INSTR(_pc)  ((_pc) + (4 >> ((_pc) & 1)))// MIPS16->MIPS32 register encoding conversion#define FIX_MIPS16_REG(r)     (((r) < 2) ? (r)+16 : (r))// MIPS16 MOV32R register encoding#define FIX_MOV32R_REG(r)     (((r) >> 2) | (((r) & 0x3) << 3))#define UNFIX_MOV32R_REG(r)   (((r) << 2) | (((r) & 0x18) >> 3))// MIPS16 instruction tests#define IS_MIPS16_MOV32RSP(i) (((i) & 0xfff8) == ((I8_OP16 << 11) | (MOV32R_OP16 << 8) | (UNFIX_MOV32R_REG (SP) << 3)))#define IS_MIPS16_ADDIUSP(i)  (((i) & 0xff00) == ((I8_OP16 << 11) | (ADJSP_OP16 << 8)))#define IS_MIPS16_JR(i)       (((i) & 0xf8ff) == ((RR_OP16 << 11) | JR_OP16))#define IS_MIPS16_JRRA(i)     ((i) == ((RR_OP16 << 11) | (0x1 << 5) | JR_OP16))#define IS_MIPS16_RETURN(i)   (IS_MIPS16_JR(i) || IS_MIPS16_JRRA(i))                // MIPS32 instruction tests#define IS_MIPS32_ADDIUSP(i) (((i) & 0xffff0000) == ((ADDIU_OP << 26) | (SP << 16) | (SP << 21)))#define IS_MIPS32_ADDUSP(i) (((i) & 0xffe0ffff) == ((SPEC_OP << 26) | ADDU_OP | (SP << 11) | (SP << 21)))#define IS_MIPS32_RETURN(i) ((i) == JUMP_RA)// Interpreter opcodesenum {    OP_NOP = 0,    OP_ADD,    OP_ADDI,    OP_SUB,    OP_OR,    OP_MOVE,    OP_IMM,    OP_STORE,    OP_FSTORE,    OP_DSTORE,};// Interpreter operation structuretypedef struct Operation {    BYTE Opcode;    BYTE Rd;    BYTE Rs;    BYTE Rt;    ULONG Imm;} OPERATION, *POPERATION;POPERATIONBuildSimpleOp16 (    IN OUT POPERATION Op,    IN ULONG Address,    IN ULONG PCAddress,    IN ULONG Extend)/*++Routine Description    This function converts a MIPS16 instruction at the specified address into the    equivalent interpreter instruction.Arguments    Op - A pointer to an interpreter operation structure to receive the translated        opcode.    Address - The address of the MIPS16 instruction.    PCAddress - The PC value at execution time (PCAddress != Address when the        instruction is being executed in a delay slot).    Extend - The value of a previous EXTEND opcode immediate field.  Set to -1        if the instruction is not extended.--*/{    MIPS16_INSTRUCTION Instruction;    ULONG UImm8, UImm5, SImm8;    Instruction.Short = *(PUSHORT) Address;    UImm8 = Instruction.ri_format.Immediate << 2;    UImm5 = Instruction.rri_format.Immediate << 2;    SImm8 = Instruction.rsi_format.Simmediate;    if (Extend != (ULONG) -1) {        SImm8 = UImm8 = UImm5 = Extend | Instruction.rri_format.Immediate;    }    Op->Opcode = OP_NOP;    Op->Rt = Op->Rs = Op->Rd = NOREG;    switch (Instruction.i_format.Opcode) {    case LI_OP16:        Op->Opcode = OP_IMM;        Op->Rd = FIX_MIPS16_REG (Instruction.ri_format.Rx);        Op->Imm = Instruction.ri_format.Immediate;        if (Extend != (ULONG) -1) {            Op->Imm = Extend | Instruction.rri_format.Immediate;        }        break;    case SW_OP16:        Op->Opcode = OP_STORE;        Op->Rs = FIX_MIPS16_REG (Instruction.rri_format.Rx);        Op->Rt = FIX_MIPS16_REG (Instruction.rri_format.Ry);        Op->Imm = UImm5;        break;    case SWSP_OP16:        Op->Opcode = OP_STORE;        Op->Rs = SP;        Op->Rt = FIX_MIPS16_REG (Instruction.ri_format.Rx);        Op->Imm = UImm8;        break;    case LWPC_OP16:        Op->Opcode = OP_IMM;        Op->Rd = FIX_MIPS16_REG (Instruction.ri_format.Rx);        Op->Imm = *(PULONG) ((PCAddress & ~3) + UImm8);        break;    case ADDIU8_OP16:        Op->Opcode = OP_ADDI;        Op->Rs = Op->Rd = FIX_MIPS16_REG (Instruction.ri_format.Rx);        Op->Imm = SImm8;        break;    case RRR_OP16:        Op->Rd = FIX_MIPS16_REG (Instruction.rrr_format.Rz);        Op->Rs = FIX_MIPS16_REG (Instruction.rrr_format.Rx);        Op->Rt = FIX_MIPS16_REG (Instruction.rrr_format.Ry);        if (Op->Rs != Op->Rd) break;        switch (Instruction.rrr_format.Function) {        case SUBU_OP16:            Op->Opcode = OP_SUB;            break;        case ADDU_OP16:            Op->Opcode = OP_ADD;            break;        }        break;    case I8_OP16:        switch (Instruction.i8_format.Function) {        case SWRASP_OP16:            Op->Opcode = OP_STORE;            Op->Rs = SP;            Op->Rt = RA;            Op->Imm = UImm8;            break;        case ADJSP_OP16:            Op->Opcode = OP_ADDI;            Op->Rs = Op->Rd = SP;            Op->Imm = SImm8;            if (Extend == (ULONG) -1) {                Op->Imm = SImm8 << 3;            }            break;        case MOV32R_OP16:            Op->Opcode = OP_MOVE;            Op->Rd = FIX_MOV32R_REG (Instruction.mov32r_format.R32);            Op->Rs = FIX_MIPS16_REG (Instruction.mov32r_format.Rz);            break;        case MOVR32_OP16:            Op->Opcode = OP_MOVE;            Op->Rd = FIX_MIPS16_REG (Instruction.movr32_format.Ry);            Op->Rs = (BYTE) Instruction.movr32_format.R32;            break;        }        break;    default:        break;    }    return Op + (Op->Opcode != OP_NOP);}POPERATIONBuildSimpleOp32 (    IN OUT POPERATION Op,    IN ULONG Address,    IN BOOLEAN NotFirst)/*++Routine Description    This function converts a MIPS32 instruction at the specified address into the    equivalent interpreter instruction.  It will attempt to compress LUI-ORI pairs    into a single OP_IMM operation.Arguments    Op - A pointer to an interpreter operation structure to receive the translated        opcode.    Address - The address of the MIPS32 instruction.    NotFirst - True if this is not the first Op in the list, to tell LUI-ORI        compression to look at the previous operation at Op-1. --*/{    MIPS_INSTRUCTION I32;    I32.Long = *(PULONG) Address;    Op->Rs = (BYTE) I32.i_format.Rs;    Op->Rt = (BYTE) I32.i_format.Rt;    Op->Rd = (BYTE) I32.r_format.Rd;    Op->Imm = I32.i_format.Simmediate;    switch (I32.i_format.Opcode) {    case SW_OP:        Op->Opcode = OP_STORE;        goto store;    case SWC1_OP:        Op->Opcode = OP_FSTORE;        goto store;    case SDC1_OP:        Op->Opcode = OP_DSTORE;    store:        if (Op->Rs == SP) {            Op->Rd = NOREG;            Op++;        }        break;    case ADDIU_OP:        Op->Rd = Op->Rt;        if (Op->Rs == Op->Rt) {            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++;            }            break;        case SUBU_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;}    INTBuildOps (    IN OUT POPERATION Operations,    IN INT Max,    IN ULONG Address,    IN ULONG EndAddress)/*++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

⌨️ 快捷键说明

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