浏览代码

fix problems with windows calling conventions and stack pointer alignment

Kolja Strohm 3 月之前
父节点
当前提交
11df41f23f
共有 5 个文件被更改,包括 2266 次插入986 次删除
  1. 1627 839
      Assembly.cpp
  2. 433 69
      Assembly.h
  3. 5 0
      CharMap.h
  4. 163 74
      Framework Tests/Assembly.cpp
  5. 38 4
      Trie.h

+ 1627 - 839
Assembly.cpp

@@ -2,6 +2,29 @@
 
 #include "InMemoryBuffer.h"
 
+enum OperandSizeOverwrite
+{
+    NO_PREFIX = 0,
+    X66 = 0x66,
+    XF2 = 0xF2,
+    XF3 = 0xF3
+};
+
+bool isVolatile(Framework::Assembly::GPRegister reg)
+{
+    return reg == Framework::Assembly::RAX || reg == Framework::Assembly::RCX
+        || reg == Framework::Assembly::RDX || reg == Framework::Assembly::R8
+        || reg == Framework::Assembly::R9 || reg == Framework::Assembly::R10
+        || reg == Framework::Assembly::R11;
+}
+
+bool isVolatile(Framework::Assembly::FPRegister reg)
+{
+    return reg == Framework::Assembly::MM0 || reg == Framework::Assembly::MM1
+        || reg == Framework::Assembly::MM2 || reg == Framework::Assembly::MM3
+        || reg == Framework::Assembly::MM4 || reg == Framework::Assembly::MM5;
+}
+
 struct MachineCodeInstruction
 {
     bool needsRex;
@@ -15,7 +38,7 @@ struct MachineCodeInstruction
     char dispLength;
     char imm[8];
     char immLength;
-    bool operandSizeOverride;
+    OperandSizeOverwrite operandSizeOverride;
     bool errIfRex;
     bool errIfNoRex;
     bool exR;
@@ -31,7 +54,7 @@ struct MachineCodeInstruction
     {
         if (operandSizeOverride)
         {
-            char prefix = 0x66;
+            char prefix = *(char*)&operandSizeOverride;
             writer.schreibe(&prefix, 1);
         }
         if (needsRex && !needsVex)
@@ -209,13 +232,13 @@ private:
     std::vector<Framework::Assembly::GPRegister> impliedWriteGPRegs;
     std::vector<Framework::Assembly::FPRegister> impliedReadFPRegs;
     std::vector<Framework::Assembly::FPRegister> impliedWriteFPRegs;
-    bool operandSizeOverride;
+    OperandSizeOverwrite operandSizeOverride;
 
 public:
     MachineCodeTableEntry(bool rexW,
         int opcode,
         char opcodeLength,
-        bool operandSizeOverride,
+        OperandSizeOverwrite operandSizeOverride,
         bool vex,
         bool vexL,
         char vexPP,
@@ -245,7 +268,7 @@ public:
     MachineCodeTableEntry(bool rexW,
         int opcode,
         char opcodeLength,
-        bool operandSizeOverride,
+        OperandSizeOverwrite operandSizeOverride,
         bool vex,
         bool vexL,
         char vexPP,
@@ -279,7 +302,7 @@ public:
     MachineCodeTableEntry(bool rexW,
         int opcode,
         char opcodeLength,
-        bool operandSizeOverride,
+        OperandSizeOverwrite operandSizeOverride,
         bool vex,
         bool vexL,
         char vexPP,
@@ -306,7 +329,7 @@ public:
     MachineCodeTableEntry(bool rexW,
         int opcode,
         char opcodeLength,
-        bool operandSizeOverride,
+        OperandSizeOverwrite operandSizeOverride,
         bool vex,
         bool vexL,
         char vexPP,
@@ -345,7 +368,7 @@ public:
     MachineCodeTableEntry(bool rexW,
         int opcode,
         char opcodeLength,
-        bool operandSizeOverride,
+        OperandSizeOverwrite operandSizeOverride,
         bool vex,
         bool vexL,
         char vexPP,
@@ -379,7 +402,7 @@ public:
     MachineCodeTableEntry(bool rexW,
         int opcode,
         char opcodeLength,
-        bool operandSizeOverride,
+        OperandSizeOverwrite operandSizeOverride,
         bool vex,
         bool vexL,
         char vexPP,
@@ -425,7 +448,7 @@ public:
     MachineCodeTableEntry(bool rexW,
         int opcode,
         char opcodeLength,
-        bool operandSizeOverride,
+        OperandSizeOverwrite operandSizeOverride,
         bool vex,
         bool vexL,
         char vexPP,
@@ -466,7 +489,7 @@ public:
     MachineCodeTableEntry(bool rexW,
         int opcode,
         char opcodeLength,
-        bool operandSizeOverride,
+        OperandSizeOverwrite operandSizeOverride,
         bool vex,
         bool vexL,
         char vexPP,
@@ -519,7 +542,7 @@ public:
     MachineCodeTableEntry(bool rexW,
         int opcode,
         char opcodeLength,
-        bool operandSizeOverride,
+        OperandSizeOverwrite operandSizeOverride,
         bool vex,
         bool vexL,
         char vexPP,
@@ -567,7 +590,7 @@ public:
     MachineCodeTableEntry(bool rexW,
         int opcode,
         char opcodeLength,
-        bool operandSizeOverride,
+        OperandSizeOverwrite operandSizeOverride,
         bool vex,
         bool vexL,
         char vexPP,
@@ -714,96 +737,99 @@ public:
           entries(entries)
     {}
 
-    MachineCodeInstruction getInstruction(
+    virtual MachineCodeInstruction getInstruction(
         const std::vector<Framework::Assembly::OperationArgument*>& args,
         const Framework::Assembly::AssemblyBlock* codeBlock,
-        const Framework::Assembly::Instruction* current)
+        const Framework::Assembly::Instruction* current,
+        Framework::Text& err)
     {
         MachineCodeInstruction result;
         memset(&result, 0, sizeof(MachineCodeInstruction));
-        const MachineCodeTableEntry& entry = getEntry(args, codeBlock, current);
-        result.needsVex = entry.vex;
-        result.vexL = entry.vexL;
-        result.vexPP = entry.vexPP;
-        result.needsRex = entry.rexW;
-        result.exWE = entry.rexW;
-        result.modRM = entry.rmReg << 3;
-        if (entry.rmReg)
+        const MachineCodeTableEntry* entry
+            = getEntry(args, codeBlock, current, err);
+        if (!entry)
+        {
+            return result;
+        }
+        result.needsVex = entry->vex;
+        result.vexL = entry->vexL;
+        result.vexPP = entry->vexPP;
+        result.needsRex = entry->rexW;
+        result.exWE = entry->rexW;
+        result.modRM = entry->rmReg << 3;
+        if (entry->rmReg)
         {
             result.needsModRM = true;
         }
-        memcpy(result.opcode, entry.opcode, 3);
-        result.opcodeLength = entry.opcodeLength;
-        result.operandSizeOverride = entry.operandSizeOverride;
+        memcpy(result.opcode, entry->opcode, 3);
+        result.opcodeLength = entry->opcodeLength;
+        result.operandSizeOverride = entry->operandSizeOverride;
         for (int i = 0; i < args.size(); i++)
         {
             OperandEncoding encoding = UNDEFINED;
             switch (i)
             {
             case 0:
-                encoding = entry.op1Encoding;
+                encoding = entry->op1Encoding;
                 break;
             case 1:
-                encoding = entry.op2Encoding;
+                encoding = entry->op2Encoding;
                 break;
             case 2:
-                encoding = entry.op3Encoding;
+                encoding = entry->op3Encoding;
                 break;
             case 3:
-                encoding = entry.op4Encoding;
+                encoding = entry->op4Encoding;
                 break;
             }
             switch (encoding)
             {
             case MODRM_REG:
-                encodeModRM_REG(result, args[i], i + 1);
+                encodeModRM_REG(result, args[i], i + 1, err);
                 break;
             case MODRM_RM:
-                encodeModRM_RM(result, args[i], i + 1);
+                encodeModRM_RM(result, args[i], i + 1, err);
                 break;
             case VEX_VVVV:
-                encodeVex_VVVV(result, args[i], i + 1);
+                encodeVex_VVVV(result, args[i], i + 1, err);
                 break;
             case OPCODE_RD:
-                encodeOpcode_RD(result, args[i], i + 1);
+                encodeOpcode_RD(result, args[i], i + 1, err);
                 break;
             case IMM8:
-                encodeIMM8(result, args[i], i + 1);
+                encodeIMM8(result, args[i], i + 1, err);
                 break;
             case IMM16:
-                encodeIMM16(result, args[i], i + 1);
+                encodeIMM16(result, args[i], i + 1, err);
                 break;
             case IMM32:
-                encodeIMM32(result, args[i], i + 1);
+                encodeIMM32(result, args[i], i + 1, err);
                 break;
             case IMM64:
-                encodeIMM64(result, args[i], i + 1);
+                encodeIMM64(result, args[i], i + 1, err);
                 break;
             }
         }
         if (result.errIfNoRex && !result.needsRex)
         {
-            Framework::Text* err = new Framework::Text();
-            err->append() << "Instruction " << op
-                          << " has no REX prefix and can not address "
-                             "LOWER8 of registers RSP, RBP, RSI or RDI";
-            throw err->getText();
+            err.append() << "Instruction " << op
+                         << " has no REX prefix and can not address "
+                            "LOWER8 of registers RSP, RBP, RSI or RDI\n";
         }
         if (result.errIfRex && result.needsRex)
         {
-            Framework::Text* err = new Framework::Text();
-            err->append() << "Instruction " << op
-                          << " has a REX prefix and can not address "
-                             "HIGHER8 of registers RAX, RBX, RCX or RDX";
-            throw err->getText();
+            err.append() << "Instruction " << op
+                         << " has a REX prefix and can not address "
+                            "HIGHER8 of registers RAX, RBX, RCX or RDX\n";
         }
         return result;
     }
 
-    virtual MachineCodeTableEntry& getEntry(
+    MachineCodeTableEntry* getEntry(
         const std::vector<Framework::Assembly::OperationArgument*>& args,
         const Framework::Assembly::AssemblyBlock* codeBlock,
-        const Framework::Assembly::Instruction* current)
+        const Framework::Assembly::Instruction* current,
+        Framework::Text& err)
     {
         MachineCodeInstruction result;
         memset(&result, 0, sizeof(MachineCodeInstruction));
@@ -811,17 +837,16 @@ public:
         {
             if (entry.matches((int)args.size(), args))
             {
-                return entry;
+                return &entry;
             }
         }
-        Framework::Text err;
         err.append() << "operation " << (int)op
                      << " not found in translation table. args: \n";
         for (auto arg : args)
         {
             err.append() << "  " << typeid(*arg).name() << "\n";
         }
-        throw err.getText();
+        return 0;
     }
 
     Framework::Assembly::Operation getOperation() const
@@ -831,7 +856,8 @@ public:
 
     void encodeModRM_REG(MachineCodeInstruction& result,
         const Framework::Assembly::OperationArgument* arg,
-        int index) const
+        int index,
+        Framework::Text& err) const
     {
         result.needsModRM = true;
         const Framework::Assembly::GPRegisterArgument* gpRegArg
@@ -840,27 +866,26 @@ public:
             = arg->asFPRegisterArgument();
         if (gpRegArg)
         {
-            encodeModRM_REG_GP(result, gpRegArg, index);
+            encodeModRM_REG_GP(result, gpRegArg, index, err);
         }
         else if (fpRegArg)
         {
-            encodeModRM_REG_FP(result, fpRegArg, index);
+            encodeModRM_REG_FP(result, fpRegArg, index, err);
         }
         else
         {
-            Framework::Text* err = new Framework::Text();
-            err->append()
+            err.append()
                 << "Invalid argument type for operand " << index
                 << " for operation " << op << " encoded as MODRM_REG: found "
                 << typeid(*arg).name()
-                << " but expected GPRegisterArgument or FPRegisterArgument";
-            throw err->getText();
+                << " but expected GPRegisterArgument or FPRegisterArgument\n";
         }
     }
 
     void encodeModRM_REG_GP(MachineCodeInstruction& result,
         const Framework::Assembly::GPRegisterArgument* arg,
-        int index) const
+        int index,
+        Framework::Text& err) const
     {
         Framework::Assembly::GPRegister reg = arg->getRegister();
         if (reg >= Framework::Assembly::R8)
@@ -892,11 +917,10 @@ public:
             }
             else
             {
-                Framework::Text* err = new Framework::Text();
-                err->append() << "Invalid argument for operand " << index
-                              << " for operation " << op
-                              << " HIGHER8 can only be used for registers RAX, "
-                                 "RBX, RCX or RDX";
+                err.append() << "Invalid argument for operand " << index
+                             << " for operation " << op
+                             << " HIGHER8 can only be used for registers RAX, "
+                                "RBX, RCX or RDX\n";
             }
         }
         else
@@ -915,7 +939,8 @@ public:
 
     void encodeModRM_REG_FP(MachineCodeInstruction& result,
         const Framework::Assembly::FPRegisterArgument* arg,
-        int index) const
+        int index,
+        Framework::Text& err) const
     {
         Framework::Assembly::FPRegister reg = arg->getRegister();
         if (reg >= Framework::Assembly::MM8)
@@ -928,7 +953,8 @@ public:
 
     void encodeModRM_RM(MachineCodeInstruction& result,
         const Framework::Assembly::OperationArgument* arg,
-        int index) const
+        int index,
+        Framework::Text& err) const
     {
         result.needsModRM = true;
         const Framework::Assembly::GPRegisterArgument* gpRegArg
@@ -939,32 +965,31 @@ public:
             = arg->asMemoryAccessArgument();
         if (gpRegArg)
         {
-            encodeModRM_RM_GP(result, gpRegArg, index);
+            encodeModRM_RM_GP(result, gpRegArg, index, err);
         }
         else if (fpRegArg)
         {
-            encodeModRM_RM_FP(result, fpRegArg, index);
+            encodeModRM_RM_FP(result, fpRegArg, index, err);
         }
         else if (memArg)
         {
-            encodeModRM_RM_Mem(result, memArg, index);
+            encodeModRM_RM_Mem(result, memArg, index, err);
         }
         else
         {
-            Framework::Text* err = new Framework::Text();
-            err->append()
+            err.append()
                 << "Invalid argument type for operand " << index
                 << " for operation " << op << " encoded as MODRM_RM: found "
                 << typeid(*arg).name()
                 << " but expected GPRegisterArgument, FPRegisterArgument "
-                   "or MemoryAccessArgument";
-            throw err->getText();
+                   "or MemoryAccessArgument\n";
         }
     }
 
     void encodeModRM_RM_GP(MachineCodeInstruction& result,
         const Framework::Assembly::GPRegisterArgument* arg,
-        int index) const
+        int index,
+        Framework::Text& err) const
     {
         Framework::Assembly::GPRegister reg = arg->getRegister();
         if (reg >= Framework::Assembly::R8)
@@ -997,11 +1022,10 @@ public:
             }
             else
             {
-                Framework::Text* err = new Framework::Text();
-                err->append() << "Invalid argument for operand " << index
-                              << " for operation " << op
-                              << " HIGHER8 can only be used for registers RAX, "
-                                 "RBX, RCX or RDX";
+                err.append() << "Invalid argument for operand " << index
+                             << " for operation " << op
+                             << " HIGHER8 can only be used for registers RAX, "
+                                "RBX, RCX or RDX\n";
             }
         }
         else
@@ -1020,7 +1044,8 @@ public:
 
     void encodeModRM_RM_FP(MachineCodeInstruction& result,
         const Framework::Assembly::FPRegisterArgument* arg,
-        int index) const
+        int index,
+        Framework::Text& err) const
     {
         Framework::Assembly::FPRegister reg = arg->getRegister();
         if (reg >= Framework::Assembly::MM8)
@@ -1034,7 +1059,8 @@ public:
 
     void encodeModRM_RM_Mem(MachineCodeInstruction& result,
         const Framework::Assembly::MemoryAccessArgument* arg,
-        int index) const
+        int index,
+        Framework::Text& err) const
     {
         if (arg->isUsingAddressRegister() || arg->isUsingOffsetRegister())
         {
@@ -1045,7 +1071,7 @@ public:
             {
                 // SIB needed
                 result.sibNeeded = true;
-                result.modRM |= 0b100 << 3; // indicate SIB
+                result.modRM |= 0b100; // indicate SIB
                 if (reg >= Framework::Assembly::R8)
                 {
                     result.needsRex = true;
@@ -1056,11 +1082,9 @@ public:
                     = arg->getOffsetRegister();
                 if (offsetReg == Framework::Assembly::RSP)
                 {
-                    Framework::Text* err = new Framework::Text();
-                    err->append() << "Invalid argument for operand " << index
-                                  << " for operation " << op
-                                  << " RSP can not be used as index register";
-                    throw err->getText();
+                    err.append() << "Invalid argument for operand " << index
+                                 << " for operation " << op
+                                 << " RSP can not be used as index register\n";
                 }
                 if (offsetReg >= Framework::Assembly::R8)
                 {
@@ -1069,6 +1093,14 @@ public:
                 }
                 result.sib |= (offsetReg & 0b111) << 3; // index register
             }
+            else if (reg == 0b100)
+            {
+                // SIB needed
+                result.sibNeeded = true;
+                result.modRM |= 0b100; // indicate SIB
+                result.sib |= reg & 0b111;
+                result.sib |= 0b100 << 3; // no index register
+            }
             else
             {
                 if (reg >= Framework::Assembly::R8)
@@ -1079,7 +1111,7 @@ public:
                 result.modRM |= reg & 0b111;
             }
             int offset = arg->getOffset();
-            if (offset > 0)
+            if (offset)
             {
                 if (offset <= 127 && offset >= -128)
                 {
@@ -1119,29 +1151,29 @@ public:
 
     void encodeVex_VVVV(MachineCodeInstruction& result,
         const Framework::Assembly::OperationArgument* arg,
-        int index) const
+        int index,
+        Framework::Text& err) const
     {
         const Framework::Assembly::FPRegisterArgument* fpRegArg
             = arg->asFPRegisterArgument();
         if (fpRegArg)
         {
-            encodeVex_VVVV_FP(result, fpRegArg, index);
+            encodeVex_VVVV_FP(result, fpRegArg, index, err);
         }
         else
         {
-            Framework::Text* err = new Framework::Text();
-            err->append() << "Invalid argument type for operand " << index
-                          << " for operation " << op
-                          << " encoded as VEX_VVVV: found "
-                          << typeid(*arg).name()
-                          << " but expected FPRegisterArgument";
-            throw err->getText();
+            err.append() << "Invalid argument type for operand " << index
+                         << " for operation " << op
+                         << " encoded as VEX_VVVV: found "
+                         << typeid(*arg).name()
+                         << " but expected FPRegisterArgument\n";
         }
     }
 
     void encodeVex_VVVV_FP(MachineCodeInstruction& result,
         const Framework::Assembly::FPRegisterArgument* arg,
-        int index) const
+        int index,
+        Framework::Text& err) const
     {
         Framework::Assembly::FPRegister reg = arg->getRegister();
         result.vexVVVV = reg & 0b1111;
@@ -1150,29 +1182,29 @@ public:
 
     void encodeOpcode_RD(MachineCodeInstruction& result,
         const Framework::Assembly::OperationArgument* arg,
-        int index) const
+        int index,
+        Framework::Text& err) const
     {
         const Framework::Assembly::GPRegisterArgument* gpRegArg
             = arg->asGPRegisterArgument();
         if (gpRegArg)
         {
-            encodeOpcode_RD_GP(result, gpRegArg, index);
+            encodeOpcode_RD_GP(result, gpRegArg, index, err);
         }
         else
         {
-            Framework::Text* err = new Framework::Text();
-            err->append() << "Invalid argument type for operand " << index
-                          << " for operation " << op
-                          << " encoded as OPCODE_RD: found "
-                          << typeid(*arg).name()
-                          << " but expected GPRegisterArgument";
-            throw err->getText();
+            err.append() << "Invalid argument type for operand " << index
+                         << " for operation " << op
+                         << " encoded as OPCODE_RD: found "
+                         << typeid(*arg).name()
+                         << " but expected GPRegisterArgument\n";
         }
     }
 
     void encodeOpcode_RD_GP(MachineCodeInstruction& result,
         const Framework::Assembly::GPRegisterArgument* arg,
-        int index) const
+        int index,
+        Framework::Text& err) const
     {
         Framework::Assembly::GPRegister reg = arg->getRegister();
         if (reg >= Framework::Assembly::R8)
@@ -1185,37 +1217,35 @@ public:
 
     void encodeIMM8(MachineCodeInstruction& result,
         Framework::Assembly::OperationArgument* arg,
-        int index) const
+        int index,
+        Framework::Text& err) const
     {
         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();
+            err.append() << "Invalid argument type for operand " << index
+                         << " for operation " << op
+                         << " encoded as IMM8: imm bytes are already in use\n";
+            return;
         }
         const Framework::Assembly::ConstantArgument* constArg
             = arg->asConstantArgument();
         if (constArg == 0)
         {
-            Framework::Text* err = new Framework::Text();
-            err->append() << "Invalid argument type for operand " << index
-                          << " for operation " << op
-                          << " encoded as IMM8: found " << typeid(*arg).name()
-                          << " but expected ConstantArgument";
-            throw err->getText();
+            err.append() << "Invalid argument type for operand " << index
+                         << " for operation " << op
+                         << " encoded as IMM8: found " << typeid(*arg).name()
+                         << " but expected ConstantArgument\n";
+            return;
         }
         int value = (int)constArg->getValue();
         int len = (int)constArg->getSize();
         if (len > 1)
         {
-            Framework::Text* err = new Framework::Text();
-            err->append() << "Constant size too large for operand " << index
-                          << " for operation " << op
-                          << " encoded as IMM8: found size " << len
-                          << " but expected size BYTE";
-            throw err->getText();
+            err.append() << "Constant size too large for operand " << index
+                         << " for operation " << op
+                         << " encoded as IMM8: found size " << len
+                         << " but expected size BYTE\n";
+            return;
         }
         result.imm[(int)result.immLength] = (char)(value);
         result.immLength += 1;
@@ -1223,37 +1253,35 @@ public:
 
     void encodeIMM16(MachineCodeInstruction& result,
         Framework::Assembly::OperationArgument* arg,
-        int index) const
+        int index,
+        Framework::Text& err) const
     {
         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();
+            err.append() << "Invalid argument type for operand " << index
+                         << " for operation " << op
+                         << " encoded as IMM16: imm bytes are already in use\n";
+            return;
         }
         const Framework::Assembly::ConstantArgument* constArg
             = arg->asConstantArgument();
         if (constArg == 0)
         {
-            Framework::Text* err = new Framework::Text();
-            err->append() << "Invalid argument type for operand " << index
-                          << " for operation " << op
-                          << " encoded as IMM8: found " << typeid(*arg).name()
-                          << " but expected ConstantArgument";
-            throw err->getText();
+            err.append() << "Invalid argument type for operand " << index
+                         << " for operation " << op
+                         << " encoded as IMM16: found " << typeid(*arg).name()
+                         << " but expected ConstantArgument\n";
+            return;
         }
         int value = (int)constArg->getValue();
         int len = (int)constArg->getSize();
         if (len > 2)
         {
-            Framework::Text* err = new Framework::Text();
-            err->append() << "Constant size too large for operand " << index
-                          << " for operation " << op
-                          << " encoded as IMM8: found size " << len
-                          << " but expected size range [BYTE, WORD]";
-            throw err->getText();
+            err.append() << "Constant size too large for operand " << index
+                         << " for operation " << op
+                         << " encoded as IMM16: found size " << len
+                         << " but expected size range [BYTE, WORD]\n";
+            return;
         }
         short val = (short)(value);
         memcpy(result.imm + result.immLength, &val, 2);
@@ -1262,37 +1290,35 @@ public:
 
     void encodeIMM32(MachineCodeInstruction& result,
         Framework::Assembly::OperationArgument* arg,
-        int index) const
+        int index,
+        Framework::Text& err) const
     {
         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();
+            err.append() << "Invalid argument type for operand " << index
+                         << " for operation " << op
+                         << " encoded as IMM32: imm bytes are already in use\n";
+            return;
         }
         const Framework::Assembly::ConstantArgument* constArg
             = arg->asConstantArgument();
         if (constArg == 0)
         {
-            Framework::Text* err = new Framework::Text();
-            err->append() << "Invalid argument type for operand " << index
-                          << " for operation " << op
-                          << " encoded as IMM8: found " << typeid(*arg).name()
-                          << " but expected ConstantArgument";
-            throw err->getText();
+            err.append() << "Invalid argument type for operand " << index
+                         << " for operation " << op
+                         << " encoded as IMM32: found " << typeid(*arg).name()
+                         << " but expected ConstantArgument\n";
+            return;
         }
         int value = (int)constArg->getValue();
         int len = (int)constArg->getSize();
         if (len > 4)
         {
-            Framework::Text* err = new Framework::Text();
-            err->append() << "Constant size too large for operand " << index
-                          << " for operation " << op
-                          << " encoded as IMM8: found size " << len
-                          << " but expected size range [BYTE, DWORD]";
-            throw err->getText();
+            err.append() << "Constant size too large for operand " << index
+                         << " for operation " << op
+                         << " encoded as IMM32: found size " << len
+                         << " but expected size range [BYTE, DWORD]\n";
+            return;
         }
         memcpy(result.imm + result.immLength, &value, 4);
         result.immLength += 4;
@@ -1300,37 +1326,35 @@ public:
 
     void encodeIMM64(MachineCodeInstruction& result,
         Framework::Assembly::OperationArgument* arg,
-        int index) const
+        int index,
+        Framework::Text& err) const
     {
         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();
+            err.append() << "Invalid argument type for operand " << index
+                         << " for operation " << op
+                         << " encoded as IMM64: imm bytes are already in use\n";
+            return;
         }
         const Framework::Assembly::ConstantArgument* constArg
             = arg->asConstantArgument();
         if (constArg == 0)
         {
-            Framework::Text* err = new Framework::Text();
-            err->append() << "Invalid argument type for operand " << index
-                          << " for operation " << op
-                          << " encoded as IMM8: found " << typeid(*arg).name()
-                          << " but expected ConstantArgument";
-            throw err->getText();
+            err.append() << "Invalid argument type for operand " << index
+                         << " for operation " << op
+                         << " encoded as IMM64: found " << typeid(*arg).name()
+                         << " but expected ConstantArgument\n";
+            return;
         }
         __int64 value = constArg->getValue();
         int len = (int)constArg->getSize();
         if (len > 8)
         {
-            Framework::Text* err = new Framework::Text();
-            err->append() << "Constant size too large for operand " << index
-                          << " for operation " << op
-                          << " encoded as IMM8: found size " << len
-                          << " but expected size range [BYTE, QWORD]";
-            throw err->getText();
+            err.append() << "Constant size too large for operand " << index
+                         << " for operation " << op
+                         << " encoded as IMM64: found size " << len
+                         << " but expected size range [BYTE, QWORD]\n";
+            return;
         }
         memcpy(result.imm + result.immLength, &value, 8);
         result.immLength += 8;
@@ -1348,13 +1372,15 @@ public:
         char opCodeLength,
         std::initializer_list<MachineCodeTableEntry> entries)
         : OperationCodeTable(op, entries),
-          opCodeLength(opCodeLength)
+          opCodeLength(opCodeLength),
+          inGetEntry(0)
     {}
 
-    virtual MachineCodeTableEntry& getEntry(
+    virtual MachineCodeInstruction getInstruction(
         const std::vector<Framework::Assembly::OperationArgument*>& args,
         const Framework::Assembly::AssemblyBlock* codeBlock,
-        const Framework::Assembly::Instruction* current) override
+        const Framework::Assembly::Instruction* current,
+        Framework::Text& err) override
     {
         if (inGetEntry)
         {
@@ -1377,8 +1403,8 @@ public:
                     transformedArgs.push_back(arg);
                 }
             }
-            MachineCodeTableEntry& result = OperationCodeTable::getEntry(
-                transformedArgs, codeBlock, current);
+            MachineCodeInstruction result = OperationCodeTable::getInstruction(
+                transformedArgs, codeBlock, current, err);
             for (Framework::Assembly::OperationArgument* arg : newArgs)
             {
                 delete arg;
@@ -1408,10 +1434,6 @@ public:
                         {
                             break;
                         }
-                        else
-                        {
-                            backwords = true;
-                        }
                         continue;
                     }
                     if (instr->definesLabel(label))
@@ -1421,6 +1443,10 @@ public:
                         {
                             break;
                         }
+                        else
+                        {
+                            backwords = true;
+                        }
                         continue;
                     }
                     if (labelFound || currentFound)
@@ -1442,12 +1468,13 @@ public:
                 transformedArgs.push_back(arg);
             }
         }
-        MachineCodeTableEntry& result
-            = OperationCodeTable::getEntry(transformedArgs, codeBlock, current);
+        MachineCodeInstruction result = OperationCodeTable::getInstruction(
+            transformedArgs, codeBlock, current, err);
         for (Framework::Assembly::OperationArgument* arg : newArgs)
         {
             delete arg;
         }
+        inGetEntry = 0;
         return result;
     }
 };
@@ -1564,7 +1591,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x04,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -1580,7 +1607,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x05,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -1597,7 +1624,7 @@ void __intializeMachineCodeTranslationTable()
                         false,
                         0x05,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -1615,7 +1642,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x05,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -1631,7 +1658,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x80,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -1647,7 +1674,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x83,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -1663,7 +1690,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x83,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -1679,7 +1706,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x83,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -1696,7 +1723,7 @@ void __intializeMachineCodeTranslationTable()
                         false,
                         0x81,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -1718,7 +1745,7 @@ void __intializeMachineCodeTranslationTable()
                         false,
                         0x81,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -1740,7 +1767,7 @@ void __intializeMachineCodeTranslationTable()
                         true,
                         0x81,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -1761,7 +1788,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x00,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -1778,7 +1805,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x01,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -1795,7 +1822,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x01,
                         (char)1,
-                        true,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -1812,7 +1839,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x01,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -1829,7 +1856,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x02,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -1846,7 +1873,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x03,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -1863,7 +1890,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x03,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -1880,7 +1907,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x03,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -1899,7 +1926,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x580F,
                         (char)2,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -1916,7 +1943,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x580F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b01,
@@ -1937,7 +1964,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x580F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         true,
                         0b01,
@@ -1960,7 +1987,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x580F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -1977,7 +2004,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x580F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0,
@@ -1998,7 +2025,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x580F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         true,
                         0,
@@ -2019,9 +2046,9 @@ void __intializeMachineCodeTranslationTable()
             new OperationCodeTable(Framework::Assembly::ADDSD,
                 {// ADDSD xmm1, xmm2/m64
                     MachineCodeTableEntry(false,
-                        0x580FF2,
-                        (char)3,
-                        false,
+                        0x580F,
+                        (char)2,
+                        XF2,
                         false,
                         false,
                         0,
@@ -2039,7 +2066,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x580F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b11,
@@ -2061,9 +2088,9 @@ void __intializeMachineCodeTranslationTable()
             new OperationCodeTable(Framework::Assembly::ADDSS,
                 {// ADDPS xmm1, xmm2/m32
                     MachineCodeTableEntry(false,
-                        0x580FF3,
-                        (char)3,
-                        false,
+                        0x580F,
+                        (char)2,
+                        XF3,
                         false,
                         false,
                         0,
@@ -2082,7 +2109,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x580F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b10,
@@ -2107,7 +2134,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x2C,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2123,7 +2150,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x2D,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -2139,7 +2166,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x2D,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2155,7 +2182,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x2D,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2171,7 +2198,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x80,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2187,7 +2214,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x83,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -2203,7 +2230,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x83,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2219,7 +2246,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x83,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2235,7 +2262,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x81,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -2251,7 +2278,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x81,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2267,7 +2294,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x81,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2283,7 +2310,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x28,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2300,7 +2327,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x29,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -2317,7 +2344,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x29,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2334,7 +2361,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x29,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2351,7 +2378,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x2A,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2368,7 +2395,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x2B,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -2385,7 +2412,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x2B,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2402,7 +2429,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x2B,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2423,7 +2450,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x5D0F,
                         (char)2,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -2440,7 +2467,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x5C0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b01,
@@ -2461,7 +2488,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x5C0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         true,
                         0b01,
@@ -2486,7 +2513,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x5D0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2503,7 +2530,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x5C0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b00,
@@ -2524,7 +2551,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x5C0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         true,
                         0b00,
@@ -2547,9 +2574,9 @@ void __intializeMachineCodeTranslationTable()
                 {
                     // SUBSD xmm1, xmm2/m64
                     MachineCodeTableEntry(false,
-                        0x5C0FF2,
-                        (char)3,
-                        false,
+                        0x5C0F,
+                        (char)2,
+                        XF2,
                         false,
                         false,
                         0,
@@ -2567,7 +2594,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x5C0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b11,
@@ -2591,9 +2618,9 @@ void __intializeMachineCodeTranslationTable()
                 {
                     // SUBSS xmm1, xmm2/m32
                     MachineCodeTableEntry(false,
-                        0x5C0FF3,
-                        (char)3,
-                        false,
+                        0x5C0F,
+                        (char)2,
+                        XF3,
                         false,
                         false,
                         0,
@@ -2611,7 +2638,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x5C0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b10,
@@ -2637,7 +2664,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF6,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2654,7 +2681,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF7,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -2671,7 +2698,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2688,7 +2715,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0xF7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2709,7 +2736,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF6,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2726,7 +2753,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF7,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -2743,7 +2770,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2760,7 +2787,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0xF7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2777,7 +2804,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xAF0F,
                         (char)2,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -2794,7 +2821,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xAF0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2811,7 +2838,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0xAF0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2828,7 +2855,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x6B,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -2848,7 +2875,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x6B,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2868,7 +2895,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x6B,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2888,7 +2915,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x69,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -2908,7 +2935,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x69,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2928,7 +2955,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x69,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -2952,7 +2979,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x590F,
                         (char)2,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -2969,7 +2996,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x590F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b01,
@@ -2990,7 +3017,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x590F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         true,
                         0b01,
@@ -3015,7 +3042,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x590F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3032,7 +3059,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x590F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0,
@@ -3053,7 +3080,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x590F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         true,
                         0,
@@ -3076,9 +3103,9 @@ void __intializeMachineCodeTranslationTable()
                 {
                     // MULSD xmm1,xmm2/m64
                     MachineCodeTableEntry(false,
-                        0x590FF2,
-                        (char)3,
-                        false,
+                        0x590F,
+                        (char)2,
+                        XF2,
                         false,
                         false,
                         0,
@@ -3095,7 +3122,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x590F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b11,
@@ -3118,9 +3145,9 @@ void __intializeMachineCodeTranslationTable()
                 {
                     // MULSS xmm1,xmm2/m64
                     MachineCodeTableEntry(false,
-                        0x590FF3,
-                        (char)3,
-                        false,
+                        0x590F,
+                        (char)2,
+                        XF3,
                         false,
                         false,
                         0,
@@ -3137,7 +3164,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x590F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b10,
@@ -3162,7 +3189,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF6,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3179,7 +3206,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF7,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -3196,7 +3223,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3213,7 +3240,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0xF7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3234,7 +3261,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF6,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3251,7 +3278,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF7,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -3268,7 +3295,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3285,7 +3312,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0xF7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3306,7 +3333,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x5E0F,
                         (char)2,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -3323,7 +3350,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x5E0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b01,
@@ -3344,7 +3371,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x5E0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         true,
                         0b01,
@@ -3369,7 +3396,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x5E0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3386,7 +3413,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x5E0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0,
@@ -3407,7 +3434,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x5E0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         true,
                         0,
@@ -3430,9 +3457,9 @@ void __intializeMachineCodeTranslationTable()
                 {
                     // DIVSD xmm1, xmm2/m128
                     MachineCodeTableEntry(false,
-                        0x5E0FF2,
-                        (char)3,
-                        false,
+                        0x5E0F,
+                        (char)2,
+                        XF2,
                         false,
                         false,
                         0,
@@ -3449,7 +3476,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x5E0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b11,
@@ -3472,9 +3499,9 @@ void __intializeMachineCodeTranslationTable()
                 {
                     // DIVSS xmm1, xmm2/m128
                     MachineCodeTableEntry(false,
-                        0x5E0FF3,
-                        (char)3,
-                        false,
+                        0x5E0F,
+                        (char)2,
+                        XF3,
                         false,
                         false,
                         0,
@@ -3491,7 +3518,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x5E0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b10,
@@ -3516,7 +3543,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF6,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3529,7 +3556,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF7,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -3542,7 +3569,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3555,7 +3582,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0xF7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3572,7 +3599,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xFE,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3585,7 +3612,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF7,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -3598,7 +3625,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3611,7 +3638,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0xF7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3628,7 +3655,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x24,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3644,7 +3671,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x25,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -3660,7 +3687,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x25,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3676,7 +3703,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x25,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3692,7 +3719,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x80,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3708,7 +3735,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x83,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -3724,7 +3751,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x83,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3740,7 +3767,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x83,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3756,7 +3783,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x81,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -3772,7 +3799,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x81,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3788,7 +3815,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x81,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3804,7 +3831,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x20,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3821,7 +3848,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x21,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -3838,7 +3865,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x21,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3855,7 +3882,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x21,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3872,7 +3899,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x22,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3889,7 +3916,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x23,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -3906,7 +3933,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x23,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3923,7 +3950,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x23,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3944,7 +3971,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x0C,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3960,7 +3987,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x0D,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -3976,7 +4003,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x0D,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -3992,7 +4019,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x0D,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4008,7 +4035,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x80,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4024,7 +4051,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x83,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -4040,7 +4067,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x83,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4056,7 +4083,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x83,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4072,7 +4099,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x81,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -4088,7 +4115,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x81,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4104,7 +4131,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x81,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4120,7 +4147,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x08,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4137,7 +4164,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x09,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -4154,7 +4181,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x09,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4171,7 +4198,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x09,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4188,7 +4215,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x0A,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4205,7 +4232,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x0B,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -4222,7 +4249,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x0B,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4239,7 +4266,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x0B,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4260,7 +4287,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x34,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4276,7 +4303,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x35,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -4292,7 +4319,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x35,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4308,7 +4335,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x35,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4324,7 +4351,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x80,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4340,7 +4367,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x83,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -4356,7 +4383,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x83,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4372,7 +4399,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x83,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4388,7 +4415,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x81,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -4404,7 +4431,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x81,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4420,7 +4447,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x81,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4436,7 +4463,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x30,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4453,7 +4480,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x31,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -4470,7 +4497,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x31,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4487,7 +4514,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x31,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4504,7 +4531,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x32,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4521,7 +4548,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x33,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -4538,7 +4565,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x33,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4555,7 +4582,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x33,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4576,7 +4603,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF6,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4589,7 +4616,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF7,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -4602,7 +4629,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4615,7 +4642,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0xF7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4632,7 +4659,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xA8,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4648,7 +4675,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xA9,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -4664,7 +4691,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xA9,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4680,7 +4707,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0xA9,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4696,7 +4723,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF6,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4712,7 +4739,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF7,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -4728,7 +4755,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xF7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4744,7 +4771,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0xF7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4760,7 +4787,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x84,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4777,7 +4804,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x85,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -4794,7 +4821,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x85,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4811,7 +4838,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x85,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4832,7 +4859,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x3C,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4848,7 +4875,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x3D,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -4864,7 +4891,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x3D,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4880,7 +4907,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x3D,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4896,7 +4923,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x80,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4912,7 +4939,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x83,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -4928,7 +4955,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x83,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4944,7 +4971,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x83,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4960,7 +4987,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x81,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -4976,7 +5003,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x81,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -4992,7 +5019,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x81,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5008,7 +5035,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x38,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5025,7 +5052,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x39,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -5042,7 +5069,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x39,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5059,7 +5086,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x39,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5076,7 +5103,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x3A,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5093,7 +5120,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x3B,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -5110,7 +5137,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x3B,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5127,7 +5154,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x3B,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5148,7 +5175,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xC20F,
                         (char)2,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -5168,7 +5195,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xC20F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b01,
@@ -5192,7 +5219,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xC20F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         true,
                         0b01,
@@ -5220,7 +5247,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xC20F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5240,7 +5267,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xC20F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b00,
@@ -5264,7 +5291,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xC20F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         true,
                         0b00,
@@ -5290,9 +5317,9 @@ void __intializeMachineCodeTranslationTable()
                 {
                     // CMPSD xmm1, xmm2/m128, imm8
                     MachineCodeTableEntry(false,
-                        0xC20FF2,
-                        (char)3,
-                        false,
+                        0xC20F,
+                        (char)2,
+                        XF2,
                         false,
                         false,
                         0,
@@ -5312,7 +5339,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xC20F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b11,
@@ -5338,9 +5365,9 @@ void __intializeMachineCodeTranslationTable()
                 {
                     // CMPSS xmm1, xmm2/m128, imm8
                     MachineCodeTableEntry(false,
-                        0xC20FF3,
-                        (char)3,
-                        false,
+                        0xC20F,
+                        (char)2,
+                        XF3,
                         false,
                         false,
                         0,
@@ -5360,7 +5387,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xC20F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b10,
@@ -5381,13 +5408,53 @@ void __intializeMachineCodeTranslationTable()
                         IMM8,
                         READ),
                 }));
+        OperationCodeTable::machineCodeTranslationTable.add(
+            new OperationCodeTable(Framework::Assembly::COMISD,
+                {// COMISD xmm1, xmm2/m64
+                    MachineCodeTableEntry(false,
+                        0x2F0F,
+                        (char)2,
+                        X66,
+                        false,
+                        false,
+                        0,
+                        0,
+                        isFPRegister(
+                            Framework::Assembly::MemoryBlockSize::M128),
+                        MODRM_REG,
+                        READ,
+                        isFPRegisterOrMEmoryAccess(
+                            Framework::Assembly::MemoryBlockSize::M128,
+                            Framework::Assembly::MemoryBlockSize::QWORD),
+                        MODRM_RM,
+                        READ)}));
+        OperationCodeTable::machineCodeTranslationTable.add(
+            new OperationCodeTable(Framework::Assembly::COMISS,
+                {// COMISS xmm1, xmm2/m32
+                    MachineCodeTableEntry(false,
+                        0x2F0F,
+                        (char)2,
+                        NO_PREFIX,
+                        false,
+                        false,
+                        0,
+                        0,
+                        isFPRegister(
+                            Framework::Assembly::MemoryBlockSize::M128),
+                        MODRM_REG,
+                        READ,
+                        isFPRegisterOrMEmoryAccess(
+                            Framework::Assembly::MemoryBlockSize::M128,
+                            Framework::Assembly::MemoryBlockSize::DWORD),
+                        MODRM_RM,
+                        READ)}));
         OperationCodeTable::machineCodeTranslationTable.add(
             new OperationCodeTable(Framework::Assembly::MOV,
                 {// MOV r/m8, r8
                     MachineCodeTableEntry(false,
                         0x88,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5404,7 +5471,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x89,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -5421,7 +5488,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x89,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5438,7 +5505,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x89,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5455,7 +5522,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x8A,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5472,7 +5539,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x8B,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -5489,7 +5556,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x8B,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5506,7 +5573,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0x8B,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5523,7 +5590,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xB0,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5539,7 +5606,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xB8,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -5555,7 +5622,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xB8,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5571,7 +5638,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0xB8,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5587,7 +5654,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xC6,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5603,7 +5670,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xC7,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -5619,7 +5686,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xC7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5635,7 +5702,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(true,
                         0xC7,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5648,13 +5715,13 @@ void __intializeMachineCodeTranslationTable()
                         IMM32,
                         READ)}));
         OperationCodeTable::machineCodeTranslationTable.add(
-            new OperationCodeTable(Framework::Assembly::MOVAPD,
+            new OperationCodeTable(Framework::Assembly::MOVUPD,
                 {
-                    // MOVAPD xmm1, xmm2/m128
+                    // MOVUPD xmm1, xmm2/m128
                     MachineCodeTableEntry(false,
-                        0x280F,
+                        0x100F,
                         (char)2,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -5667,48 +5734,14 @@ void __intializeMachineCodeTranslationTable()
                             Framework::Assembly::MemoryBlockSize::M128),
                         MODRM_RM,
                         READ),
-                    // MOVAPD xmm2/m128, xmm1
+                    // MOVUPD xmm2/m128, xmm1
                     MachineCodeTableEntry(false,
-                        0x290F,
-                        (char)2,
-                        true,
-                        false,
-                        false,
-                        0,
-                        0,
-                        isFPRegisterOrMEmoryAccess(
-                            Framework::Assembly::MemoryBlockSize::M128),
-                        MODRM_RM,
-                        WRITE,
-                        isFPRegister(
-                            Framework::Assembly::MemoryBlockSize::M128),
-                        MODRM_REG,
-                        READ),
-                    // MOVAPD xmm1, xmm2/m128
-                    MachineCodeTableEntry(false,
-                        0x280F,
+                        0x110F,
                         (char)2,
+                        X66,
                         false,
-                        true,
                         false,
-                        0b01,
                         0,
-                        isFPRegister(
-                            Framework::Assembly::MemoryBlockSize::M128),
-                        MODRM_REG,
-                        WRITE,
-                        isFPRegisterOrMEmoryAccess(
-                            Framework::Assembly::MemoryBlockSize::M128),
-                        MODRM_RM,
-                        READ),
-                    // VMOVAPD xmm2/m128, xmm1
-                    MachineCodeTableEntry(false,
-                        0x290F,
-                        (char)2,
-                        false,
-                        true,
-                        false,
-                        0b01,
                         0,
                         isFPRegisterOrMEmoryAccess(
                             Framework::Assembly::MemoryBlockSize::M128),
@@ -5718,11 +5751,11 @@ void __intializeMachineCodeTranslationTable()
                             Framework::Assembly::MemoryBlockSize::M128),
                         MODRM_REG,
                         READ),
-                    // MOVAPD ymm1, ymm2/m256
+                    // VMOVUPD ymm1, ymm2/m256
                     MachineCodeTableEntry(false,
-                        0x280F,
+                        0x100F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         true,
                         0b01,
@@ -5735,11 +5768,11 @@ void __intializeMachineCodeTranslationTable()
                             Framework::Assembly::MemoryBlockSize::M256),
                         MODRM_RM,
                         READ),
-                    // VMOVAPD ymm2/m256, ymm1
+                    // VMOVUPD ymm2/m256, ymm1
                     MachineCodeTableEntry(false,
-                        0x290F,
+                        0x110F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         true,
                         0b01,
@@ -5754,13 +5787,13 @@ void __intializeMachineCodeTranslationTable()
                         READ),
                 }));
         OperationCodeTable::machineCodeTranslationTable.add(
-            new OperationCodeTable(Framework::Assembly::MOVAPS,
+            new OperationCodeTable(Framework::Assembly::MOVUPS,
                 {
-                    // MOVAPS xmm1, xmm2/m128
+                    // MOVUPS xmm1, xmm2/m128
                     MachineCodeTableEntry(false,
-                        0x280F,
+                        0x100F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -5773,48 +5806,14 @@ void __intializeMachineCodeTranslationTable()
                             Framework::Assembly::MemoryBlockSize::M128),
                         MODRM_RM,
                         READ),
-                    // MOVAPS xmm2/m128, xmm1
-                    MachineCodeTableEntry(false,
-                        0x290F,
-                        (char)2,
-                        false,
-                        false,
-                        false,
-                        0,
-                        0,
-                        isFPRegisterOrMEmoryAccess(
-                            Framework::Assembly::MemoryBlockSize::M128),
-                        MODRM_RM,
-                        WRITE,
-                        isFPRegister(
-                            Framework::Assembly::MemoryBlockSize::M128),
-                        MODRM_REG,
-                        READ),
-                    // VMOVAPS xmm1, xmm2/m128
+                    // MOVUPS xmm2/m128, xmm1
                     MachineCodeTableEntry(false,
-                        0x280F,
+                        0x110F,
                         (char)2,
+                        NO_PREFIX,
                         false,
-                        true,
                         false,
-                        0b00,
                         0,
-                        isFPRegister(
-                            Framework::Assembly::MemoryBlockSize::M128),
-                        MODRM_REG,
-                        WRITE,
-                        isFPRegisterOrMEmoryAccess(
-                            Framework::Assembly::MemoryBlockSize::M128),
-                        MODRM_RM,
-                        READ),
-                    // VMOVAPS xmm2/m128, xmm1
-                    MachineCodeTableEntry(false,
-                        0x290F,
-                        (char)2,
-                        false,
-                        true,
-                        false,
-                        0b00,
                         0,
                         isFPRegisterOrMEmoryAccess(
                             Framework::Assembly::MemoryBlockSize::M128),
@@ -5824,11 +5823,11 @@ void __intializeMachineCodeTranslationTable()
                             Framework::Assembly::MemoryBlockSize::M128),
                         MODRM_REG,
                         READ),
-                    // VMOVAPS ymm1, ymm2/m256
+                    // VMOVUPS ymm1, ymm2/m256
                     MachineCodeTableEntry(false,
-                        0x280F,
+                        0x100F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         true,
                         0b00,
@@ -5841,11 +5840,11 @@ void __intializeMachineCodeTranslationTable()
                             Framework::Assembly::MemoryBlockSize::M256),
                         MODRM_RM,
                         READ),
-                    // VMOVAPS ymm2/m256, ymm1
+                    // VMOVUPS ymm2/m256, ymm1
                     MachineCodeTableEntry(false,
-                        0x290F,
+                        0x110F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         true,
                         0b00,
@@ -5864,9 +5863,9 @@ void __intializeMachineCodeTranslationTable()
                 {
                     // MOVSD xmm1, xmm2/m64
                     MachineCodeTableEntry(false,
-                        0x100FF2,
-                        (char)3,
-                        false,
+                        0x100F,
+                        (char)2,
+                        XF2,
                         false,
                         false,
                         0,
@@ -5882,9 +5881,9 @@ void __intializeMachineCodeTranslationTable()
                         READ),
                     // MOVSD xmm2/m128, xmm1
                     MachineCodeTableEntry(false,
-                        0x110FF2,
-                        (char)3,
-                        false,
+                        0x110F,
+                        (char)2,
+                        XF2,
                         false,
                         false,
                         0,
@@ -5902,7 +5901,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x100F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b11,
@@ -5925,9 +5924,9 @@ void __intializeMachineCodeTranslationTable()
                 {
                     // MOVSS xmm1, xmm2/m32
                     MachineCodeTableEntry(false,
-                        0x100FF3,
-                        (char)3,
-                        false,
+                        0x100F,
+                        (char)2,
+                        XF3,
                         false,
                         false,
                         0,
@@ -5943,9 +5942,9 @@ void __intializeMachineCodeTranslationTable()
                         READ),
                     // MOVSS xmm2/m128, xmm1
                     MachineCodeTableEntry(false,
-                        0x110FF3,
-                        (char)3,
-                        false,
+                        0x110F,
+                        (char)2,
+                        XF3,
                         false,
                         false,
                         0,
@@ -5963,7 +5962,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x100F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         true,
                         false,
                         0b10,
@@ -5989,7 +5988,7 @@ void __intializeMachineCodeTranslationTable()
                         false,
                         0x8D,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -6008,7 +6007,7 @@ void __intializeMachineCodeTranslationTable()
                         false,
                         0x8D,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6027,7 +6026,7 @@ void __intializeMachineCodeTranslationTable()
                         true,
                         0x8D,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6043,95 +6042,331 @@ void __intializeMachineCodeTranslationTable()
                         READ),
                 }));
         OperationCodeTable::machineCodeTranslationTable.add(
-            new JumpOperationCodeTable(Framework::Assembly::JMP,
-                1,
-                {// JMP rel32
+            new OperationCodeTable(Framework::Assembly::CVTSI2SD,
+                {
+                    // CVTSI2SD xmm1, r32/m32
                     MachineCodeTableEntry(false,
-                        0xE9,
-                        (char)1,
-                        false,
+                        0x2A0F,
+                        (char)2,
+                        XF3,
                         false,
                         false,
                         0,
                         0,
-                        isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
-                        IMM32,
-                        READ)}));
-        OperationCodeTable::machineCodeTranslationTable.add(
-            new JumpOperationCodeTable(Framework::Assembly::JZ,
-                2,
-                {// JZ rel32
-                    MachineCodeTableEntry(false,
-                        0x840F,
+                        isFPRegister(
+                            Framework::Assembly::MemoryBlockSize::M128),
+                        MODRM_REG,
+                        WRITE,
+                        isGPRegisterOrMemoryAccess(
+                            Framework::Assembly::MemoryBlockSize::DWORD),
+                        MODRM_RM,
+                        READ),
+                    // CVTSI2SD xmm1, r64/m64
+                    MachineCodeTableEntry(true,
+                        0x2A0F,
                         (char)2,
-                        false,
+                        XF3,
                         false,
                         false,
                         0,
                         0,
-                        isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
-                        IMM32,
-                        READ)}));
+                        isFPRegister(
+                            Framework::Assembly::MemoryBlockSize::M128),
+                        MODRM_REG,
+                        WRITE,
+                        isGPRegisterOrMemoryAccess(
+                            Framework::Assembly::MemoryBlockSize::QWORD),
+                        MODRM_RM,
+                        READ),
+                }));
         OperationCodeTable::machineCodeTranslationTable.add(
-            new JumpOperationCodeTable(Framework::Assembly::JNZ,
-                2,
-                {// JNZ rel32
+            new OperationCodeTable(Framework::Assembly::CVTTSD2SI,
+                {
+                    // CVTTSD2SI r32, xmm1/m64
                     MachineCodeTableEntry(false,
-                        0x850F,
+                        0x2C0F,
                         (char)2,
-                        false,
+                        XF2,
                         false,
                         false,
                         0,
                         0,
-                        isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
-                        IMM32,
-                        READ)}));
-        OperationCodeTable::machineCodeTranslationTable.add(
-            new JumpOperationCodeTable(Framework::Assembly::JG,
-                2,
-                {// JG rel32
-                    MachineCodeTableEntry(false,
-                        0x8F0F,
+                        isGPRegister(
+                            Framework::Assembly::MemoryBlockSize::DWORD),
+                        MODRM_REG,
+                        WRITE,
+                        isFPRegisterOrMEmoryAccess(
+                            Framework::Assembly::MemoryBlockSize::M128,
+                            Framework::Assembly::MemoryBlockSize::QWORD),
+                        MODRM_RM,
+                        READ),
+                    // CVTTSD2SI r64, xmm1/m64
+                    MachineCodeTableEntry(true,
+                        0x2C0F,
                         (char)2,
-                        false,
+                        XF2,
                         false,
                         false,
                         0,
                         0,
-                        isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
-                        IMM32,
-                        READ)}));
+                        isGPRegister(
+                            Framework::Assembly::MemoryBlockSize::QWORD),
+                        MODRM_REG,
+                        WRITE,
+                        isFPRegisterOrMEmoryAccess(
+                            Framework::Assembly::MemoryBlockSize::M128,
+                            Framework::Assembly::MemoryBlockSize::QWORD),
+                        MODRM_RM,
+                        READ),
+                }));
         OperationCodeTable::machineCodeTranslationTable.add(
-            new JumpOperationCodeTable(Framework::Assembly::JGE,
-                2,
-                {// JGE rel32
+            new OperationCodeTable(Framework::Assembly::CVTTSS2SI,
+                {
+                    // CVTTSS2SI r32, xmm1/m32
                     MachineCodeTableEntry(false,
-                        0x8D0F,
+                        0x2C0F,
                         (char)2,
-                        false,
+                        XF3,
                         false,
                         false,
                         0,
                         0,
-                        isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
-                        IMM32,
-                        READ)}));
-        OperationCodeTable::machineCodeTranslationTable.add(
-            new JumpOperationCodeTable(Framework::Assembly::JL,
-                2,
-                {// JL rel32
-                    MachineCodeTableEntry(false,
-                        0x8C0F,
+                        isGPRegister(
+                            Framework::Assembly::MemoryBlockSize::DWORD),
+                        MODRM_REG,
+                        WRITE,
+                        isFPRegisterOrMEmoryAccess(
+                            Framework::Assembly::MemoryBlockSize::M128,
+                            Framework::Assembly::MemoryBlockSize::DWORD),
+                        MODRM_RM,
+                        READ),
+                    // CVTTSS2SI r64, xmm1/m32
+                    MachineCodeTableEntry(true,
+                        0x2C0F,
                         (char)2,
-                        false,
+                        XF3,
                         false,
                         false,
                         0,
                         0,
-                        isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
-                        IMM32,
-                        READ)}));
+                        isGPRegister(
+                            Framework::Assembly::MemoryBlockSize::QWORD),
+                        MODRM_REG,
+                        WRITE,
+                        isFPRegisterOrMEmoryAccess(
+                            Framework::Assembly::MemoryBlockSize::M128,
+                            Framework::Assembly::MemoryBlockSize::DWORD),
+                        MODRM_RM,
+                        READ),
+                }));
+        OperationCodeTable::machineCodeTranslationTable.add(
+            new OperationCodeTable(Framework::Assembly::CVTSD2SI,
+                {
+                    // CVTSD2SI r32, xmm1/m64
+                    MachineCodeTableEntry(false,
+                        0x2D0F,
+                        (char)2,
+                        XF2,
+                        false,
+                        false,
+                        0,
+                        0,
+                        isGPRegister(
+                            Framework::Assembly::MemoryBlockSize::DWORD),
+                        MODRM_REG,
+                        WRITE,
+                        isFPRegisterOrMEmoryAccess(
+                            Framework::Assembly::MemoryBlockSize::M128,
+                            Framework::Assembly::MemoryBlockSize::QWORD),
+                        MODRM_RM,
+                        READ),
+                    // CVTSD2SI r64, xmm1/m64
+                    MachineCodeTableEntry(true,
+                        0x2D0F,
+                        (char)2,
+                        XF2,
+                        false,
+                        false,
+                        0,
+                        0,
+                        isGPRegister(
+                            Framework::Assembly::MemoryBlockSize::QWORD),
+                        MODRM_REG,
+                        WRITE,
+                        isFPRegisterOrMEmoryAccess(
+                            Framework::Assembly::MemoryBlockSize::M128,
+                            Framework::Assembly::MemoryBlockSize::QWORD),
+                        MODRM_RM,
+                        READ),
+                }));
+        OperationCodeTable::machineCodeTranslationTable.add(
+            new OperationCodeTable(Framework::Assembly::CVTSS2SI,
+                {
+                    // CVTSS2SI r32, xmm1/m32
+                    MachineCodeTableEntry(false,
+                        0x2D0F,
+                        (char)2,
+                        XF3,
+                        false,
+                        false,
+                        0,
+                        0,
+                        isGPRegister(
+                            Framework::Assembly::MemoryBlockSize::DWORD),
+                        MODRM_REG,
+                        WRITE,
+                        isFPRegisterOrMEmoryAccess(
+                            Framework::Assembly::MemoryBlockSize::M128,
+                            Framework::Assembly::MemoryBlockSize::DWORD),
+                        MODRM_RM,
+                        READ),
+                    // CVTSS2SI r64, xmm1/m32
+                    MachineCodeTableEntry(true,
+                        0x2D0F,
+                        (char)2,
+                        XF3,
+                        false,
+                        false,
+                        0,
+                        0,
+                        isGPRegister(
+                            Framework::Assembly::MemoryBlockSize::QWORD),
+                        MODRM_REG,
+                        WRITE,
+                        isFPRegisterOrMEmoryAccess(
+                            Framework::Assembly::MemoryBlockSize::M128,
+                            Framework::Assembly::MemoryBlockSize::DWORD),
+                        MODRM_RM,
+                        READ),
+                }));
+        OperationCodeTable::machineCodeTranslationTable.add(
+            new OperationCodeTable(Framework::Assembly::CVTSI2SS,
+                {
+                    // CVTSI2SS xmm1, r32/m32
+                    MachineCodeTableEntry(false,
+                        0x2A0F,
+                        (char)2,
+                        XF2,
+                        false,
+                        false,
+                        0,
+                        0,
+                        isFPRegister(
+                            Framework::Assembly::MemoryBlockSize::M128),
+                        MODRM_REG,
+                        WRITE,
+                        isGPRegisterOrMemoryAccess(
+                            Framework::Assembly::MemoryBlockSize::DWORD),
+                        MODRM_RM,
+                        READ),
+                    // CVTSI2SS xmm1, r64/m64
+                    MachineCodeTableEntry(true,
+                        0x2A0F,
+                        (char)2,
+                        XF2,
+                        false,
+                        false,
+                        0,
+                        0,
+                        isFPRegister(
+                            Framework::Assembly::MemoryBlockSize::M128),
+                        MODRM_REG,
+                        WRITE,
+                        isGPRegisterOrMemoryAccess(
+                            Framework::Assembly::MemoryBlockSize::QWORD),
+                        MODRM_RM,
+                        READ),
+                }));
+        OperationCodeTable::machineCodeTranslationTable.add(
+            new JumpOperationCodeTable(Framework::Assembly::JMP,
+                1,
+                {// JMP rel32
+                    MachineCodeTableEntry(false,
+                        0xE9,
+                        (char)1,
+                        NO_PREFIX,
+                        false,
+                        false,
+                        0,
+                        0,
+                        isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
+                        IMM32,
+                        READ)}));
+        OperationCodeTable::machineCodeTranslationTable.add(
+            new JumpOperationCodeTable(Framework::Assembly::JZ,
+                2,
+                {// JZ rel32
+                    MachineCodeTableEntry(false,
+                        0x840F,
+                        (char)2,
+                        NO_PREFIX,
+                        false,
+                        false,
+                        0,
+                        0,
+                        isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
+                        IMM32,
+                        READ)}));
+        OperationCodeTable::machineCodeTranslationTable.add(
+            new JumpOperationCodeTable(Framework::Assembly::JNZ,
+                2,
+                {// JNZ rel32
+                    MachineCodeTableEntry(false,
+                        0x850F,
+                        (char)2,
+                        NO_PREFIX,
+                        false,
+                        false,
+                        0,
+                        0,
+                        isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
+                        IMM32,
+                        READ)}));
+        OperationCodeTable::machineCodeTranslationTable.add(
+            new JumpOperationCodeTable(Framework::Assembly::JG,
+                2,
+                {// JG rel32
+                    MachineCodeTableEntry(false,
+                        0x8F0F,
+                        (char)2,
+                        NO_PREFIX,
+                        false,
+                        false,
+                        0,
+                        0,
+                        isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
+                        IMM32,
+                        READ)}));
+        OperationCodeTable::machineCodeTranslationTable.add(
+            new JumpOperationCodeTable(Framework::Assembly::JGE,
+                2,
+                {// JGE rel32
+                    MachineCodeTableEntry(false,
+                        0x8D0F,
+                        (char)2,
+                        NO_PREFIX,
+                        false,
+                        false,
+                        0,
+                        0,
+                        isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
+                        IMM32,
+                        READ)}));
+        OperationCodeTable::machineCodeTranslationTable.add(
+            new JumpOperationCodeTable(Framework::Assembly::JL,
+                2,
+                {// JL rel32
+                    MachineCodeTableEntry(false,
+                        0x8C0F,
+                        (char)2,
+                        NO_PREFIX,
+                        false,
+                        false,
+                        0,
+                        0,
+                        isIMM(Framework::Assembly::MemoryBlockSize::DWORD),
+                        IMM32,
+                        READ)}));
         OperationCodeTable::machineCodeTranslationTable.add(
             new JumpOperationCodeTable(Framework::Assembly::JLE,
                 2,
@@ -6139,7 +6374,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x8E0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6154,7 +6389,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x870F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6169,7 +6404,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x820F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6184,7 +6419,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x830F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6199,7 +6434,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x860F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6214,7 +6449,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x800F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6229,7 +6464,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x810F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6244,7 +6479,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x8A0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6259,7 +6494,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x8B0F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6274,7 +6509,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x880F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6289,7 +6524,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x890F,
                         (char)2,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6303,7 +6538,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xE8,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6315,7 +6550,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xFF,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6324,33 +6559,11 @@ 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
                     MachineCodeTableEntry(
-                        false, 0xC3, (char)1, false, false, false, 0, 0)}));
+                        false, 0xC3, (char)1, NO_PREFIX, false, false, 0, 0)}));
         OperationCodeTable::machineCodeTranslationTable.add(
             new OperationCodeTable(Framework::Assembly::PUSH,
                 {
@@ -6358,7 +6571,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xFF,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -6371,7 +6584,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0xFF,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6384,7 +6597,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x6A,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6396,7 +6609,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x68,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -6408,7 +6621,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x68,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6424,7 +6637,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x8F,
                         (char)1,
-                        true,
+                        X66,
                         false,
                         false,
                         0,
@@ -6437,7 +6650,7 @@ void __intializeMachineCodeTranslationTable()
                     MachineCodeTableEntry(false,
                         0x8F,
                         (char)1,
-                        false,
+                        NO_PREFIX,
                         false,
                         false,
                         0,
@@ -6686,9 +6899,22 @@ const Framework::Text& Framework::Assembly::JumpTargetArgument::getLabel() const
 
 Framework::Assembly::Instruction::Instruction(
     Operation op, std::initializer_list<OperationArgument*> args)
+    : Instruction(op, args, {}, {}, {}, {})
+{}
+
+Framework::Assembly::Instruction::Instruction(Operation op,
+    std::initializer_list<OperationArgument*> params,
+    std::initializer_list<GPRegister> implicitReadGPs,
+    std::initializer_list<FPRegister> implicitReadFPs,
+    std::initializer_list<GPRegister> implicitWriteGPs,
+    std::initializer_list<FPRegister> implicitWriteFPs)
     : ReferenceCounter(),
       op(op),
-      args(args)
+      args(params),
+      implicitReadGPs(implicitReadGPs),
+      implicitReadFPs(implicitReadFPs),
+      implicitWriteGPs(implicitWriteGPs),
+      implicitWriteFPs(implicitWriteFPs)
 {}
 
 Framework::Assembly::Instruction::~Instruction()
@@ -6702,34 +6928,46 @@ Framework::Assembly::Instruction::~Instruction()
 bool Framework::Assembly::Instruction::writesToRegister(
     GPRegister reg, const AssemblyBlock* block) const
 {
+    for (GPRegister r : implicitWriteGPs)
+    {
+        if (r == reg)
+        {
+            return 0;
+        }
+    }
     __intializeMachineCodeTranslationTable();
     for (OperationCodeTable* tableEntry :
         OperationCodeTable::machineCodeTranslationTable)
     {
         if (tableEntry->getOperation() == op)
         {
-            MachineCodeTableEntry& entry
-                = tableEntry->getEntry(args, block, this);
-            for (GPRegister r : entry.getImpliedWriteGPRegs())
+            Framework::Text err;
+            MachineCodeTableEntry* entry
+                = tableEntry->getEntry(args, block, this, err);
+            if (entry)
             {
-                if (r == reg)
+                for (GPRegister r : entry->getImpliedWriteGPRegs())
                 {
-                    return 1;
+                    if (r == reg)
+                    {
+                        return 1;
+                    }
                 }
-            }
-            int index = 0;
-            for (const OperationArgument* arg : args)
-            {
-                OperandRW rw = entry.getOperandRW(index);
-                if (rw == WRITE || rw == READWRITE)
+                int index = 0;
+                for (const OperationArgument* arg : args)
                 {
-                    if (arg->asGPRegisterArgument()
-                        && arg->asGPRegisterArgument()->getRegister() == reg)
+                    OperandRW rw = entry->getOperandRW(index);
+                    if (rw == WRITE || rw == READWRITE)
                     {
-                        return 1;
+                        if (arg->asGPRegisterArgument()
+                            && arg->asGPRegisterArgument()->getRegister()
+                                   == reg)
+                        {
+                            return 1;
+                        }
                     }
+                    index++;
                 }
-                index++;
             }
         }
     }
@@ -6739,34 +6977,46 @@ bool Framework::Assembly::Instruction::writesToRegister(
 bool Framework::Assembly::Instruction::writesToRegister(
     FPRegister reg, const AssemblyBlock* block) const
 {
+    for (FPRegister r : implicitWriteFPs)
+    {
+        if (r == reg)
+        {
+            return 0;
+        }
+    }
     __intializeMachineCodeTranslationTable();
     for (OperationCodeTable* tableEntry :
         OperationCodeTable::machineCodeTranslationTable)
     {
         if (tableEntry->getOperation() == op)
         {
-            MachineCodeTableEntry& entry
-                = tableEntry->getEntry(args, block, this);
-            for (FPRegister r : entry.getImpliedWriteFPRegs())
+            Framework::Text err;
+            MachineCodeTableEntry* entry
+                = tableEntry->getEntry(args, block, this, err);
+            if (entry)
             {
-                if (r == reg)
+                for (FPRegister r : entry->getImpliedWriteFPRegs())
                 {
-                    return 1;
+                    if (r == reg)
+                    {
+                        return 1;
+                    }
                 }
-            }
-            int index = 0;
-            for (const OperationArgument* arg : args)
-            {
-                OperandRW rw = entry.getOperandRW(index);
-                if (rw == WRITE || rw == READWRITE)
+                int index = 0;
+                for (const OperationArgument* arg : args)
                 {
-                    if (arg->asFPRegisterArgument()
-                        && arg->asFPRegisterArgument()->getRegister() == reg)
+                    OperandRW rw = entry->getOperandRW(index);
+                    if (rw == WRITE || rw == READWRITE)
                     {
-                        return 1;
+                        if (arg->asFPRegisterArgument()
+                            && arg->asFPRegisterArgument()->getRegister()
+                                   == reg)
+                        {
+                            return 1;
+                        }
                     }
+                    index++;
                 }
-                index++;
             }
         }
     }
@@ -6776,39 +7026,51 @@ bool Framework::Assembly::Instruction::writesToRegister(
 bool Framework::Assembly::Instruction::readsFromRegister(
     GPRegister reg, const AssemblyBlock* block) const
 {
-    __intializeMachineCodeTranslationTable();
+    for (GPRegister r : implicitReadGPs)
+    {
+        if (r == reg)
+        {
+            return 0;
+        }
+    }
+    __intializeMachineCodeTranslationTable();
     for (OperationCodeTable* tableEntry :
         OperationCodeTable::machineCodeTranslationTable)
     {
         if (tableEntry->getOperation() == op)
         {
-            const MachineCodeTableEntry& entry
-                = tableEntry->getEntry(args, block, this);
-            for (GPRegister r : entry.getImpliedReadGPRegs())
+            Framework::Text err;
+            MachineCodeTableEntry* entry
+                = tableEntry->getEntry(args, block, this, err);
+            if (entry)
             {
-                if (r == reg)
+                for (GPRegister r : entry->getImpliedReadGPRegs())
                 {
-                    return 1;
-                }
-            }
-            int index = 0;
-            for (const OperationArgument* arg : args)
-            {
-                OperandRW rw = entry.getOperandRW(index);
-                if (rw == READ || rw == READWRITE)
-                {
-                    if (arg->asGPRegisterArgument()
-                        && arg->asGPRegisterArgument()->getRegister() == reg)
+                    if (r == reg)
                     {
                         return 1;
                     }
                 }
-                if (arg->asMemoryAccessArgument()
-                    && arg->asMemoryAccessArgument()->usesRegister(reg))
+                int index = 0;
+                for (const OperationArgument* arg : args)
                 {
-                    return 1;
+                    OperandRW rw = entry->getOperandRW(index);
+                    if (rw == READ || rw == READWRITE)
+                    {
+                        if (arg->asGPRegisterArgument()
+                            && arg->asGPRegisterArgument()->getRegister()
+                                   == reg)
+                        {
+                            return 1;
+                        }
+                    }
+                    if (arg->asMemoryAccessArgument()
+                        && arg->asMemoryAccessArgument()->usesRegister(reg))
+                    {
+                        return 1;
+                    }
+                    index++;
                 }
-                index++;
             }
         }
     }
@@ -6818,34 +7080,46 @@ bool Framework::Assembly::Instruction::readsFromRegister(
 bool Framework::Assembly::Instruction::readsFromRegister(
     FPRegister reg, const AssemblyBlock* block) const
 {
+    for (FPRegister r : implicitReadFPs)
+    {
+        if (r == reg)
+        {
+            return 0;
+        }
+    }
     __intializeMachineCodeTranslationTable();
     for (OperationCodeTable* tableEntry :
         OperationCodeTable::machineCodeTranslationTable)
     {
         if (tableEntry->getOperation() == op)
         {
-            MachineCodeTableEntry& entry
-                = tableEntry->getEntry(args, block, this);
-            for (FPRegister r : entry.getImpliedReadFPRegs())
+            Framework::Text err;
+            MachineCodeTableEntry* entry
+                = tableEntry->getEntry(args, block, this, err);
+            if (entry)
             {
-                if (r == reg)
+                for (FPRegister r : entry->getImpliedReadFPRegs())
                 {
-                    return 1;
+                    if (r == reg)
+                    {
+                        return 1;
+                    }
                 }
-            }
-            int index = 0;
-            for (const OperationArgument* arg : args)
-            {
-                OperandRW rw = entry.getOperandRW(index);
-                if (rw == READ || rw == READWRITE)
+                int index = 0;
+                for (const OperationArgument* arg : args)
                 {
-                    if (arg->asFPRegisterArgument()
-                        && arg->asFPRegisterArgument()->getRegister() == reg)
+                    OperandRW rw = entry->getOperandRW(index);
+                    if (rw == READ || rw == READWRITE)
                     {
-                        return 1;
+                        if (arg->asFPRegisterArgument()
+                            && arg->asFPRegisterArgument()->getRegister()
+                                   == reg)
+                        {
+                            return 1;
+                        }
                     }
+                    index++;
                 }
-                index++;
             }
         }
     }
@@ -6855,30 +7129,53 @@ bool Framework::Assembly::Instruction::readsFromRegister(
 bool Framework::Assembly::Instruction::isReplacementPossible(
     GPRegister oldReg, GPRegister newReg, const AssemblyBlock* block) const
 {
+    for (GPRegister r : implicitReadGPs)
+    {
+        if (r == oldReg)
+        {
+            return 0;
+        }
+    }
+    for (GPRegister r : implicitWriteGPs)
+    {
+        if (r == oldReg)
+        {
+            return 0;
+        }
+    }
     __intializeMachineCodeTranslationTable();
     for (OperationCodeTable* tableEntry :
         OperationCodeTable::machineCodeTranslationTable)
     {
         if (tableEntry->getOperation() == op)
         {
-            MachineCodeTableEntry& entry
-                = tableEntry->getEntry(args, block, this);
-            for (GPRegister r : entry.getImpliedReadGPRegs())
+            Framework::Text err;
+            MachineCodeTableEntry* entry
+                = tableEntry->getEntry(args, block, this, err);
+            if (entry)
             {
-                if (r == oldReg)
+                for (GPRegister r : entry->getImpliedReadGPRegs())
                 {
-                    return 0;
+                    if (r == oldReg)
+                    {
+                        return 0;
+                    }
                 }
-            }
-            for (GPRegister r : entry.getImpliedWriteGPRegs())
-            {
-                if (r == oldReg)
+                for (GPRegister r : entry->getImpliedWriteGPRegs())
                 {
-                    return 0;
+                    if (r == oldReg)
+                    {
+                        return 0;
+                    }
                 }
             }
         }
     }
+    if (this->readsFromRegister(newReg, block)
+        || this->writesToRegister(newReg, block))
+    {
+        return 0;
+    }
     if (newReg == RBP || newReg == RSI || newReg == RDI)
     {
         if (oldReg == RBP || oldReg == RSI || oldReg == RDI)
@@ -6900,30 +7197,53 @@ bool Framework::Assembly::Instruction::isReplacementPossible(
 bool Framework::Assembly::Instruction::isReplacementPossible(
     FPRegister oldReg, FPRegister newReg, const AssemblyBlock* block) const
 {
+    for (FPRegister r : implicitReadFPs)
+    {
+        if (r == oldReg)
+        {
+            return 0;
+        }
+    }
+    for (FPRegister r : implicitWriteFPs)
+    {
+        if (r == oldReg)
+        {
+            return 0;
+        }
+    }
     __intializeMachineCodeTranslationTable();
     for (OperationCodeTable* tableEntry :
         OperationCodeTable::machineCodeTranslationTable)
     {
         if (tableEntry->getOperation() == op)
         {
-            MachineCodeTableEntry& entry
-                = tableEntry->getEntry(args, block, this);
-            for (FPRegister r : entry.getImpliedReadFPRegs())
+            Framework::Text err;
+            MachineCodeTableEntry* entry
+                = tableEntry->getEntry(args, block, this, err);
+            if (entry)
             {
-                if (r == oldReg)
+                for (FPRegister r : entry->getImpliedReadFPRegs())
                 {
-                    return 0;
+                    if (r == oldReg)
+                    {
+                        return 0;
+                    }
                 }
-            }
-            for (FPRegister r : entry.getImpliedWriteFPRegs())
-            {
-                if (r == oldReg)
+                for (FPRegister r : entry->getImpliedWriteFPRegs())
                 {
-                    return 0;
+                    if (r == oldReg)
+                    {
+                        return 0;
+                    }
                 }
             }
         }
     }
+    if (this->readsFromRegister(newReg, block)
+        || this->writesToRegister(newReg, block))
+    {
+        return 0;
+    }
     return 1;
 }
 
@@ -6956,6 +7276,11 @@ void Framework::Assembly::Instruction::addJumpLabelPrefix(Text labelPrefix)
 void Framework::Assembly::Instruction::compile(
     StreamWriter* byteCodeWriter, const AssemblyBlock* block) const
 {
+    if (op == NOP)
+    {
+        return;
+    }
+    Framework::Text err;
     __intializeMachineCodeTranslationTable();
     for (OperationCodeTable* tableEntry :
         OperationCodeTable::machineCodeTranslationTable)
@@ -6963,19 +7288,38 @@ void Framework::Assembly::Instruction::compile(
         if (tableEntry->getOperation() == op)
         {
             MachineCodeInstruction instr
-                = tableEntry->getInstruction(args, block, this);
+                = tableEntry->getInstruction(args, block, this, err);
+            if (err.getLength())
+            {
+                throw err;
+            }
             instr.write(*byteCodeWriter);
             return;
         }
     }
-    Text err;
     err.append() << "Failed to compile instruction: operation code " << (int)op
                  << " not found in translation table. args: \n";
     for (auto arg : args)
     {
         err.append() << "  " << typeid(*arg).name() << "\n";
     }
-    throw err.getText();
+    throw err;
+}
+
+bool Framework::Assembly::Instruction::isValid(const AssemblyBlock* block) const
+{
+    __intializeMachineCodeTranslationTable();
+    for (OperationCodeTable* tableEntry :
+        OperationCodeTable::machineCodeTranslationTable)
+    {
+        if (tableEntry->getOperation() == op)
+        {
+            Framework::Text err;
+            tableEntry->getInstruction(args, block, this, err);
+            return err.getLength() == 0;
+        }
+    }
+    return false;
 }
 
 int Framework::Assembly::Instruction::compiledSize(
@@ -6987,8 +7331,13 @@ int Framework::Assembly::Instruction::compiledSize(
     {
         if (tableEntry->getOperation() == op)
         {
+            Framework::Text err;
             MachineCodeInstruction instr
-                = tableEntry->getInstruction(args, block, this);
+                = tableEntry->getInstruction(args, block, this, err);
+            if (err.getLength())
+            {
+                throw err;
+            }
             return instr.calculateSize();
         }
     }
@@ -7007,6 +7356,12 @@ bool Framework::Assembly::Instruction::definesLabel(Text label) const
         && args.at(0)->asJumpTargetArgument()->getLabel().istGleich(label);
 }
 
+const std::vector<Framework::Assembly::OperationArgument*>&
+Framework::Assembly::Instruction::getArguments() const
+{
+    return args;
+}
+
 Framework::Assembly::AssemblyBlock::AssemblyBlock()
     : inlineIndex(0),
       compiledCode(0)
@@ -7038,6 +7393,203 @@ void Framework::Assembly::AssemblyBlock::addJump(
         new Instruction(jumpOp, {new JumpTargetArgument(targetName)}));
 }
 
+void Framework::Assembly::AssemblyBlock::addAddition(
+    GPRegister target, GPRegister source, GPRegisterPart part)
+{
+    instructions.add(new Instruction(ADD,
+        {new GPRegisterArgument(target, part),
+            new GPRegisterArgument(source, part)}));
+}
+
+void Framework::Assembly::AssemblyBlock::addAddition(
+    FPRegister target, FPRegister source, FPDataType type, FPRegisterPart part)
+{
+    Operation op = NOP;
+    switch (type)
+    {
+    case SINGLE_FLOAT:
+        op = ADDSS;
+        break;
+    case SINGLE_DOUBLE:
+        op = ADDSD;
+        break;
+    case PACKED_FLOAT:
+        op = ADDPS;
+        break;
+    case PACKED_DOUBLE:
+        op = ADDPD;
+        break;
+    }
+    instructions.add(new Instruction(op,
+        {new FPRegisterArgument(target, part),
+            new FPRegisterArgument(source, part)}));
+}
+
+void Framework::Assembly::AssemblyBlock::addSubtraction(
+    GPRegister target, GPRegister source, GPRegisterPart part)
+{
+    instructions.add(new Instruction(SUB,
+        {new GPRegisterArgument(target, part),
+            new GPRegisterArgument(source, part)}));
+}
+
+void Framework::Assembly::AssemblyBlock::addSubtraction(
+    FPRegister target, FPRegister source, FPDataType type, FPRegisterPart part)
+{
+    Operation op = NOP;
+    switch (type)
+    {
+    case SINGLE_FLOAT:
+        op = SUBSS;
+        break;
+    case SINGLE_DOUBLE:
+        op = SUBSD;
+        break;
+    case PACKED_FLOAT:
+        op = SUBPS;
+        break;
+    case PACKED_DOUBLE:
+        op = SUBPD;
+        break;
+    }
+    instructions.add(new Instruction(op,
+        {new FPRegisterArgument(target, part),
+            new FPRegisterArgument(source, part)}));
+}
+
+void Framework::Assembly::AssemblyBlock::addMultiplication(
+    GPRegister target, GPRegister source, GPRegisterPart part)
+{
+    instructions.add(new Instruction(IMUL,
+        {new GPRegisterArgument(target, part),
+            new GPRegisterArgument(source, part)}));
+}
+
+void Framework::Assembly::AssemblyBlock::addMultiplication(
+    FPRegister target, FPRegister source, FPDataType type, FPRegisterPart part)
+{
+    Operation op = NOP;
+    switch (type)
+    {
+    case SINGLE_FLOAT:
+        op = MULSS;
+        break;
+    case SINGLE_DOUBLE:
+        op = MULSD;
+        break;
+    case PACKED_FLOAT:
+        op = MULPS;
+        break;
+    case PACKED_DOUBLE:
+        op = MULPD;
+        break;
+    }
+    instructions.add(new Instruction(op,
+        {new FPRegisterArgument(target, part),
+            new FPRegisterArgument(source, part)}));
+}
+
+void Framework::Assembly::AssemblyBlock::addDivision(
+    GPRegister target, GPRegister source, GPRegisterPart part)
+{
+    instructions.add(new Instruction(DIV,
+        {new GPRegisterArgument(target, part),
+            new GPRegisterArgument(source, part)}));
+}
+
+void Framework::Assembly::AssemblyBlock::addDivision(
+    FPRegister target, FPRegister source, FPDataType type, FPRegisterPart part)
+{
+    Operation op = NOP;
+    switch (type)
+    {
+    case SINGLE_FLOAT:
+        op = DIVSS;
+        break;
+    case SINGLE_DOUBLE:
+        op = DIVSD;
+        break;
+    case PACKED_FLOAT:
+        op = DIVPS;
+        break;
+    case PACKED_DOUBLE:
+        op = DIVPD;
+        break;
+    }
+    instructions.add(new Instruction(op,
+        {new FPRegisterArgument(target, part),
+            new FPRegisterArgument(source, part)}));
+}
+
+void Framework::Assembly::AssemblyBlock::addTest(
+    GPRegister r1, GPRegister r2, GPRegisterPart part)
+{
+    instructions.add(new Instruction(TEST,
+        {new GPRegisterArgument(r1, part), new GPRegisterArgument(r2, part)}));
+}
+
+void Framework::Assembly::AssemblyBlock::addCompare(
+    GPRegister r1, GPRegister r2, GPRegisterPart part)
+{
+    instructions.add(new Instruction(CMP,
+        {new GPRegisterArgument(r1, part), new GPRegisterArgument(r2, part)}));
+}
+
+void Framework::Assembly::AssemblyBlock::addCompare(GPRegister r1, char value)
+{
+    instructions.add(new Instruction(CMP,
+        {new GPRegisterArgument(r1, LOWER8), new ConstantArgument(value)}));
+}
+
+void Framework::Assembly::AssemblyBlock::addCompare(GPRegister r1, short value)
+{
+    instructions.add(new Instruction(CMP,
+        {new GPRegisterArgument(r1, LOWER16), new ConstantArgument(value)}));
+}
+
+void Framework::Assembly::AssemblyBlock::addCompare(GPRegister r1, int value)
+{
+    instructions.add(new Instruction(CMP,
+        {new GPRegisterArgument(r1, LOWER32), new ConstantArgument(value)}));
+}
+
+void Framework::Assembly::AssemblyBlock::addCompare(
+    FPRegister r1, FPRegister r2, FPDataType type)
+{
+    Operation op = NOP;
+    switch (type)
+    {
+    case SINGLE_FLOAT:
+        op = COMISS;
+        break;
+    case SINGLE_DOUBLE:
+        op = COMISD;
+        break;
+    }
+    if (op != NOP)
+    {
+        instructions.add(new Instruction(op,
+            {new FPRegisterArgument(r1, FPRegisterPart::X),
+                new FPRegisterArgument(r2, FPRegisterPart::X)}));
+    }
+}
+
+void Framework::Assembly::AssemblyBlock::addAnd(
+    GPRegister target, GPRegister source, GPRegisterPart part)
+{
+    instructions.add(new Instruction(AND,
+        {new GPRegisterArgument(target, part),
+            new GPRegisterArgument(source, part)}));
+}
+
+void Framework::Assembly::AssemblyBlock::addOr(
+    GPRegister target, GPRegister source, GPRegisterPart part)
+{
+    instructions.add(new Instruction(OR,
+        {new GPRegisterArgument(target, part),
+            new GPRegisterArgument(source, part)}));
+}
+
 void Framework::Assembly::AssemblyBlock::addLoadValue(
     char* valueAddress, GPRegister target)
 {
@@ -7082,6 +7634,27 @@ void Framework::Assembly::AssemblyBlock::addLoadValue(
             new MemoryAccessArgument(MemoryBlockSize::QWORD, target)}));
 }
 
+void Framework::Assembly::AssemblyBlock::addLoadValue(
+    GPRegister addressRegister,
+    GPRegister target,
+    GPRegisterPart targetPart,
+    int offset)
+{
+    instructions.add(new Instruction(MOV,
+        {new GPRegisterArgument(target, targetPart),
+            new MemoryAccessArgument(
+                (targetPart == LOWER8 || targetPart == HIGHER8)
+                    ? MemoryBlockSize::BYTE
+                    : (targetPart == LOWER16
+                              ? MemoryBlockSize::WORD
+                              : (targetPart == LOWER32
+                                        ? MemoryBlockSize::DWORD
+                                        : MemoryBlockSize::QWORD)),
+                addressRegister,
+                true,
+                offset)}));
+}
+
 void Framework::Assembly::AssemblyBlock::addLoadValue(
     float* valueAddress, FPRegister target, GPRegister temp)
 {
@@ -7139,12 +7712,11 @@ void Framework::Assembly::AssemblyBlock::addMoveValue(
 {
     int data = *reinterpret_cast<int*>(&value);
     addMoveValue(temp, data);
-    addPush(temp, LOWER32);
+    addPush(temp);
     instructions.add(new Instruction(MOVSS,
         {new FPRegisterArgument(target, X),
-            new MemoryAccessArgument(
-                MemoryBlockSize::DWORD, RSP, true, -4, true)}));
-    addPop(temp, LOWER32);
+            new MemoryAccessArgument(MemoryBlockSize::DWORD, RSP)}));
+    addPop(temp);
 }
 
 void Framework::Assembly::AssemblyBlock::addMoveValue(
@@ -7155,8 +7727,7 @@ void Framework::Assembly::AssemblyBlock::addMoveValue(
     addPush(temp);
     instructions.add(new Instruction(MOVSD,
         {new FPRegisterArgument(target, X),
-            new MemoryAccessArgument(
-                MemoryBlockSize::QWORD, RSP, true, -8, true)}));
+            new MemoryAccessArgument(MemoryBlockSize::QWORD, RSP)}));
     addPop(temp);
 }
 
@@ -7181,10 +7752,10 @@ void Framework::Assembly::AssemblyBlock::addMoveValue(
         op = MOVSD;
         break;
     case PACKED_FLOAT:
-        op = MOVAPS;
+        op = MOVUPS;
         break;
     case PACKED_DOUBLE:
-        op = MOVAPD;
+        op = MOVUPD;
         break;
     }
     instructions.add(new Instruction(op,
@@ -7192,27 +7763,97 @@ void Framework::Assembly::AssemblyBlock::addMoveValue(
             new FPRegisterArgument(source, part)}));
 }
 
-void Framework::Assembly::AssemblyBlock::addCall(
-    void* functionAddress, GPRegister temp)
+void Framework::Assembly::AssemblyBlock::addConversion(GPRegister target,
+    FPRegister source,
+    FPDataType type,
+    GPRegisterPart targetPart,
+    bool round)
 {
-    instructions.add(new Instruction(MOV,
-        {new GPRegisterArgument(temp),
-            new ConstantArgument(reinterpret_cast<__int64>(functionAddress))}));
-    instructions.add(new Instruction(CALL, {new GPRegisterArgument(temp)}));
+    Operation op = NOP;
+    if (type == SINGLE_DOUBLE)
+    {
+        op = round ? CVTSD2SI : CVTTSD2SI;
+    }
+    else if (type == SINGLE_FLOAT)
+    {
+        op = round ? CVTSS2SI : CVTTSS2SI;
+    }
+    instructions.add(new Instruction(op,
+        {new GPRegisterArgument(target, targetPart),
+            new FPRegisterArgument(source, X)}));
 }
 
-void Framework::Assembly::AssemblyBlock::addEnter(
-    short stackSize, char nestingLevel)
+void Framework::Assembly::AssemblyBlock::addConversion(FPRegister target,
+    GPRegister source,
+    FPDataType targetType,
+    GPRegisterPart sourcePart)
 {
-    instructions.add(
-        new Framework::Assembly::Instruction(Framework::Assembly::ENTER,
-            {new Framework::Assembly::ConstantArgument(stackSize),
-                new Framework::Assembly::ConstantArgument(nestingLevel)}));
+    Operation op = NOP;
+    if (targetType == SINGLE_DOUBLE)
+    {
+        op = CVTSI2SD;
+    }
+    else if (targetType == SINGLE_FLOAT)
+    {
+        op = CVTSI2SS;
+    }
+    instructions.add(new Instruction(op,
+        {new FPRegisterArgument(target, X),
+            new GPRegisterArgument(source, sourcePart)}));
 }
 
-void Framework::Assembly::AssemblyBlock::addLeave()
+void Framework::Assembly::AssemblyBlock::addCall(void* functionAddress,
+    FuncReturnType returnType,
+    std::initializer_list<GPRegister> gpParams,
+    std::initializer_list<FPRegister> fpParams,
+    GPRegister temp,
+    GPRegister bpTemp)
 {
-    instructions.add(new Instruction(LEAVE, {}));
+    if (isVolatile(bpTemp) || bpTemp == RSP)
+    {
+        throw "Temporary register for base pointer must be a non-volatile "
+              "register (not RAX, RCX, RDX, R8, R9, R10, R11) and not RSP";
+    }
+    // enshure calling conventions
+    // save stack pointer value to bpTemp
+    addMoveValue(bpTemp, RSP);
+    // align stack pointer to 16 bytes
+    instructions.add(new Instruction(
+        AND, {new GPRegisterArgument(RSP), new ConstantArgument(-16)}));
+    // allocate shadow space
+    instructions.add(new Instruction(
+        SUB, {new GPRegisterArgument(RSP), new ConstantArgument(32)}));
+
+    // load function address into temp register
+    instructions.add(new Instruction(MOV,
+        {new GPRegisterArgument(temp),
+            new ConstantArgument(reinterpret_cast<__int64>(functionAddress))}));
+    // call the function
+    if (returnType == INT_VALUE)
+    {
+        instructions.add(new Instruction(CALL,
+            {new GPRegisterArgument(temp)},
+            gpParams,
+            fpParams,
+            {RAX},
+            {}));
+    }
+    else if (returnType == FLOAT_VALUE)
+    {
+        instructions.add(new Instruction(CALL,
+            {new GPRegisterArgument(temp)},
+            gpParams,
+            fpParams,
+            {},
+            {MM0}));
+    }
+    else
+    {
+        instructions.add(new Instruction(
+            CALL, {new GPRegisterArgument(temp)}, gpParams, fpParams, {}, {}));
+    }
+    // restore stack pointer
+    addMoveValue(RSP, bpTemp);
 }
 
 void Framework::Assembly::AssemblyBlock::addReturn()
@@ -7223,47 +7864,134 @@ void Framework::Assembly::AssemblyBlock::addReturn()
 void Framework::Assembly::AssemblyBlock::addPush(
     GPRegister reg, GPRegisterPart part)
 {
+    GPRegisterPart pushPart = part;
+    if (part == LOWER8 || part == HIGHER8)
+    {
+        pushPart = LOWER16;
+    }
+    if (part == LOWER32)
+    {
+        pushPart = FULL64;
+    }
     instructions.add(
-        new Instruction(PUSH, {new GPRegisterArgument(reg, part)}));
+        new Instruction(PUSH, {new GPRegisterArgument(reg, pushPart)}));
 }
 
 void Framework::Assembly::AssemblyBlock::addPop(
     GPRegister reg, GPRegisterPart part)
 {
-    instructions.add(new Instruction(POP, {new GPRegisterArgument(reg, part)}));
+    GPRegisterPart popPart = part;
+    if (part == LOWER8 || part == HIGHER8)
+    {
+        popPart = LOWER16;
+    }
+    if (part == LOWER32)
+    {
+        popPart = FULL64;
+    }
+    instructions.add(
+        new Instruction(POP, {new GPRegisterArgument(reg, popPart)}));
 }
 
 void Framework::Assembly::AssemblyBlock::addPush(
-    FPRegister reg, FPRegisterPart part)
+    FPRegister reg, FPDataType type, FPRegisterPart part)
 {
-    instructions.add(new Instruction(SUB,
-        {new GPRegisterArgument(RSP),
-            new ConstantArgument(part == X ? 16 : 32)}));
-    instructions.add(new Instruction(MOVAPD,
-        {new MemoryAccessArgument(
-             part == X ? MemoryBlockSize::M128 : MemoryBlockSize::M256, RSP),
+    MemoryBlockSize size;
+    int bytes;
+    Operation moveOp;
+    switch (type)
+    {
+    case SINGLE_DOUBLE:
+        moveOp = MOVSD;
+        bytes = 8;
+        size = MemoryBlockSize::QWORD;
+        part = X;
+        break;
+    case SINGLE_FLOAT:
+        moveOp = MOVSS;
+        bytes = 4;
+        size = MemoryBlockSize::DWORD;
+        part = X;
+        break;
+    case PACKED_DOUBLE:
+        moveOp = MOVUPD;
+        bytes = part == X ? 16 : 32;
+        size = part == X ? MemoryBlockSize::M128 : MemoryBlockSize::M256;
+    case PACKED_FLOAT:
+        moveOp = MOVUPS;
+        bytes = part == X ? 16 : 32;
+        size = part == X ? MemoryBlockSize::M128 : MemoryBlockSize::M256;
+    }
+    instructions.add(new Instruction(
+        SUB, {new GPRegisterArgument(RSP), new ConstantArgument(bytes)}));
+    instructions.add(new Instruction(moveOp,
+        {new MemoryAccessArgument(size, RSP),
             new FPRegisterArgument(reg, part)}));
 }
 
 void Framework::Assembly::AssemblyBlock::addPop(
-    FPRegister reg, FPRegisterPart part)
+    FPRegister reg, FPDataType type, FPRegisterPart part)
 {
-    instructions.add(new Instruction(MOVAPD,
+    addPop(instructions, reg, type, part);
+}
+
+void Framework::Assembly::AssemblyBlock::addPop(
+    RCArray<Instruction>& instructionList,
+    FPRegister reg,
+    FPDataType type,
+    FPRegisterPart part)
+{
+    MemoryBlockSize size;
+    int bytes;
+    Operation moveOp;
+    switch (type)
+    {
+    case SINGLE_DOUBLE:
+        moveOp = MOVSD;
+        bytes = 8;
+        size = MemoryBlockSize::QWORD;
+        part = X;
+        break;
+    case SINGLE_FLOAT:
+        moveOp = MOVSS;
+        bytes = 4;
+        size = MemoryBlockSize::DWORD;
+        part = X;
+        break;
+    case PACKED_DOUBLE:
+        moveOp = MOVUPD;
+        bytes = part == X ? 16 : 32;
+        size = part == X ? MemoryBlockSize::M128 : MemoryBlockSize::M256;
+    case PACKED_FLOAT:
+        moveOp = MOVUPS;
+        bytes = part == X ? 16 : 32;
+        size = part == X ? MemoryBlockSize::M128 : MemoryBlockSize::M256;
+    }
+    instructionList.add(new Instruction(moveOp,
         {new FPRegisterArgument(reg, part),
-            new MemoryAccessArgument(
-                part == X ? MemoryBlockSize::M128 : MemoryBlockSize::M256,
-                RSP)}));
-    instructions.add(new Instruction(ADD,
-        {new GPRegisterArgument(RSP),
-            new ConstantArgument(part == X ? 16 : 32)}));
+            new MemoryAccessArgument(size, RSP)}));
+    instructionList.add(new Instruction(
+        ADD, {new GPRegisterArgument(RSP), new ConstantArgument(bytes)}));
 }
 
 void Framework::Assembly::AssemblyBlock::addBlock(AssemblyBlock* block,
     std::initializer_list<GPRegister> preservedGPRegisters,
     std::initializer_list<FPRegister> preservedFPRegisters,
+    std::initializer_list<FPDataType> preservedFPDataTypes,
     GPRegister* blockResultGpReg,
     FPRegister* blockResultFpReg)
 {
+    std::vector<FPDataType> fpTypes(preservedFPDataTypes);
+    bool containsCall = false;
+    for (const auto& instr : block->instructions)
+    {
+        if (instr->getOperation() == CALL)
+        {
+            containsCall = true; // volatile registers that should be preserved
+                                 // needs to be pushed to the stack
+            break;
+        }
+    }
     RCArray<Instruction> tempInstructions;
     for (GPRegister preservedReg : preservedGPRegisters)
     {
@@ -7272,35 +8000,43 @@ void Framework::Assembly::AssemblyBlock::addBlock(AssemblyBlock* block,
             bool replaced = false;
             for (int i = 0; i < 16; i++)
             {
-                if (i == 4)
+                if (i == 4 || i == 5 || preservedReg == RSP
+                    || preservedReg == RBP)
                 {
-                    continue; // Skip RSP (stack counter register)
+                    continue; // Skip RSP and RBP (stack counter register)
                 }
-                bool found = false;
-                for (GPRegister r : preservedGPRegisters)
-                {
-                    if (r == (GPRegister)i)
+                if (!containsCall
+                    || (isVolatile(preservedReg)
+                        == isVolatile((Framework::Assembly::GPRegister)i)))
+                { // call inside the block -> only replace volatile with
+                  // volatile and non volatile with non volatile registers
+                    bool found = false;
+                    for (GPRegister r : preservedGPRegisters)
                     {
-                        found = true;
-                        break;
+                        if (r == (GPRegister)i)
+                        {
+                            found = true;
+                            break;
+                        }
                     }
-                }
-                if (found)
-                {
-                    continue;
-                }
-                GPRegister newReg = (GPRegister)i;
-                if (!block->writesToRegister(newReg)
-                    && !block->readsFromRegister(newReg)
-                    && block->isReplacementPossible(preservedReg, newReg))
-                {
-                    if (preservedReg == RAX)
+                    if (found)
+                    {
+                        continue;
+                    }
+                    GPRegister newReg = (GPRegister)i;
+                    if (block->isReplacementPossible(preservedReg, newReg))
                     {
-                        *blockResultGpReg = newReg;
+                        if (blockResultGpReg)
+                        {
+                            if (preservedReg == *blockResultGpReg)
+                            {
+                                *blockResultGpReg = newReg;
+                            }
+                        }
+                        replaced = true;
+                        block->replaceRegister(preservedReg, newReg);
+                        break;
                     }
-                    replaced = true;
-                    block->replaceRegister(preservedReg, newReg);
-                    break;
                 }
             }
             if (!replaced)
@@ -7313,6 +8049,7 @@ void Framework::Assembly::AssemblyBlock::addBlock(AssemblyBlock* block,
             }
         }
     }
+    int index = 0;
     for (FPRegister preservedReg : preservedFPRegisters)
     {
         if (block->writesToRegister(preservedReg))
@@ -7320,47 +8057,52 @@ void Framework::Assembly::AssemblyBlock::addBlock(AssemblyBlock* block,
             bool replaced = false;
             for (int i = 0; i < __FP_REGISTER_COUNT; i++)
             {
-                bool found = false;
-                for (FPRegister r : preservedFPRegisters)
-                {
-                    if (r == (FPRegister)i)
+                if (!containsCall
+                    || (isVolatile(preservedReg) == isVolatile((FPRegister)i)))
+                { // call inside the block -> only replace volatile with
+                  // volatile and non volatile with non volatile registers
+                    bool found = false;
+                    for (FPRegister r : preservedFPRegisters)
                     {
-                        found = true;
-                        break;
+                        if (r == (FPRegister)i)
+                        {
+                            found = true;
+                            break;
+                        }
                     }
-                }
-                if (found)
-                {
-                    continue;
-                }
-                FPRegister newReg = (FPRegister)i;
-                if (!block->writesToRegister(newReg)
-                    && !block->readsFromRegister(newReg)
-                    && block->isReplacementPossible(preservedReg, newReg))
-                {
-                    if (preservedReg == MM0)
+                    if (found)
                     {
-                        *blockResultFpReg = newReg;
+                        continue;
+                    }
+                    FPRegister newReg = (FPRegister)i;
+                    if (block->isReplacementPossible(preservedReg, newReg))
+                    {
+                        if (blockResultFpReg)
+                        {
+                            if (preservedReg == *blockResultFpReg)
+                            {
+                                *blockResultFpReg = newReg;
+                            }
+                        }
+                        replaced = true;
+                        block->replaceRegister(preservedReg, newReg);
+                        break;
                     }
-                    replaced = true;
-                    block->replaceRegister(preservedReg, newReg);
-                    break;
                 }
             }
             if (!replaced)
             {
-                addPush(preservedReg);
-                tempInstructions.add(new Instruction(MOVAPD,
-                    {new FPRegisterArgument(preservedReg, Y),
-                        new MemoryAccessArgument(MemoryBlockSize::M256, RSP)}));
-                tempInstructions.add(new Instruction(ADD,
-                    {new GPRegisterArgument(RSP), new ConstantArgument(32)}));
+                // TODO: search for last instruction that wrote to preservedReg
+                // to find its data type
+                addPush(preservedReg, fpTypes[index], Y);
+                addPop(tempInstructions, preservedReg, fpTypes[index], Y);
             }
         }
+        index++;
     }
-    int index = 0;
+    index = 0;
     Text prefix = "inlined_";
-    prefix.append() << inlineIndex << "_";
+    prefix.append() << inlineIndex++ << "_";
     block->addJumpLabelPrefix(prefix);
     bool returnFound = false;
     for (const auto& instr : block->instructions)
@@ -7496,6 +8238,55 @@ Framework::Assembly::AssemblyBlock::getInstructions() const
     return instructions;
 }
 
+void Framework::Assembly::AssemblyBlock::optimize()
+{
+    RCArray<Instruction> optimizedInstructions;
+    for (int index = 0; index < instructions.getEintragAnzahl(); index++)
+    {
+        Instruction* curr = instructions.z(index);
+        if (index < instructions.getEintragAnzahl() - 1
+            && curr->getOperation() == MOV && curr->getArguments().size() == 2
+            && curr->getArguments().at(0)->asGPRegisterArgument()
+            && curr->getArguments().at(1)->asMemoryAccessArgument())
+        {
+            GPRegister target = curr->getArguments()
+                                    .at(0)
+                                    ->asGPRegisterArgument()
+                                    ->getRegister();
+            GPRegisterPart part
+                = curr->getArguments().at(0)->asGPRegisterArgument()->getPart();
+            Instruction* next = instructions.z(index + 1);
+            if (!next->writesToRegister(target, this)
+                && next->getArguments().size() == 2
+                && next->getArguments().at(1)->asGPRegisterArgument()
+                && next->getArguments()
+                           .at(1)
+                           ->asGPRegisterArgument()
+                           ->getRegister()
+                       == target
+                && next->getArguments().at(1)->asGPRegisterArgument()->getPart()
+                       == part)
+            {
+                Instruction* replacement = new Instruction(next->getOperation(),
+                    {next->getArguments().at(0), curr->getArguments().at(1)});
+                if (replacement->isValid(this))
+                {
+                    optimizedInstructions.add(replacement);
+                    index++;
+                    continue;
+                }
+                replacement->release();
+            }
+        }
+        optimizedInstructions.add(dynamic_cast<Instruction*>(curr->getThis()));
+    }
+    instructions.leeren();
+    for (Instruction* instr : optimizedInstructions)
+    {
+        instructions.add(dynamic_cast<Instruction*>(instr->getThis()));
+    }
+}
+
 void* Framework::Assembly::AssemblyBlock::compile()
 {
     if (compiledCode != 0)
@@ -7526,11 +8317,11 @@ void* Framework::Assembly::AssemblyBlock::compile()
             Instruction subInst(
                 SUB, {new GPRegisterArgument(RSP), new ConstantArgument(32)});
             subInst.compile(&buffer, this);
-            Instruction pushInstr(MOVAPD,
+            Instruction pushInstr(MOVUPD,
                 {new MemoryAccessArgument(MemoryBlockSize::M256, RSP),
                     new FPRegisterArgument(nvReg, Y)});
             pushInstr.compile(&buffer, this);
-            restoreInstructions.add(new Instruction(MOVAPD,
+            restoreInstructions.add(new Instruction(MOVUPD,
                 {new FPRegisterArgument(nvReg, Y),
                     new MemoryAccessArgument(MemoryBlockSize::M256, RSP)}));
             restoreInstructions.add(new Instruction(
@@ -7578,11 +8369,8 @@ void* Framework::Assembly::AssemblyBlock::compile()
         instr->compile(&buffer, this);
     }
     // add final RET instruction
-    if (instructions.z(instructions.getLastIndex())->getOperation() != RET)
-    {
-        Instruction retInstr(RET, {});
-        retInstr.compile(&buffer, this);
-    }
+    Instruction retInstr(RET, {});
+    retInstr.compile(&buffer, this);
     int totalSize = (int)buffer.getSize();
     // Allocate executable memory
     compiledCode = VirtualAlloc(nullptr, totalSize, MEM_COMMIT, PAGE_READWRITE);

+ 433 - 69
Assembly.h

@@ -59,38 +59,82 @@ namespace Framework
             // SpecialRegister.FLAGS is affected
             CMP,
             // Compare Packed Double Precision Floating-Point Values
-            // temporary subtracts op2 from op without storing the result. only
-            // SpecialRegister.FLAGS is affected
             CMPPD,
             // Compare Packed Single Precision Floating-Point Values
-            // temporary subtracts op2 from op without storing the result. only
-            // SpecialRegister.FLAGS is affected
             CMPPS,
             // Compare Scalar Double Precision Floating-Point Value
-            // temporary subtracts op2 from op without storing the result. only
-            // SpecialRegister.FLAGS is affected
             CMPSD,
             // Compare Scalar Single Precision Floating-Point Value
-            // temporary subtracts op2 from op without storing the result. only
-            // SpecialRegister.FLAGS is affected
             CMPSS,
+            // Compare Scalar Ordered Double Precision Floating-Point Values
+            // writes to SpecialRegister.FLAGS (ZF, PF, CF)
+            // UNORDERED (one of the values was NAN) = 0b111
+            // GREATER_THAN = 0b000
+            // LESS_THAN = 0b001
+            // EQUAL = 0b100
+            COMISD,
+            // Compare Scalar Ordered Single Precision Floating-Point Values
+            // writes to SpecialRegister.FLAGS (ZF, PF, CF)
+            // UNORDERED (one of the values was NAN) = 0b111
+            // GREATER_THAN = 0b000
+            // LESS_THAN = 0b001
+            // EQUAL = 0b100
+            COMISS,
 
             // Data Movement
 
             MOV, // Move data from source to destination
-            // Move Aligned Packed Double-Precision Floating-Point Value
-            MOVAPD,
-            // Move Aligned Packed Single-Precision Floating-Point Value
-            MOVAPS,
+            // Move Unaligned Packed Double-Precision Floating-Point Value
+            MOVUPD,
+            // Move Unaligned Packed Single-Precision Floating-Point Value
+            MOVUPS,
             MOVSD, // Move Scalar Double-Precision Floating-Point Value
             MOVSS, // Move Scalar Single-Precision Floating-Point Value
             LEA,   // Load Effective Address
 
+            // DATA Conversion
+
+            // Convert Integer to Scalar Double Precision Floating-Point Value
+            CVTSI2SD,
+            // Convert Integer to Scalar Single Precision Floating-Point Value
+            CVTSI2SS,
+            // Convert With Truncation Scalar Double Precision Floating-Point
+            // Value to Signed Integer
+            CVTTSD2SI,
+            // Convert With Truncation Scalar Single Precision Floating-Point
+            // Value to Signed Integer
+            CVTTSS2SI,
+            // Convert Scalar Double Precision Floating-Point Value to Integer
+            // with rounding according to the bits 13 an 14 of the MXCSR
+            // register value:
+            //
+            // 0b00: (default) round to nearest integer value
+            // 0b01: round to the next lower integer value
+            // 0b10: round to the next heigher integer value
+            // 0b11: truncate (like CVTTSS2SI)
+            CVTSD2SI,
+            // Convert Scalar Single Precision Floating-Point Value to Integer
+            // with rounding according to the bits 13 an 14 of the MXCSR
+            // register value:
+            //
+            // 0b00: (default) round to nearest integer value
+            // 0b01: round to the next lower integer value
+            // 0b10: round to the next heigher integer value
+            // 0b11: truncate (like CVTTSS2SI)
+            CVTSS2SI,
+
             // Control Flow
 
-            JMP, // Unconditional Jump
-            JZ,  // Jump if Zero: SpecialRegister.FLAGS(ZF) = 1
-            JNZ, // Jump if Not Zero: SpecialRegister.FLAGS(ZF) = 0
+            // Unconditional Jump
+            JMP,
+            // Jump if Zero: SpecialRegister.FLAGS(ZF) = 1
+            JZ,
+            // Jump if equal: SpecialRegister.FLAGS(ZF) = 1
+            JE = JZ,
+            // Jump if Not Zero: SpecialRegister.FLAGS(ZF) = 0
+            JNZ,
+            // Jump if Not Equal: SpecialRegister.FLAGS(ZF) = 0
+            JNE = JNZ,
             // Jump if Greater: SpecialRegister.FLAGS(SF) =
             // SpecialRegister.FLAGS(OF) and SpecialRegister.FLAGS(ZF) = 0
             JG,
@@ -108,21 +152,23 @@ namespace Framework
             JA,
             // Jump if carry: SpecialRegister.FLAGS(CF) = 1
             JC,
+            // Jump if below:  SpecialRegister.FLAGS(CF) = 1
+            JB = JC,
             // Jump if not carry: SpecialRegister.FLAGS(CF) = 0
             JNC,
+            // Jump if not below: SpecialRegister.FLAGS(CF) = 0
+            JNB = JNC,
             // Jump if below or equal: SpecialRegister.FLAGS(CF) = 1 or
             // SpecialRegister.FLAGS(ZF) = 1
             JBE,
-            JO,    // Jump if overflow: SpecialRegister.FLAGS(OF) = 1
-            JNO,   // Jump if not overflow: SpecialRegister.FLAGS(OF) = 0
-            JP,    // Jump if parity even: SpecialRegister.FLAGS(PF) = 1
-            JNP,   // Jump if not parity odd: SpecialRegister.FLAGS(PF) = 0
-            JS,    // Jump if sign: SpecialRegister.FLAGS(SF) = 1
-            JNS,   // Jump if not sign: SpecialRegister.FLAGS(SF) = 0
-            CALL,  // Call subroutine
-            ENTER, // Set up stack frame for procedure
-            LEAVE, // Destroy stack frame for procedure
-            RET,   // Return from subroutine
+            JO,   // Jump if overflow: SpecialRegister.FLAGS(OF) = 1
+            JNO,  // Jump if not overflow: SpecialRegister.FLAGS(OF) = 0
+            JP,   // Jump if parity even: SpecialRegister.FLAGS(PF) = 1
+            JNP,  // Jump if not parity odd: SpecialRegister.FLAGS(PF) = 0
+            JS,   // Jump if sign: SpecialRegister.FLAGS(SF) = 1
+            JNS,  // Jump if not sign: SpecialRegister.FLAGS(SF) = 0
+            CALL, // Call subroutine
+            RET,  // Return from subroutine
 
             // Stack Operations
 
@@ -174,6 +220,13 @@ namespace Framework
             PACKED_DOUBLE
         };
 
+        enum FuncReturnType
+        {
+            NO_VALUE,
+            INT_VALUE,
+            FLOAT_VALUE
+        };
+
         // General Purpose Registers
         enum GPRegister
         {
@@ -188,6 +241,7 @@ namespace Framework
             // Stack pointer points to the position of the last item that was
             // pushed to the stack. The stack grows downwards so lower means
             // more elements in the stack. needs to be aligned to 16 bytes
+            // non-volatile register (mus be restored on return)
             RSP = 0b0100,
             // base pointer points to the base of the current stack frame
             // non-volatile register (mus be restored on return)
@@ -234,6 +288,10 @@ namespace Framework
               - OF: Overflow Flag
              */
             FLAGS,
+            /**
+             * controls the behaviour of some operations.
+             */
+            MXCSR,
         };
 
         /**
@@ -241,22 +299,22 @@ namespace Framework
          */
         enum FPRegister
         {
-            MM0,
-            MM1,
-            MM2,
-            MM3,
-            MM4,
-            MM5,
-            MM6,
-            MM7,
-            MM8,
-            MM9,
-            MM10,
-            MM11,
-            MM12,
-            MM13,
-            MM14,
-            MM15,
+            MM0,  // volatile register (can be altered by a function call)
+            MM1,  // volatile register (can be altered by a function call)
+            MM2,  // volatile register (can be altered by a function call)
+            MM3,  // volatile register (can be altered by a function call)
+            MM4,  // volatile register (can be altered by a function call)
+            MM5,  // volatile register (can be altered by a function call)
+            MM6,  // non volatile register (mus be restored on return)
+            MM7,  // non volatile register (mus be restored on return)
+            MM8,  // non volatile register (mus be restored on return)
+            MM9,  // non volatile register (mus be restored on return)
+            MM10, // non volatile register (mus be restored on return)
+            MM11, // non volatile register (mus be restored on return)
+            MM12, // non volatile register (mus be restored on return)
+            MM13, // non volatile register (mus be restored on return)
+            MM14, // non volatile register (mus be restored on return)
+            MM15, // non volatile register (mus be restored on return)
             __FP_REGISTER_COUNT
         };
 
@@ -425,12 +483,12 @@ namespace Framework
         class MemoryAccessArgument : public OperationArgument
         {
         private:
+            MemoryBlockSize blockSize; // size of the block to access (1,2,4,8)
             bool useAddressReg;
             GPRegister address;
             int offset; // offset from the address in the register
             GPRegister offsetReg;
             bool useOffsetReg;
-            MemoryBlockSize blockSize; // size of the block to access (1,2,4,8)
 
         public:
             DLLEXPORT MemoryAccessArgument(MemoryBlockSize blockSize,
@@ -494,10 +552,20 @@ namespace Framework
         private:
             Operation op;
             std::vector<OperationArgument*> args;
+            std::vector<GPRegister> implicitReadGPs;
+            std::vector<FPRegister> implicitReadFPs;
+            std::vector<GPRegister> implicitWriteGPs;
+            std::vector<FPRegister> implicitWriteFPs;
 
         public:
             DLLEXPORT Instruction(
                 Operation op, std::initializer_list<OperationArgument*> params);
+            DLLEXPORT Instruction(Operation op,
+                std::initializer_list<OperationArgument*> params,
+                std::initializer_list<GPRegister> implicitReadGPs,
+                std::initializer_list<FPRegister> implicitReadFPs,
+                std::initializer_list<GPRegister> implicitWriteGPs,
+                std::initializer_list<FPRegister> implicitWriteFPs);
             DLLEXPORT ~Instruction();
             /**
              * checks if this instruction reads from a specified register.
@@ -585,6 +653,13 @@ namespace Framework
              */
             DLLEXPORT void compile(StreamWriter* machineCodeWriter,
                 const AssemblyBlock* block) const;
+            /**
+             * test if this instruction is valid.
+             *
+             * \param block the code block that contains this instruction
+             * \return true if the instruction can be compiled
+             */
+            DLLEXPORT bool isValid(const AssemblyBlock* block) const;
             /**
              * calculates the bytes needed for this instruction in machine code.
              *
@@ -599,6 +674,11 @@ namespace Framework
              * \return true if the given label is defined by this operation
              */
             DLLEXPORT bool definesLabel(Text label) const;
+            /**
+             * \return the arguments of this instruction
+             */
+            DLLEXPORT const std::vector<OperationArgument*>&
+            getArguments() const;
         };
 
         /**
@@ -635,6 +715,192 @@ namespace Framework
              * \param targetName the label to jump to.
              */
             DLLEXPORT void addJump(Operation jumpOp, Text targetName);
+            /**
+             * adds the value of the source register to the value of the target
+             * register and stores the result in the target register. single
+             * operation.
+             *
+             * \param target the target register
+             * \param source the source register
+             * \param part the register part
+             */
+            DLLEXPORT void addAddition(GPRegister target,
+                GPRegister source,
+                GPRegisterPart part = FULL64);
+            /**
+             * adds the value of the source register to the value of the target
+             * register and stores the result in the target register. single
+             * operation.
+             *
+             * \param target the target register
+             * \param source the source register
+             * \param type the data type stored in the registers
+             * \param part the register part
+             */
+            DLLEXPORT void addAddition(FPRegister target,
+                FPRegister source,
+                FPDataType type,
+                FPRegisterPart part = Y);
+            /**
+             * subtracts the value of the target register from the value of the
+             * source register and stores the result in the target register.
+             * single operation.
+             *
+             * \param target the target register
+             * \param source the source register
+             * \param part the register part
+             */
+            DLLEXPORT void addSubtraction(GPRegister target,
+                GPRegister source,
+                GPRegisterPart part = FULL64);
+            /**
+             * subtracts the value of the target register from the value of the
+             * source register and stores the result in the target register.
+             * single operation.
+             *
+             * \param target the target register
+             * \param source the source register
+             * \param type the data type stored in the registers
+             * \param part the register part
+             */
+            DLLEXPORT void addSubtraction(FPRegister target,
+                FPRegister source,
+                FPDataType type,
+                FPRegisterPart part = Y);
+            /**
+             * multiplies the value of the source register to the value of the
+             * target register and stores the result in the target register.
+             * single operation.
+             *
+             * \param target the target register
+             * \param source the source register
+             * \param part the register part
+             */
+            DLLEXPORT void addMultiplication(GPRegister target,
+                GPRegister source,
+                GPRegisterPart part = FULL64);
+            /**
+             * multiplies the value of the source register to the value of the
+             * target register and stores the result in the target register.
+             * single operation.
+             *
+             * \param target the target register
+             * \param source the source register
+             * \param type the data type stored in the registers
+             * \param part the register part
+             */
+            DLLEXPORT void addMultiplication(FPRegister target,
+                FPRegister source,
+                FPDataType type,
+                FPRegisterPart part = Y);
+            /**
+             * devides the value of the target register by the value of the
+             * source register and stores the result in the target register.
+             * single operation.
+             *
+             * \param target the target register
+             * \param source the source register
+             * \param part the register part
+             */
+            DLLEXPORT void addDivision(GPRegister target,
+                GPRegister source,
+                GPRegisterPart part = FULL64);
+            /**
+             * devides the value of the target register by the value of the
+             * source register and stores the result in the target register.
+             * single operation.
+             *
+             * \param target the target register
+             * \param source the source register
+             * \param type the data type stored in the registers
+             * \param part the register part
+             */
+            DLLEXPORT void addDivision(FPRegister target,
+                FPRegister source,
+                FPDataType type,
+                FPRegisterPart part = Y);
+            /**
+             * performes bitwise AND without storing the result. only
+             * SpecialRegister.FLAGS (SF, ZF, PF) is affected. Single operation.
+             *
+             * \param r1 the first value
+             * \param r2 the second value
+             * \param part the part of the values to test
+             */
+            DLLEXPORT void addTest(
+                GPRegister r1, GPRegister r2, GPRegisterPart part = FULL64);
+            /**
+             * subtracts the value of r2 from r1 and sets FLAGS (CF, OF, SF, ZF,
+             * AF, PF) according to the result. The result is discarded.
+             *
+             * \param r1 the first value
+             * \param r2 the second value
+             * \param part the part of the values to compare
+             */
+            DLLEXPORT void addCompare(
+                GPRegister r1, GPRegister r2, GPRegisterPart part = FULL64);
+            /**
+             * subtracts the value from r1 and sets FLAGS (CF, OF, SF, ZF,
+             * AF, PF) according to the result. The result is discarded.
+             *
+             * \param r1 the first value
+             * \param value the value to subtract
+             */
+            DLLEXPORT void addCompare(GPRegister r1, char value);
+            /**
+             * subtracts the value from r1 and sets FLAGS (CF, OF, SF, ZF,
+             * AF, PF) according to the result. The result is discarded.
+             *
+             * \param r1 the first value
+             * \param value the value to subtract
+             */
+            DLLEXPORT void addCompare(GPRegister r1, short value);
+            /**
+             * subtracts the value from r1 and sets FLAGS (CF, OF, SF, ZF,
+             * AF, PF) according to the result. The result is discarded.
+             *
+             * \param r1 the first value
+             * \param value the value to subtract
+             */
+            DLLEXPORT void addCompare(GPRegister r1, int value);
+            /**
+             * subtracts the value of r2 from r1 and sets FLAGS (ZF, PF, CF).
+             * the result is discarded
+             *
+             * UNORDERED: ZF,PF,CF := 111;
+             * GREATER_THAN: ZF,PF,CF := 000;
+             * LESS_THAN: ZF,PF,CF := 001;
+             * EUAL: ZF,PF,CF := 100;
+             *
+             * \param r1 the first value
+             * \param r2 the second value
+             * \param type the datatype to compare. only SINGLE types are valid
+             */
+            DLLEXPORT void addCompare(
+                FPRegister r1, FPRegister r2, FPDataType type);
+            /**
+             * computes bitwise AND for the values in source and target
+             * register and stores the result in the target register. single
+             * operation
+             *
+             * \param target the target register
+             * \param source the source register
+             * \param part the register part
+             */
+            DLLEXPORT void addAnd(GPRegister target,
+                GPRegister source,
+                GPRegisterPart part = FULL64);
+            /**
+             * computes bitwise AND for the values in source and target register
+             * and stores the result in the target register. single operation
+             *
+             * \param target the target register
+             * \param source the source register
+             * \param part the register part
+             */
+            DLLEXPORT void addOr(GPRegister target,
+                GPRegister source,
+                GPRegisterPart part = FULL64);
             /**
              * writes the specified valueAddress pointer into a register.
              *
@@ -668,6 +934,19 @@ namespace Framework
              */
             DLLEXPORT void addLoadValue(
                 __int64* valueAddress, GPRegister target);
+            /**
+             * loads the value at the address stored in addressRegister into the
+             * target register. Single operation.
+             *
+             * \param addressRegister a register that contains a memory address
+             * \param target the target register to store the value into
+             * \param targetPart the part of the target register that will be
+             * written to
+             */
+            DLLEXPORT void addLoadValue(GPRegister addressRegister,
+                GPRegister target,
+                GPRegisterPart targetPart,
+                int offset = 0);
             /**
              * writes the specified valueAddress pointer into a register.
              *
@@ -694,7 +973,7 @@ namespace Framework
              * call
              */
             template<typename T>
-            void addLoadAddress(T* addr, GPRegister temp = RAX)
+            DLLEXPORT void addLoadAddress(T* addr, GPRegister temp = RAX)
             {
                 instructions.add(new Instruction(MOV,
                     {new GPRegisterArgument(temp),
@@ -775,42 +1054,103 @@ namespace Framework
                 FPRegister source,
                 FPDataType type,
                 FPRegisterPart part = Y);
+            /**
+             * converts a floating point value from source register into a
+             * signed integer value and writes it into the target register.
+             * Single operation.
+             *
+             * \param target the target register
+             * \param source the source register
+             * \param type the datatype of the source register. Only SINGLE
+             * types are valid.
+             * \param targetPart the register part to write the result into.
+             * Only LOWER32 or FULL64 are valid.
+             * \param round if true the value is rounded acourding to bits 13
+             * and 14 of the MXCSR register value
+             */
+            DLLEXPORT void addConversion(GPRegister target,
+                FPRegister source,
+                FPDataType type,
+                GPRegisterPart targetPart,
+                bool round = 0);
+            /**
+             * converts a signed integer from source register into a floating
+             * point value and writes it into the target register. Single
+             * operation
+             *
+             * \param target the target register
+             * \param source the source register
+             * \param targetType the data type after the conversion. Only SINGLE
+             * types are valid.
+             * \param sourcePart the register part that contains the signed
+             * integer. Only LOWER32 and FULL64 are valid.
+             */
+            DLLEXPORT void addConversion(FPRegister target,
+                GPRegister source,
+                FPDataType targetType,
+                GPRegisterPart sourcePart);
 
             /**
              * calls a function at a specified memory address.
              *
              * \param functionAddress pointet to the address of the function to
              * call
-             */
-            DLLEXPORT void addCall(
-                void* functionAddress, GPRegister temp = RAX);
+             * \param gpParams must be the the every n-th entry of the register
+             * list (RCX, RDX, R8, R9) for each n-th function parameter that is
+             * of type integer
+             * \param fpParams must be the the every n-th entry of the register
+             * list (MM0, MM1, MM2, MM3) for each n-th function parameter that
+             * is of type float/double
+             * \param temp temporary register to store the address of the
+             * function
+             * \param bpTemp temporary register to store the stack pointer
+             * before ligning the stack pointer to a 16 byte boundry. The stack
+             * pointer will be automatically restored after the function call
+             * using the value of this register. A non-volatile register must be
+             * used.
+             */
+            DLLEXPORT void addCall(void* functionAddress,
+                FuncReturnType returnType = NO_VALUE,
+                std::initializer_list<GPRegister> gpParams = {},
+                std::initializer_list<FPRegister> fpParams = {},
+                GPRegister temp = RAX,
+                GPRegister bpTemp = RBP);
 
             /**
              * calls a function at a specified memory address.
              *
              * \param functionAddress pointet to the address of the function to
              * call
+             * \param gpParams must be the the every n-th entry of the register
+             * list (RCX, RDX, R8, R9) for each n-th function parameter that is
+             * of type integer
+             * \param fpParams must be the the every n-th entry of the register
+             * list (MM0, MM1, MM2, MM3) for each n-th function parameter that
+             * is of type float/double
+             * \param temp temporary register to store the address of the
+             * function
+             * \param bpTemp temporary register to store the stack pointer
+             * before ligning the stack pointer to a 16 byte boundry. The stack
+             * pointer will be automatically restored after the function call
+             * using the value of this register. A non-volatile register must be
+             * used.
              */
             template<typename T>
-            void addMemberCall(T&& functionAddress, GPRegister temp = RAX)
+            DLLEXPORT void addMemberCall(T&& functionAddress,
+                FuncReturnType returnType = NO_VALUE,
+                std::initializer_list<GPRegister> gpParams = {},
+                std::initializer_list<FPRegister> fpParams = {},
+                GPRegister temp = RAX,
+                GPRegister bpTemp = RBP)
             {
-                addCall((void*&)functionAddress, temp);
+                addCall((void*&)functionAddress,
+                    returnType,
+                    gpParams,
+                    fpParams,
+                    temp,
+                    bpTemp);
             }
 
-            /**
-             * adds an ENTER instruction to set up a stack frame for a function
-             *
-             * \param stackSize the size of the stack frame to create. should be
-             * a multiple of 16 and >= 32
-             * \param nestingLevel the nesting level of the function. usually 0
-             */
-            DLLEXPORT void addEnter(
-                short stackSize = 32, char nestingLevel = 0);
-            /**
-             * adds a LEAVE instruction to destroy the stack frame of a
-             * function.
-             */
-            DLLEXPORT void addLeave();
             /**
              * returns from executing the compiled assembly function.
              */
@@ -834,14 +1174,28 @@ namespace Framework
              * pushes a register into the stack.
              *
              * \param reg the register to push
+             * \param type the datatype of the register
+             * \param part the part of the register
              */
-            DLLEXPORT void addPush(FPRegister reg, FPRegisterPart part = X);
+            DLLEXPORT void addPush(
+                FPRegister reg, FPDataType type, FPRegisterPart part = X);
             /**
              * pops a value from the sack into a specified register.
              *
              * \param reg the register to store the popped value
+             * \param type the datatype of the register
+             * \param part the part of the register
              */
-            DLLEXPORT void addPop(FPRegister reg, FPRegisterPart part = X);
+            DLLEXPORT void addPop(
+                FPRegister reg, FPDataType type, FPRegisterPart part = X);
+
+        private:
+            DLLEXPORT void addPop(RCArray<Instruction>& instructionList,
+                FPRegister reg,
+                FPDataType type,
+                FPRegisterPart part = X);
+
+        public:
             /**
              * copies the assembly code from a given block of assembly
              * instructions.
@@ -853,14 +1207,19 @@ namespace Framework
              * pushed to the stack if no free register is available.
              * \param preservedFPRegisters same as preservedGPRegisters but for
              * FP registers
-             * \param blockResultGpReg if the register RAX should be preserved
-             * this pointer will be set to the register that was selected to
-             * replace RAX during execution of the block.
-             * \param blockResultFpReg same as blockResultGpReg but for XMM0
+             * \param preservedFPDataTypes data types of the preserved FP
+             * registers used to push them to the stack if needed
+             * \param blockResultGpReg if the register this pointer points to
+             * should be preserved this pointer will be set to the register that
+             * was selected to replace the register during execution of the
+             * block. Ignored if 0.
+             * \param blockResultFpReg same as blockResultGpReg but for FP
+             * Registers
              */
             DLLEXPORT void addBlock(AssemblyBlock* block,
                 std::initializer_list<GPRegister> preservedGPRegisters,
                 std::initializer_list<FPRegister> preservedFPRegisters,
+                std::initializer_list<FPDataType> preservedFPDataTypes,
                 GPRegister* blockResultGpReg,
                 FPRegister* blockResultFpReg);
             /**
@@ -936,6 +1295,11 @@ namespace Framework
              * \return the instructions of this block
              */
             DLLEXPORT const RCArray<Instruction>& getInstructions() const;
+            /**
+             * performs optimisations to shorten the needed instructions.
+             *
+             */
+            DLLEXPORT void optimize();
             /**
              * \return a pointer to a function that contains the compiled byte
              * code of this assembly block. and can be called directly with
@@ -947,7 +1311,7 @@ namespace Framework
              * \return a pointer to a function that contains the compiled byte
              * code of this assembly block. and can be called directly with
              */
-            template<typename T> T compileToFunction()
+            template<typename T> DLLEXPORT T compileToFunction()
             {
                 return reinterpret_cast<T>(compile());
             }

+ 5 - 0
CharMap.h

@@ -56,6 +56,11 @@ namespace Framework
         {
             return value;
         }
+
+        V* getValueP()
+        {
+            return &value;
+        }
     };
 
     template<class T, class V> class RCCharMap : public virtual ReferenceCounter

+ 163 - 74
Framework Tests/Assembly.cpp

@@ -36,43 +36,35 @@ namespace FrameworkTests
         TEST_METHOD (Add8Test)
         {
             Framework::Assembly::AssemblyBlock codeBlock;
+            codeBlock.addMoveValue(Framework::Assembly::RAX, (__int64)0);
             codeBlock.addMoveValue(Framework::Assembly::RAX,
                 Framework::Assembly::RDX,
                 Framework::Assembly::LOWER8);
-            codeBlock.addInstruction(
-                new Framework::Assembly::Instruction(Framework::Assembly::ADD,
-                    {new Framework::Assembly::GPRegisterArgument(
-                         Framework::Assembly::RAX, Framework::Assembly::LOWER8),
-                        new Framework::Assembly::GPRegisterArgument(
-                            Framework::Assembly::RCX,
-                            Framework::Assembly::LOWER8)}));
-            char (*add)(char a, char b)
-                = (char (*)(char, char))codeBlock.compile();
-            char result = add(22, 15);
-            char result2 = add(5, 6);
-            Assert::AreEqual((char)37, result);
-            Assert::AreEqual((char)11, result2);
+            codeBlock.addAddition(Framework::Assembly::RAX,
+                Framework::Assembly::RCX,
+                Framework::Assembly::LOWER8);
+            int (*add)(int a, int b) = (int (*)(int, int))codeBlock.compile();
+            int result = add(22, 15);
+            int result2 = add(0x0FFFFF43, 0x0FFFFF05);
+            Assert::AreEqual(37, result);
+            Assert::AreEqual(0x48, result2);
         }
 
         TEST_METHOD (Add16Test)
         {
             Framework::Assembly::AssemblyBlock codeBlock;
+            codeBlock.addMoveValue(Framework::Assembly::RAX, (__int64)0);
             codeBlock.addMoveValue(Framework::Assembly::RAX,
                 Framework::Assembly::RDX,
                 Framework::Assembly::LOWER16);
-            codeBlock.addInstruction(new Framework::Assembly::Instruction(
-                Framework::Assembly::ADD,
-                {new Framework::Assembly::GPRegisterArgument(
-                     Framework::Assembly::RAX, Framework::Assembly::LOWER16),
-                    new Framework::Assembly::GPRegisterArgument(
-                        Framework::Assembly::RCX,
-                        Framework::Assembly::LOWER16)}));
-            short (*add)(short a, short b)
-                = (short (*)(short, short))codeBlock.compile();
-            short result = add(22, 15);
-            short result2 = add(5, 6);
-            Assert::AreEqual((short)37, result);
-            Assert::AreEqual((short)11, result2);
+            codeBlock.addAddition(Framework::Assembly::RAX,
+                Framework::Assembly::RCX,
+                Framework::Assembly::LOWER16);
+            int (*add)(int a, int b) = (int (*)(int, int))codeBlock.compile();
+            int result = add(22, 15);
+            int result2 = add(0x11111111, 0x22222222);
+            Assert::AreEqual(37, result);
+            Assert::AreEqual(0x3333, result2);
         }
 
         TEST_METHOD (Add32Test)
@@ -81,18 +73,15 @@ namespace FrameworkTests
             codeBlock.addMoveValue(Framework::Assembly::RAX,
                 Framework::Assembly::RDX,
                 Framework::Assembly::LOWER32);
-            codeBlock.addInstruction(new Framework::Assembly::Instruction(
-                Framework::Assembly::ADD,
-                {new Framework::Assembly::GPRegisterArgument(
-                     Framework::Assembly::RAX, Framework::Assembly::LOWER32),
-                    new Framework::Assembly::GPRegisterArgument(
-                        Framework::Assembly::RCX,
-                        Framework::Assembly::LOWER32)}));
-            int (*add)(int a, int b) = (int (*)(int, int))codeBlock.compile();
-            int result = add(22, 15);
-            int result2 = add(5, 6);
-            Assert::AreEqual((int)37, result);
-            Assert::AreEqual((int)11, result2);
+            codeBlock.addAddition(Framework::Assembly::RAX,
+                Framework::Assembly::RCX,
+                Framework::Assembly::LOWER32);
+            __int64 (*add)(__int64 a, __int64 b)
+                = (__int64 (*)(__int64, __int64))codeBlock.compile();
+            __int64 result = add(22, 15);
+            __int64 result2 = add(0x1111111111111111, 0x1111111111111111);
+            Assert::AreEqual((__int64)37, result);
+            Assert::AreEqual((__int64)0x22222222, result2);
         }
 
         TEST_METHOD (Add64Test)
@@ -100,31 +89,23 @@ namespace FrameworkTests
             Framework::Assembly::AssemblyBlock codeBlock;
             codeBlock.addMoveValue(
                 Framework::Assembly::RAX, Framework::Assembly::RDX);
-            codeBlock.addInstruction(
-                new Framework::Assembly::Instruction(Framework::Assembly::ADD,
-                    {new Framework::Assembly::GPRegisterArgument(
-                         Framework::Assembly::RAX),
-                        new Framework::Assembly::GPRegisterArgument(
-                            Framework::Assembly::RCX)}));
+            codeBlock.addAddition(
+                Framework::Assembly::RAX, Framework::Assembly::RCX);
             __int64 (*add)(__int64 a, __int64 b)
                 = (__int64 (*)(__int64, __int64))codeBlock.compile();
             __int64 result = add(22, 15);
-            __int64 result2 = add(5, 6);
+            __int64 result2 = add(0x1111111111111111, 0x1111111111111111);
             Assert::AreEqual((__int64)37, result);
-            Assert::AreEqual((__int64)11, result2);
+            Assert::AreEqual((__int64)0x2222222222222222, result2);
         }
 
         TEST_METHOD (AddFloatTest)
         {
             Framework::Assembly::AssemblyBlock codeBlock;
-            codeBlock.addInstruction(
-                new Framework::Assembly::Instruction(Framework::Assembly::ADDSS,
-                    {new Framework::Assembly::FPRegisterArgument(
-                         Framework::Assembly::MM0,
-                         Framework::Assembly::FPRegisterPart::X),
-                        new Framework::Assembly::FPRegisterArgument(
-                            Framework::Assembly::MM1,
-                            Framework::Assembly::FPRegisterPart::X)}));
+            codeBlock.addAddition(Framework::Assembly::MM0,
+                Framework::Assembly::MM1,
+                Framework::Assembly::SINGLE_FLOAT,
+                Framework::Assembly::X);
             float (*add)(float a, float b)
                 = (float (*)(float, float))codeBlock.compile();
             float result = add(4.24f, 8.54f);
@@ -136,14 +117,10 @@ namespace FrameworkTests
         TEST_METHOD (AddDoubleTest)
         {
             Framework::Assembly::AssemblyBlock codeBlock;
-            codeBlock.addInstruction(
-                new Framework::Assembly::Instruction(Framework::Assembly::ADDSD,
-                    {new Framework::Assembly::FPRegisterArgument(
-                         Framework::Assembly::MM0,
-                         Framework::Assembly::FPRegisterPart::X),
-                        new Framework::Assembly::FPRegisterArgument(
-                            Framework::Assembly::MM1,
-                            Framework::Assembly::FPRegisterPart::X)}));
+            codeBlock.addAddition(Framework::Assembly::MM0,
+                Framework::Assembly::MM1,
+                Framework::Assembly::SINGLE_DOUBLE,
+                Framework::Assembly::X);
             double (*add)(double a, double b)
                 = (double (*)(double, double))codeBlock.compile();
             double result = add(4.24, 8.54);
@@ -218,38 +195,150 @@ namespace FrameworkTests
 
         TEST_METHOD (testCall)
         {
-            std::cout << 1.463f << 4.235;
             Framework::Assembly::AssemblyBlock gfcodeBlock;
-            gfcodeBlock.addEnter();
             gfcodeBlock.addMoveValue(Framework::Assembly::RCX, 20);
             gfcodeBlock.addMoveValue(Framework::Assembly::RDX, 50);
-            gfcodeBlock.addCall(globalFunc);
-            gfcodeBlock.addLeave();
+            gfcodeBlock.addCall(globalFunc,
+                Framework::Assembly::INT_VALUE,
+                {Framework::Assembly::RCX, Framework::Assembly::RDX});
             int (*f)() = gfcodeBlock.compileToFunction<int (*)()>();
             int result = f();
             Assert::AreEqual(globalFunc(20, 50), result);
             Framework::Assembly::AssemblyBlock lfcodeBlock;
-            lfcodeBlock.addEnter();
             lfcodeBlock.addLoadAddress(this, Framework::Assembly::RCX);
-            lfcodeBlock.addMoveValue(Framework::Assembly::RCX, 20);
-            lfcodeBlock.addMoveValue(Framework::Assembly::RDX, 50);
-            lfcodeBlock.addMemberCall(&AssemblyTests::testMethod);
-            lfcodeBlock.addLeave();
+            lfcodeBlock.addMoveValue(Framework::Assembly::RDX, 20);
+            lfcodeBlock.addMoveValue(Framework::Assembly::R8, 50);
+            lfcodeBlock.addMemberCall(&AssemblyTests::testMethod,
+                Framework::Assembly::INT_VALUE,
+                {Framework::Assembly::RCX,
+                    Framework::Assembly::RDX,
+                    Framework::Assembly::R8});
             c = 1;
             f = lfcodeBlock.compileToFunction<int (*)()>();
             result = f();
             A* a = new B();
             Assert::AreEqual(testMethod(20, 50), result);
             Framework::Assembly::AssemblyBlock vfcodeBlock;
-            vfcodeBlock.addEnter();
             vfcodeBlock.addLoadAddress(a, Framework::Assembly::RCX);
-            vfcodeBlock.addMemberCall(&A::getValue);
-            vfcodeBlock.addLeave();
+            vfcodeBlock.addMemberCall(
+                &A::getValue, Framework::Assembly::INT_VALUE);
             c = 1;
             f = vfcodeBlock.compileToFunction<int (*)()>();
             result = f();
             Assert::AreEqual(a->getValue(), result);
             delete a;
         }
+
+        TEST_METHOD (mulTest)
+        {
+            float fa = 3.0f;
+            float fb = 4.0f;
+            double da = 5.0;
+            double db = 6.0;
+            Framework::Assembly::AssemblyBlock fcodeBlock;
+            fcodeBlock.addLoadValue(&fa, Framework::Assembly::MM0);
+            fcodeBlock.addLoadValue(&fb, Framework::Assembly::MM1);
+            fcodeBlock.addMultiplication(Framework::Assembly::MM0,
+                Framework::Assembly::MM1,
+                Framework::Assembly::SINGLE_FLOAT,
+                Framework::Assembly::X);
+            float (*fmul)() = fcodeBlock.compileToFunction<float (*)()>();
+            float fresult = fmul();
+            Assert::AreEqual(fa * fb, fresult);
+            Framework::Assembly::AssemblyBlock dcodeBlock;
+            dcodeBlock.addLoadValue(&da, Framework::Assembly::MM0);
+            dcodeBlock.addLoadValue(&db, Framework::Assembly::MM1);
+            dcodeBlock.addMultiplication(Framework::Assembly::MM0,
+                Framework::Assembly::MM1,
+                Framework::Assembly::SINGLE_DOUBLE,
+                Framework::Assembly::X);
+            double (*dmul)() = dcodeBlock.compileToFunction<double (*)()>();
+            double dresult = dmul();
+            Assert::AreEqual(da * db, dresult);
+        }
+
+        TEST_METHOD (jumpTest)
+        {
+            Framework::Assembly::AssemblyBlock codeBlock;
+            codeBlock.addMoveValue(Framework::Assembly::RAX, 0);
+            codeBlock.addJump(Framework::Assembly::JMP, "end");
+            codeBlock.addMoveValue(Framework::Assembly::RAX, 1);
+            codeBlock.defineJumpTarget("start");
+            codeBlock.addMoveValue(Framework::Assembly::RAX, 2);
+            codeBlock.defineJumpTarget("end");
+            codeBlock.addTest(
+                Framework::Assembly::RAX, Framework::Assembly::RAX);
+            codeBlock.addJump(Framework::Assembly::JZ, "start");
+            int (*test)() = codeBlock.compileToFunction<int (*)()>();
+            int result = test();
+            Assert::AreEqual(2, result);
+        }
+
+        TEST_METHOD (stackTest)
+        {
+            Framework::Assembly::AssemblyBlock codeBlock;
+            codeBlock.addMoveValue(Framework::Assembly::RAX, (char)10);
+            codeBlock.addMoveValue(Framework::Assembly::RBX, (short)20);
+            codeBlock.addMoveValue(Framework::Assembly::RCX, (int)30);
+            codeBlock.addMoveValue(Framework::Assembly::RDX, (__int64)40);
+            codeBlock.addMoveValue(
+                Framework::Assembly::MM0, 5.f, Framework::Assembly::R8);
+            codeBlock.addMoveValue(
+                Framework::Assembly::MM1, 6.0, Framework::Assembly::R8);
+            codeBlock.addPush(
+                Framework::Assembly::RAX, Framework::Assembly::LOWER8);
+            codeBlock.addPush(
+                Framework::Assembly::RBX, Framework::Assembly::LOWER16);
+            codeBlock.addPush(
+                Framework::Assembly::RCX, Framework::Assembly::LOWER32);
+            codeBlock.addPush(
+                Framework::Assembly::RDX, Framework::Assembly::FULL64);
+            codeBlock.addPush(Framework::Assembly::MM0,
+                Framework::Assembly::SINGLE_FLOAT,
+                Framework::Assembly::X);
+            codeBlock.addPush(Framework::Assembly::MM1,
+                Framework::Assembly::SINGLE_DOUBLE,
+                Framework::Assembly::X);
+            codeBlock.addPop(Framework::Assembly::MM1,
+                Framework::Assembly::SINGLE_DOUBLE,
+                Framework::Assembly::X);
+            codeBlock.addMoveValue(Framework::Assembly::MM2, 6.0);
+            codeBlock.addCompare(Framework::Assembly::MM1,
+                Framework::Assembly::MM2,
+                Framework::Assembly::SINGLE_DOUBLE);
+            codeBlock.addJump(Framework::Assembly::JNE, "error");
+            codeBlock.addPop(Framework::Assembly::MM0,
+                Framework::Assembly::SINGLE_FLOAT,
+                Framework::Assembly::X);
+            codeBlock.addMoveValue(Framework::Assembly::MM2, 5.f);
+            codeBlock.addCompare(Framework::Assembly::MM0,
+                Framework::Assembly::MM2,
+                Framework::Assembly::SINGLE_FLOAT);
+            codeBlock.addJump(Framework::Assembly::JNE, "error");
+            codeBlock.addPop(
+                Framework::Assembly::RDX, Framework::Assembly::FULL64);
+            codeBlock.addCompare(Framework::Assembly::RDX, 40);
+            codeBlock.addJump(Framework::Assembly::JNE, "error");
+            codeBlock.addPop(
+                Framework::Assembly::RCX, Framework::Assembly::LOWER32);
+            codeBlock.addCompare(Framework::Assembly::RCX, 30);
+            codeBlock.addJump(Framework::Assembly::JNE, "error");
+            codeBlock.addPop(
+                Framework::Assembly::RBX, Framework::Assembly::LOWER16);
+            codeBlock.addCompare(Framework::Assembly::RBX, (short)20);
+            codeBlock.addJump(Framework::Assembly::JNE, "error");
+            codeBlock.addPop(
+                Framework::Assembly::RAX, Framework::Assembly::LOWER8);
+            codeBlock.addCompare(Framework::Assembly::RAX, (char)10);
+            codeBlock.addJump(Framework::Assembly::JNE, "error");
+            codeBlock.addMoveValue(Framework::Assembly::RAX, 1);
+            codeBlock.addJump(Framework::Assembly::JMP, "end");
+            codeBlock.defineJumpTarget("error");
+            codeBlock.addMoveValue(Framework::Assembly::RAX, 0);
+            codeBlock.defineJumpTarget("end");
+            int (*test)() = codeBlock.compileToFunction<int (*)()>();
+            int result = test();
+            Assert::AreEqual(1, result);
+        }
     };
 } // namespace FrameworkTests

+ 38 - 4
Trie.h

@@ -88,7 +88,7 @@ namespace Framework
                         if (i < 256)
                         {
                             for (unsigned char j = (unsigned char)(i + 1); true;
-                                 j++)
+                                j++)
                             {
                                 if (d.parent->map->z(j))
                                     return TrieIterator(TrieIteratorData<T, M>(
@@ -102,7 +102,8 @@ namespace Framework
                     if (i == 255) break;
                 }
             } while (d.parent && d.parent->map);
-            return TrieIterator(TrieIteratorData<T, M>(0, TrieIteratorData<T, M>()));
+            return TrieIterator(
+                TrieIteratorData<T, M>(0, TrieIteratorData<T, M>()));
         }
 
         TrieIterator& operator++() //! prefix
@@ -189,6 +190,28 @@ namespace Framework
             }
         }
 
+        T* getP(const char* addr, int addrLen)
+        {
+            if (!addrLen)
+                return map->getValueP();
+            else
+            {
+                if (!map->z(*addr)) return 0;
+                return map->z(*addr)->getP(addr + 1, addrLen - 1);
+            }
+        }
+
+        bool contains(const char* addr, int addrLen) const
+        {
+            if (!addrLen)
+                return true;
+            else
+            {
+                if (!map->z(*addr)) return false;
+                return map->z(*addr)->contains(addr + 1, addrLen - 1);
+            }
+        }
+
         void leeren()
         {
             map->release();
@@ -199,7 +222,7 @@ namespace Framework
         {
             return TrieIterator<T, CharMap<Trie<T>, T>>(
                 TrieIteratorData<T, CharMap<Trie<T>, T>>(
-                map, TrieIteratorData<T, CharMap<Trie<T>, T>>()));
+                    map, TrieIteratorData<T, CharMap<Trie<T>, T>>()));
         }
 
         friend TrieIterator<T, CharMap<Trie<T>, T>>;
@@ -266,6 +289,17 @@ namespace Framework
             }
         }
 
+        bool contains(const char* addr, int addrLen) const
+        {
+            if (!addrLen)
+                return true;
+            else
+            {
+                if (!map->z(*addr)) return false;
+                return map->z(*addr)->contains(addr + 1, addrLen - 1);
+            }
+        }
+
         void leeren()
         {
             map->release();
@@ -276,7 +310,7 @@ namespace Framework
         {
             return TrieIterator<T, RCCharMap<RCTrie<T>, T>>(
                 TrieIteratorData<T, RCCharMap<RCTrie<T>, T>>(
-                map, TrieIteratorData<T, RCCharMap<RCTrie<T>, T>>()));
+                    map, TrieIteratorData<T, RCCharMap<RCTrie<T>, T>>()));
         }
 
         friend TrieIterator<T, RCCharMap<RCTrie<T>, T>>;