📄 shunwind.c
字号:
// // 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 + -