Use pcodeops for bitrev and byterev.

This commit is contained in:
Alessandro Gatti
2022-06-08 20:36:33 +02:00
parent 4ebeee777f
commit b44355f367
2 changed files with 62 additions and 10 deletions

View File

@@ -860,20 +860,16 @@ define pcodeop countLeadingZeros;
@ifdef COLDFIRE
define pcodeop bitReverse;
:bitrev regdn is reg315=0x18 & regdn {
local dword = regdn;
regdn[31,1] = dword[0,1]; regdn[30,1] = dword[1,1]; regdn[29,1] = dword[2,1]; regdn[28,1] = dword[3,1];
regdn[27,1] = dword[4,1]; regdn[26,1] = dword[5,1]; regdn[25,1] = dword[6,1]; regdn[24,1] = dword[7,1];
regdn[23,1] = dword[8,1]; regdn[22,1] = dword[9,1]; regdn[21,1] = dword[10,1]; regdn[20,1] = dword[11,1];
regdn[19,1] = dword[12,1]; regdn[18,1] = dword[13,1]; regdn[17,1] = dword[14,1]; regdn[16,1] = dword[15,1];
regdn[15,1] = dword[16,1]; regdn[14,1] = dword[17,1]; regdn[13,1] = dword[18,1]; regdn[12,1] = dword[19,1];
regdn[11,1] = dword[20,1]; regdn[10,1] = dword[21,1]; regdn[9,1] = dword[22,1]; regdn[8,1] = dword[23,1];
regdn[7,1] = dword[24,1]; regdn[6,1] = dword[25,1]; regdn[5,1] = dword[26,1]; regdn[4,1] = dword[27,1];
regdn[3,1] = dword[28,1]; regdn[2,1] = dword[29,1]; regdn[1,1] = dword[30,1]; regdn[0,1] = dword[31,1];
regdn = bitReverse(regdn);
}
define pcodeop byteReverse;
:byterev regdn is reg315=0x58 & regdn {
regdn = ((regdn & 0x000000FF) << 24) | ((regdn & 0x0000FF00) << 8) | ((regdn & 0x00FF0000) >> 8) | ((regdn & 0xFF000000) >> 24);
regdn = byteReverse(regdn);
}
@endif # COLDFIRE

View File

@@ -50,6 +50,8 @@ public class m68kEmulateInstructionStateModifier extends EmulateInstructionState
registerPcodeOpBehavior("countLeadingZeros", new CountLeadingZerosOpBehavior());
registerPcodeOpBehavior("findFirstOne", new FindFirstOneOpBehavior());
registerPcodeOpBehavior("bitReverse", new BitReverseOpBehavior());
registerPcodeOpBehavior("byteReverse", new ByteReverseOpBehavior());
}
/**
@@ -142,4 +144,58 @@ public class m68kEmulateInstructionStateModifier extends EmulateInstructionState
}
}
private static class BitReverseOpBehavior implements OpBehaviorOther {
@Override
public void evaluate(Emulate emu, Varnode out, Varnode[] inputs) {
if (out == null) {
throw new LowlevelError("CALLOTHER: Bit Reverse op missing required output");
}
if (inputs.length != 2 || inputs[1].getSize() == 0 || !inputs[1].isRegister()) {
throw new LowlevelError(
"CALLOTHER: Bit Reverse op requires one register varnode input");
}
Varnode in = inputs[1];
MemoryState memoryState = emu.getMemoryState();
long value = memoryState.getValue(in);
long size = in.getSize() * 8;
long bitFrom = size - 1;
long bitTo = 0;
long reversed = 0;
while (bitFrom >= 0) {
reversed |= ((value >> bitFrom) & 1L) << bitTo;
bitTo++;
}
memoryState.setValue(out, reversed);
}
}
private static class ByteReverseOpBehavior implements OpBehaviorOther {
@Override
public void evaluate(Emulate emu, Varnode out, Varnode[] inputs) {
if (out == null) {
throw new LowlevelError("CALLOTHER: Byte Reverse op missing required output");
}
if (inputs.length != 2 || inputs[1].getSize() == 0 || !inputs[1].isRegister()) {
throw new LowlevelError(
"CALLOTHER: Byte Reverse op requires one register varnode input");
}
Varnode in = inputs[1];
MemoryState memoryState = emu.getMemoryState();
long value = memoryState.getValue(in);
memoryState.setValue(out, ((value & 0x000000FF) << 24) | ((value & 0x0000FF00) << 8) |
((value & 0x00FF0000) >> 8) | ((value & 0xFF000000) >> 24));
}
}
}