|
|
@@ -1187,7 +1187,14 @@ public:
|
|
|
Framework::Assembly::OperationArgument* arg,
|
|
|
int index) const
|
|
|
{
|
|
|
- result.immLength = 1;
|
|
|
+ if (result.immLength >= 8)
|
|
|
+ {
|
|
|
+ Framework::Text* err = new Framework::Text();
|
|
|
+ err->append() << "Invalid argument type for operand " << index
|
|
|
+ << " for operation " << op
|
|
|
+ << " encoded as IMM8: imm bytes are already in use";
|
|
|
+ throw err->getText();
|
|
|
+ }
|
|
|
const Framework::Assembly::ConstantArgument* constArg
|
|
|
= arg->asConstantArgument();
|
|
|
if (constArg == 0)
|
|
|
@@ -1210,15 +1217,22 @@ public:
|
|
|
<< " but expected size BYTE";
|
|
|
throw err->getText();
|
|
|
}
|
|
|
- result.imm[0] = (char)(value);
|
|
|
- result.immLength = 1;
|
|
|
+ result.imm[(int)result.immLength] = (char)(value);
|
|
|
+ result.immLength += 1;
|
|
|
}
|
|
|
|
|
|
void encodeIMM16(MachineCodeInstruction& result,
|
|
|
Framework::Assembly::OperationArgument* arg,
|
|
|
int index) const
|
|
|
{
|
|
|
- result.immLength = 1;
|
|
|
+ if (result.immLength >= 7)
|
|
|
+ {
|
|
|
+ Framework::Text* err = new Framework::Text();
|
|
|
+ err->append() << "Invalid argument type for operand " << index
|
|
|
+ << " for operation " << op
|
|
|
+ << " encoded as IMM8: imm bytes are already in use";
|
|
|
+ throw err->getText();
|
|
|
+ }
|
|
|
const Framework::Assembly::ConstantArgument* constArg
|
|
|
= arg->asConstantArgument();
|
|
|
if (constArg == 0)
|
|
|
@@ -1242,15 +1256,22 @@ public:
|
|
|
throw err->getText();
|
|
|
}
|
|
|
short val = (short)(value);
|
|
|
- memcpy(result.imm, &val, 2);
|
|
|
- result.immLength = 2;
|
|
|
+ memcpy(result.imm + result.immLength, &val, 2);
|
|
|
+ result.immLength += 2;
|
|
|
}
|
|
|
|
|
|
void encodeIMM32(MachineCodeInstruction& result,
|
|
|
Framework::Assembly::OperationArgument* arg,
|
|
|
int index) const
|
|
|
{
|
|
|
- result.immLength = 1;
|
|
|
+ if (result.immLength >= 5)
|
|
|
+ {
|
|
|
+ Framework::Text* err = new Framework::Text();
|
|
|
+ err->append() << "Invalid argument type for operand " << index
|
|
|
+ << " for operation " << op
|
|
|
+ << " encoded as IMM8: imm bytes are already in use";
|
|
|
+ throw err->getText();
|
|
|
+ }
|
|
|
const Framework::Assembly::ConstantArgument* constArg
|
|
|
= arg->asConstantArgument();
|
|
|
if (constArg == 0)
|
|
|
@@ -1273,15 +1294,22 @@ public:
|
|
|
<< " but expected size range [BYTE, DWORD]";
|
|
|
throw err->getText();
|
|
|
}
|
|
|
- memcpy(result.imm, &value, 4);
|
|
|
- result.immLength = 4;
|
|
|
+ memcpy(result.imm + result.immLength, &value, 4);
|
|
|
+ result.immLength += 4;
|
|
|
}
|
|
|
|
|
|
void encodeIMM64(MachineCodeInstruction& result,
|
|
|
Framework::Assembly::OperationArgument* arg,
|
|
|
int index) const
|
|
|
{
|
|
|
- result.immLength = 1;
|
|
|
+ if (result.immLength >= 1)
|
|
|
+ {
|
|
|
+ Framework::Text* err = new Framework::Text();
|
|
|
+ err->append() << "Invalid argument type for operand " << index
|
|
|
+ << " for operation " << op
|
|
|
+ << " encoded as IMM8: imm bytes are already in use";
|
|
|
+ throw err->getText();
|
|
|
+ }
|
|
|
const Framework::Assembly::ConstantArgument* constArg
|
|
|
= arg->asConstantArgument();
|
|
|
if (constArg == 0)
|
|
|
@@ -1304,8 +1332,8 @@ public:
|
|
|
<< " but expected size range [BYTE, QWORD]";
|
|
|
throw err->getText();
|
|
|
}
|
|
|
- memcpy(result.imm, &value, 8);
|
|
|
- result.immLength = 8;
|
|
|
+ memcpy(result.imm + result.immLength, &value, 8);
|
|
|
+ result.immLength += 8;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
@@ -6296,6 +6324,28 @@ void __intializeMachineCodeTranslationTable()
|
|
|
Framework::Assembly::MemoryBlockSize::QWORD),
|
|
|
MODRM_RM,
|
|
|
READ)}));
|
|
|
+ OperationCodeTable::machineCodeTranslationTable.add(
|
|
|
+ new OperationCodeTable(Framework::Assembly::ENTER,
|
|
|
+ {// ENTER
|
|
|
+ MachineCodeTableEntry(false,
|
|
|
+ 0xC8,
|
|
|
+ (char)1,
|
|
|
+ false,
|
|
|
+ false,
|
|
|
+ false,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ isIMM(Framework::Assembly::MemoryBlockSize::WORD),
|
|
|
+ IMM16,
|
|
|
+ READ,
|
|
|
+ isIMM(Framework::Assembly::MemoryBlockSize::BYTE),
|
|
|
+ IMM8,
|
|
|
+ READ)}));
|
|
|
+ OperationCodeTable::machineCodeTranslationTable.add(
|
|
|
+ new OperationCodeTable(Framework::Assembly::LEAVE,
|
|
|
+ {// LEAVE
|
|
|
+ MachineCodeTableEntry(
|
|
|
+ false, 0xC9, (char)1, false, false, false, 0, 0)}));
|
|
|
OperationCodeTable::machineCodeTranslationTable.add(
|
|
|
new OperationCodeTable(Framework::Assembly::RET,
|
|
|
{// RET
|
|
|
@@ -7054,14 +7104,115 @@ void Framework::Assembly::AssemblyBlock::addLoadValue(
|
|
|
new MemoryAccessArgument(MemoryBlockSize::QWORD, temp)}));
|
|
|
}
|
|
|
|
|
|
+void Framework::Assembly::AssemblyBlock::addMoveValue(
|
|
|
+ GPRegister target, char value)
|
|
|
+{
|
|
|
+ instructions.add(new Instruction(MOV,
|
|
|
+ {new GPRegisterArgument(target, LOWER8), new ConstantArgument(value)}));
|
|
|
+}
|
|
|
+
|
|
|
+void Framework::Assembly::AssemblyBlock::addMoveValue(
|
|
|
+ GPRegister target, short value)
|
|
|
+{
|
|
|
+ instructions.add(new Instruction(MOV,
|
|
|
+ {new GPRegisterArgument(target, LOWER16),
|
|
|
+ new ConstantArgument(value)}));
|
|
|
+}
|
|
|
+
|
|
|
+void Framework::Assembly::AssemblyBlock::addMoveValue(
|
|
|
+ GPRegister target, int value)
|
|
|
+{
|
|
|
+ instructions.add(new Instruction(MOV,
|
|
|
+ {new GPRegisterArgument(target, LOWER32),
|
|
|
+ new ConstantArgument(value)}));
|
|
|
+}
|
|
|
+
|
|
|
+void Framework::Assembly::AssemblyBlock::addMoveValue(
|
|
|
+ GPRegister target, __int64 value)
|
|
|
+{
|
|
|
+ instructions.add(new Instruction(
|
|
|
+ MOV, {new GPRegisterArgument(target), new ConstantArgument(value)}));
|
|
|
+}
|
|
|
+
|
|
|
+void Framework::Assembly::AssemblyBlock::addMoveValue(
|
|
|
+ FPRegister target, float value, GPRegister temp)
|
|
|
+{
|
|
|
+ int data = *reinterpret_cast<int*>(&value);
|
|
|
+ addMoveValue(temp, data);
|
|
|
+ addPush(temp, LOWER32);
|
|
|
+ instructions.add(new Instruction(MOVSS,
|
|
|
+ {new FPRegisterArgument(target, X),
|
|
|
+ new MemoryAccessArgument(
|
|
|
+ MemoryBlockSize::DWORD, RSP, true, -4, true)}));
|
|
|
+ addPop(temp, LOWER32);
|
|
|
+}
|
|
|
+
|
|
|
+void Framework::Assembly::AssemblyBlock::addMoveValue(
|
|
|
+ FPRegister target, double value, GPRegister temp)
|
|
|
+{
|
|
|
+ __int64 data = *reinterpret_cast<__int64*>(&value);
|
|
|
+ addMoveValue(temp, data);
|
|
|
+ addPush(temp);
|
|
|
+ instructions.add(new Instruction(MOVSD,
|
|
|
+ {new FPRegisterArgument(target, X),
|
|
|
+ new MemoryAccessArgument(
|
|
|
+ MemoryBlockSize::QWORD, RSP, true, -8, true)}));
|
|
|
+ addPop(temp);
|
|
|
+}
|
|
|
+
|
|
|
+void Framework::Assembly::AssemblyBlock::addMoveValue(
|
|
|
+ GPRegister target, GPRegister source, GPRegisterPart part)
|
|
|
+{
|
|
|
+ instructions.add(new Instruction(MOV,
|
|
|
+ {new GPRegisterArgument(target, part),
|
|
|
+ new GPRegisterArgument(source, part)}));
|
|
|
+}
|
|
|
+
|
|
|
+void Framework::Assembly::AssemblyBlock::addMoveValue(
|
|
|
+ FPRegister target, FPRegister source, FPDataType type, FPRegisterPart part)
|
|
|
+{
|
|
|
+ Operation op = NOP;
|
|
|
+ switch (type)
|
|
|
+ {
|
|
|
+ case SINGLE_FLOAT:
|
|
|
+ op = MOVSS;
|
|
|
+ break;
|
|
|
+ case SINGLE_DOUBLE:
|
|
|
+ op = MOVSD;
|
|
|
+ break;
|
|
|
+ case PACKED_FLOAT:
|
|
|
+ op = MOVAPS;
|
|
|
+ break;
|
|
|
+ case PACKED_DOUBLE:
|
|
|
+ op = MOVAPD;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ instructions.add(new Instruction(op,
|
|
|
+ {new FPRegisterArgument(target, part),
|
|
|
+ new FPRegisterArgument(source, part)}));
|
|
|
+}
|
|
|
+
|
|
|
void Framework::Assembly::AssemblyBlock::addCall(
|
|
|
void* functionAddress, GPRegister temp)
|
|
|
{
|
|
|
instructions.add(new Instruction(MOV,
|
|
|
{new GPRegisterArgument(temp),
|
|
|
new ConstantArgument(reinterpret_cast<__int64>(functionAddress))}));
|
|
|
- instructions.add(new Instruction(
|
|
|
- CALL, {new MemoryAccessArgument(MemoryBlockSize::QWORD, temp)}));
|
|
|
+ instructions.add(new Instruction(CALL, {new GPRegisterArgument(temp)}));
|
|
|
+}
|
|
|
+
|
|
|
+void Framework::Assembly::AssemblyBlock::addEnter(
|
|
|
+ short stackSize, char nestingLevel)
|
|
|
+{
|
|
|
+ instructions.add(
|
|
|
+ new Framework::Assembly::Instruction(Framework::Assembly::ENTER,
|
|
|
+ {new Framework::Assembly::ConstantArgument(stackSize),
|
|
|
+ new Framework::Assembly::ConstantArgument(nestingLevel)}));
|
|
|
+}
|
|
|
+
|
|
|
+void Framework::Assembly::AssemblyBlock::addLeave()
|
|
|
+{
|
|
|
+ instructions.add(new Instruction(LEAVE, {}));
|
|
|
}
|
|
|
|
|
|
void Framework::Assembly::AssemblyBlock::addReturn()
|