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

📄 shunwind.c

📁 windows ce 3.00 嵌入式操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        //
        // Used to push permanent registers to stack
        else if ((Instruction.instr3.opcode   == 0x2) &&
                 (Instruction.instr3.ext_disp == 0x6) &&
                 (Instruction.instr3.regN     == sp )) {
            Rm = Instruction.instr3.regM;
            IntegerRegister[Rm] = *(PULONG)IntegerRegister[sp];
            IntegerRegister[sp] += 4;
        }

#if SH4
        // FMOV FRm,FRn (or any combination of DRm,DRn,XDm,XDn)
        else if ((Instruction.instr3.opcode   == 0xf) &&
                 (Instruction.instr3.ext_disp == 0xc)) {
            Rm = Instruction.instr3.regM;
            Rn = Instruction.instr3.regN;
            if (ContextRecord->Fpscr & SZ_MASK) {
                Rm += (Rm & 0x1)*15; // DRm or XDm
                Rn += (Rn & 0x1)*15; // DRn or XDn
                // the other 32 bits of the double precision move
                FloatingRegister[Rm+1] = FloatingRegister[Rn+1];
            }
            FloatingRegister[Rm] = FloatingRegister[Rn];
        }

        // FMOV(.S) FRm,@-sp (must check for sp)
        //
        // Used to push permanent fp registers to stack
        else if ((Instruction.instr3.opcode   == 0xf) &&
                 (Instruction.instr3.ext_disp == 0xb) &&
                 (Instruction.instr3.regN     == sp)) {
            Rm = Instruction.instr3.regM;
            if (ContextRecord->Fpscr & SZ_MASK) {
                // low order bits in FR(m+1), and high order in FRm
                FloatingRegister[Rm+1] = *(PULONG)IntegerRegister[sp];
                IntegerRegister[sp] += 4;
            }
            FloatingRegister[Rm] = *(PULONG)IntegerRegister[sp];
            IntegerRegister[sp] += 4;
        }

        // FSCHG
        else if (Instruction.instr6.opcode == 0xf3fd) {
            ContextRecord->Fpscr ^= SZ_MASK;    // toggle the SZ bit
        }
#endif

        // MOV.L @(disp,pc),Rn
        //
        // Used to load stack decrement value into a register
        else if (Instruction.instr2.opcode == 0xD) {
            Rn = Instruction.instr2.reg;
            if (Rn == PendingSource) {
                // Address = 4-byte aligned current instruction address +
                //           4 (SH3 pc points 2 instructions downstream) +
                //           4-byte scaled displacement (from instruction)
                Address = (ControlPc & 0xfffffffc) + 4 +
                          (Instruction.instr2.imm_disp << 2);
    			PendingValue = *(PLONG)Address;
                if (PendingAdd) {
                    PendingValue = -PendingValue;
                }
                IntegerRegister[PendingTarget] += PendingValue;
            }
        }

        // MOV.W @(disp,pc),Rn
        //
        // Used to load stack decrement value into a register
        else if (Instruction.instr2.opcode == 0x9) {
            Rn = Instruction.instr2.reg;
            if (Rn == PendingSource) {
                // Address = current instruction address +
                //           4 (SH3 pc points 2 instructions downstream) +
                //           2-byte scaled displacement (from instruction)
                Address = ControlPc + 4 + (Instruction.instr2.imm_disp << 1);
                PendingValue = *(short *)Address;
                if (PendingAdd) {
                    PendingValue = -PendingValue;
                }
                IntegerRegister[PendingTarget] += PendingValue;
            }
        }

        // ADD #imm,Rn
        //
        // Used to allocate space on the stack (#imm < 0)
        else if (Instruction.instr2.opcode == 0x7) {
            Rn = Instruction.instr2.reg;
            Offset = (signed char)Instruction.instr2.imm_disp;
///            if (Offset & 0x80) {
///                // Offset is negative, so add 2's-complement
///                Offset = (~Offset + 1) & 0xff;
///                IntegerRegister[Rn] += Offset;
///            } else {
                // Offset is positive, so subtract it
            IntegerRegister[Rn] -= Offset;
///            }
        }

        // SUB Rm,Rn
        //
        // Used to allocate space on the stack
        else if ((Instruction.instr3.opcode   == 0x3) &&
                 (Instruction.instr3.ext_disp == 0x8)) {
            Rm = Instruction.instr3.regM;
            Rn = Instruction.instr3.regN;
            PendingSource = Rm;
            PendingTarget = Rn;
            PendingAdd = FALSE;
        }

        // ADD Rm,Rn
        //
        // Used to allocate space on the stack
        else if ((Instruction.instr3.opcode   == 0x3) &&
                 (Instruction.instr3.ext_disp == 0xc)) {
            Rm = Instruction.instr3.regM;
            Rn = Instruction.instr3.regN;
            PendingSource = Rm;
            PendingTarget = Rn;
            PendingAdd = TRUE;
        }


        // MOV.L Rm,@(disp,Rn)
        //
        // Used to store register values to stack
        else if (Instruction.instr3.opcode == 0x1) {
            Rm = Instruction.instr3.regM;
            Rn = Instruction.instr3.regN;
            TemporaryRegister = Rm;
            Address = IntegerRegister[Rn] + (Instruction.instr3.ext_disp << 2);
            TemporaryValue = *(PULONG)Address;
            // Added for unwinding parameter values
            IntegerRegister[Rm] = TemporaryValue;
        }

        // STS mach,Rn
        //
        // (special prolog only)
        else if ((Instruction.instr1.opcode   == 0x0) &&
                 (Instruction.instr1.function == 0x0a)) {
            Rn = Instruction.instr1.reg;
            if (Rn == TemporaryRegister) {
                ContextRecord->MACH = TemporaryValue;
            }
        }

        // STS macl,Rn
        //
        // (special prolog only)
        else if ((Instruction.instr1.opcode   == 0x0) &&
                 (Instruction.instr1.function == 0x1a)) {
            Rn = Instruction.instr1.reg;
            if (Rn == TemporaryRegister) {
                ContextRecord->MACL = TemporaryValue;
            }
        }

        // STS pr,Rn
        //
        // (special prolog only)
        //
        // NOTE: since this instruction is only in the prolog it cannot
        //       be the NextPc...only STC spc,Rn can
        else if ((Instruction.instr1.opcode   == 0x0) &&
                 (Instruction.instr1.function == 0x2a)) {
            Rn = Instruction.instr1.reg;
            if (Rn == TemporaryRegister) {
                ContextRecord->PR = TemporaryValue;
            }
        }

        // STC gbr,Rn
        //
        // (special prolog only)
        else if ((Instruction.instr1.opcode   == 0x0) &&
                 (Instruction.instr1.function == 0x12)) {
            Rn = Instruction.instr1.reg;
            if (Rn == TemporaryRegister) {
                ContextRecord->GBR = TemporaryValue;
            }
        }

        // STC Psr,Rn
        //
        // (special prolog only)
        else if ((Instruction.instr1.opcode   == 0x0) &&
                 (Instruction.instr1.function == 0x32)) {
            Rn = Instruction.instr1.reg;
            if (Rn == TemporaryRegister) {
                ContextRecord->Psr = TemporaryValue;
            }
        }

        // STC Fir,Rn
        //
        // (special prolog only)
        else if ((Instruction.instr1.opcode   == 0x0) &&
                 (Instruction.instr1.function == 0x42)) {
            Rn = Instruction.instr1.reg;
            if (Rn == TemporaryRegister) {
                NextPc = TemporaryValue;
            }
        }

#if SH4
        // STS.L fpscr,@-Rn
        //
        // (special prolog only)
        else if ((Instruction.instr1.opcode   == 0x4) &&
                 (Instruction.instr1.function == 0x62)) {
            Rn = Instruction.instr1.reg;
            ContextRecord->Fpscr = *(PULONG)IntegerRegister[Rn];
            IntegerRegister[Rn] += 4;
        }
#endif

        // STS.L pr,@-Rn
        else if ((Instruction.instr1.opcode   == 0x4) &&
                 (Instruction.instr1.function == 0x22)) {
            Rn = Instruction.instr1.reg;
            ContextRecord->PR = *(PULONG)IntegerRegister[Rn];
            IntegerRegister[Rn] += 4;
            NextPc = ContextRecord->PR - 2;
        } else {
            DEBUGMSG(ZONE_SEH, (TEXT("RtlVirtualUnwind: unknown instruction in proglog @%8.8lx=%4.4x\r\n"),
                    ControlPc, Instruction));
        }
    }
    *EstablisherFrame = ContextRecord->R15;
    return NextPc;
}

⌨️ 快捷键说明

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