📄 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 + -