in src/disasm.cpp [3445:3531]
BYTE CDetourDis::BeginCopy32(BYTE* pSource, BYTE* pDest)
{
ULONG instruction = GetLongInstruction(pSource);
// Immediate data processing instructions; ADD, SUB, MOV, MOVN, ADR, MOVT, BFC, SSAT16, etc.
if ((instruction & 0xF8008000) == 0xF0000000) { // 11110xxxxxxxxxxx0xxxxxxxxxxxxxxx
// Should all be blitt-able
// ToDo: What about ADR? Is it safe to do a straight-copy?
// ToDo: Not handling moves to or from PC
return PureCopy32(pSource, pDest);
}
// Non-Immediate data processing instructions; ADD, EOR, TST, etc.
if ((instruction & 0xEE000000) == 0xEA000000) { // 111x101xxxxxxxxxxxxxxxxxxxxxxx
// Should all be blitt-able
return PureCopy32(pSource, pDest);
}
// Load and store single data item, memory hints
if ((instruction & 0xFE000000) == 0xF8000000) { // 1111100xxxxxxxxxxxxxxxxxxxxxxxxx
return CopyLoadAndStoreSingle(pSource, pDest);
}
// Load and store, double and exclusive, and table branch
if ((instruction & 0xFE400000) == 0xE8400000) { // 1110100xx1xxxxxxxxxxxxxxxxxxxxxx
// Load and store double
if (instruction & 0x1200000) {
// LDRD, STRD (immediate) : xxxxxxxPxxWxxxxxxxxxxxxxxxxxxxxx where PW != 0b00
// The source register is PC
if ((instruction & 0xF0000) == 0xF0000) {
// ToDo: If the source register is PC, what should we do?
ASSERT(false);
}
// If either target registers are PC
if (((instruction & 0xF000) == 0xF000) ||
((instruction & 0xF00) == 0xF00)) {
m_pbTarget = (PBYTE)DETOUR_INSTRUCTION_TARGET_DYNAMIC;
}
return PureCopy32(pSource, pDest);
}
// Load and store exclusive
if (!(instruction & 0x800000)) { // LDREX, STREX : xxxxxxxx0xxxxxxxxxxxxxxxxxxxxxxx
if ((instruction & 0xF000) == 0xF000) { // xxxxxxxxxxxx1111xxxxxxxxxxxx
m_pbTarget = (PBYTE)DETOUR_INSTRUCTION_TARGET_DYNAMIC;
}
return PureCopy32(pSource, pDest);
}
// Table branch
if ((instruction & 0x1000F0) == 0x100000 || // TBB : xxxxxxxxxxx1xxxxxxxxxxxx0000xxxx
(instruction & 0x1000F0) == 0x100010) { // TBH : xxxxxxxxxxx1xxxxxxxxxxxx0001xxxx
return CopyTableBranch(pSource, pDest);
}
// Load and store exclusive byte, halfword, doubleword (LDREXB, LDREXH, LDREXD, STREXB, STREXH, STREXD, etc.)
return PureCopy32(pSource, pDest);
}
// Load and store multiple, RFE and SRS
if ((instruction & 0xFE400000) == 0xE8000000) { // 1110100xx0xxxxxxxxxxxxxxxxxxxxxx
// Return from exception (RFE)
if ((instruction & 0xE9900000) == 0xE9900000 || // 1110100110x1xxxxxxxxxxxxxxxxxxxx
(instruction & 0xE8100000) == 0xE8100000) { // 1110100000x1xxxxxxxxxxxxxxxxxxxx
return PureCopy32(pSource, pDest);
}
return CopyLoadAndStoreMultipleAndSRS(pSource, pDest);
}
// Branches, miscellaneous control
if ((instruction & 0xF8008000) == 0xF0008000) { // 11110xxxxxxxxxxx0xxxxxxxxxxxxxxx
// Branches, miscellaneous control
return CopyBranchOrMiscellaneous32(pSource, pDest);
}
// Coprocessor instructions
if ((instruction & 0xEC000000) == 0xEC000000) { // 111x11xxxxxxxxxxxxxxxxxxxxxxxxxx
return PureCopy32(pSource, pDest);
}
// Unhandled instruction; should never make it this far
ASSERT(false);
return PureCopy32(pSource, pDest);
}